mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-26 10:31:39 +08:00
261 lines
9.6 KiB
C++
261 lines
9.6 KiB
C++
/*
|
|
Copyright (c) 2008-2018 Jan W. Krieger (<jan@jkrieger.de>)
|
|
|
|
|
|
|
|
|
|
|
|
This software is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License (LGPL) for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/** \file jkqtpdrawingtools.cpp
|
|
* \ingroup jkqtptools
|
|
*/
|
|
|
|
#include "jkqtplottertools/jkqtpdrawingtools.h"
|
|
#include "jkqtplottertools/jkqtpenhancedpainter.h"
|
|
|
|
|
|
|
|
void JKQTPplotSymbol(QPaintDevice& paintDevice, double x, double y, JKQTPgraphSymbols symbol, double size, double symbolLineWidth, QColor color, QColor fillColor) {
|
|
JKQTPEnhancedPainter p(&paintDevice);
|
|
JKQTPplotSymbol(p, x, y, symbol, size, symbolLineWidth, color, fillColor);
|
|
}
|
|
|
|
void JKQTPplotSymbol(JKQTPEnhancedPainter& painter, double x, double y, JKQTPgraphSymbols symbol, double symbolSize, double symbolLineWidth, QColor color, QColor fillColor) {
|
|
painter.save();
|
|
QPen p=painter.pen();
|
|
p.setColor(color);
|
|
p.setWidthF(qMax(JKQTPLOTTER_ABS_MIN_LINEWIDTH, symbolLineWidth));
|
|
p.setStyle(Qt::SolidLine);
|
|
painter.setPen(p);
|
|
QBrush b=painter.brush();
|
|
b.setColor(fillColor);
|
|
b.setStyle(Qt::SolidPattern);
|
|
const double w=symbolSize;
|
|
const double w2=w/2.0;
|
|
const double w3=w/3.0;
|
|
|
|
// calculate star cordinates as static values
|
|
static int star_items=0;
|
|
static double starcordsx[10];
|
|
static double starcordsy[10];
|
|
if (star_items==0) {
|
|
star_items=5;
|
|
double angle=360.0/double(star_items)/180.0*M_PI;
|
|
for (int i=0; i<star_items; i++) {
|
|
double a=((double)i+0.5)*angle;
|
|
starcordsx[i*2]=sin(a);
|
|
starcordsx[i*2+1]=0.5*sin(a+angle/2.0);
|
|
starcordsy[i*2]=cos(a);
|
|
starcordsy[i*2+1]=0.5*cos(a+angle/2.0);
|
|
}
|
|
}
|
|
|
|
switch(symbol) {
|
|
case JKQTPdot:
|
|
painter.drawPoint(QPointF(x,y));
|
|
break;
|
|
case JKQTPcross:{
|
|
/*QVector<QLineF> lines;
|
|
lines<<QLineF(x-w2,y-w2,x+w2,y+w2);
|
|
lines<<QLineF(x-w2,y+w2,x+w2,y-w2);
|
|
painter.drawLines(lines);*/
|
|
QPainterPath path;
|
|
path.moveTo(x-w2,y-w2);
|
|
path.lineTo(x+w2,y+w2);
|
|
path.moveTo(x-w2,y+w2);
|
|
path.lineTo(x+w2,y-w2);
|
|
painter.drawPath(path);
|
|
}
|
|
break;
|
|
case JKQTPplus:{
|
|
QVector<QLineF> lines;
|
|
lines<<QLineF(x,y-w2,x,y+w2);
|
|
lines<<QLineF(x-w2,y,x+w2,y);
|
|
painter.drawLines(lines);
|
|
}
|
|
break;
|
|
case JKQTPcircle:{
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawEllipse(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPtarget:{
|
|
QPainterPath path;
|
|
QRectF rectangle3(x-w3, y-w3, 2.0*w3, 2.0*w3);
|
|
path.addEllipse(rectangle3);
|
|
path.moveTo(QPointF(x,y-w2));
|
|
path.lineTo(QPointF(x,y+w2));
|
|
path.moveTo(QPointF(x-w2,y));
|
|
path.lineTo(QPointF(x+w2,y));
|
|
painter.drawPath(path);
|
|
}
|
|
break;
|
|
case JKQTPfilledCircle:{
|
|
painter.setBrush(b);
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawEllipse(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPrect:{
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawRect(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPrectCross:{
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QPainterPath path;
|
|
path.moveTo(x-w2,y-w2);
|
|
path.lineTo(x+w2,y+w2);
|
|
path.moveTo(x-w2,y+w2);
|
|
path.lineTo(x+w2,y-w2);
|
|
painter.drawPath(path);
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawRect(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPrectPlus:{
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QVector<QLineF> lines;
|
|
lines<<QLineF(x,y-w2,x,y+w2);
|
|
lines<<QLineF(x-w2,y,x+w2,y);
|
|
painter.drawLines(lines);
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawRect(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPfilledRect:{
|
|
painter.setBrush(b);
|
|
QRectF rectangle(x-w2, y-w2, w, w);
|
|
painter.drawRect(rectangle);
|
|
}
|
|
break;
|
|
case JKQTPtriangle: {
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QPolygonF poly;
|
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPfilledTriangle: {
|
|
painter.setBrush(b);
|
|
QPolygonF poly;
|
|
poly<<QPointF(x-w2, y+w2)<<QPointF(x+w2, y+w2)<<QPointF(x, y-w2);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPdownTriangle: {
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QPolygonF poly;
|
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x, y+w2);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPfilledDownTriangle: {
|
|
painter.setBrush(b);
|
|
QPolygonF poly;
|
|
poly<<QPointF(x-w2, y-w2)<<QPointF(x+w2, y-w2)<<QPointF(x, y+w2);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPdiamond: {
|
|
QPolygonF poly;
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPfilledDiamond: {
|
|
painter.setBrush(b);
|
|
QPolygonF poly;
|
|
poly<<QPointF(x, y-w2)<<QPointF(x+w2, y)<<QPointF(x, y+w2)<<QPointF(x-w2, y);
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPstar: {
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QPolygonF poly;
|
|
for (int i=0; i<star_items*2; i++) {
|
|
poly<<QPointF(x+starcordsx[i]*w2, y+starcordsy[i]*w2);
|
|
}
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPfilledStar: {
|
|
painter.setBrush(b);
|
|
QPolygonF poly;
|
|
for (int i=0; i<star_items*2; i++) {
|
|
poly<<QPointF(x+starcordsx[i]*w2, y+starcordsy[i]*w2);
|
|
}
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPpentagon: {
|
|
painter.setBrush(QColor(Qt::transparent));
|
|
QPolygonF poly;
|
|
for (int i=0; i<star_items*2; i+=2) {
|
|
poly<<QPointF(x+starcordsx[i]*w2, y+starcordsy[i]*w2);
|
|
}
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
case JKQTPasterisc: {
|
|
//QVector<QLineF> lines;
|
|
QPainterPath path;
|
|
for (int i=0; i<star_items*2; i+=2) {
|
|
//lines<<QLineF(x+starcordsx[i]*w2, y+starcordsy[i]*w2, x, y);
|
|
path.moveTo(x+starcordsx[i]*w2, y+starcordsy[i]*w2);
|
|
path.lineTo(x,y);
|
|
}
|
|
//painter.drawLines(lines);
|
|
painter.drawPath(path);
|
|
} break;
|
|
case JKQTPfilledPentagon: {
|
|
painter.setBrush(b);
|
|
QPolygonF poly;
|
|
for (int i=0; i<star_items*2; i+=2) {
|
|
poly<<QPointF(x+starcordsx[i]*w2, y+starcordsy[i]*w2);
|
|
}
|
|
painter.drawConvexPolygon(poly);
|
|
} break;
|
|
default: break;
|
|
}
|
|
painter.restore();
|
|
};
|
|
|
|
|
|
|
|
QVector<QPointF> JKQTPdrawEllipse(double x, double y, double a, double b, double angle_start, double angle_end, double alpha, int controlPoints, QPointF* x_start, QPointF* x_end) {
|
|
QVector<QPointF> result;
|
|
double start=angle_start*M_PI/180.0;
|
|
double stop=angle_end*M_PI/180.0;
|
|
double step=(stop-start)/(double)controlPoints;
|
|
while (fabs(stop-start)/step<10) step=step/2.0;
|
|
double sina=sin(1.0*alpha/180.0*M_PI);
|
|
double cosa=cos(1.0*alpha/180.0*M_PI);
|
|
QPointF xp(x+a*cos(start)*cosa-b*sin(start)*sina, y+a*cos(start)*sina+b*sin(start)*cosa);
|
|
result.append(xp);
|
|
if (x_start) *x_start = xp;
|
|
double t=start+step;
|
|
for (int i=1; i<controlPoints; i++) {
|
|
double cost=cos(t);
|
|
double sint=sin(t);
|
|
xp=QPointF( x+a*cost*cosa-b*sint*sina, y+a*cost*sina+b*sint*cosa);
|
|
result.append(xp);
|
|
//std::cout<<"t="<<t/M_PI*180.0<<": sin(al)="<<sina<<" cos(al)="<<cosa<<" sin(t)="<<sint<<" cos(t)="<<cost<<" a="<<a<<" b="<<b<<": ("<<x+a*cost*cosa-b*sint*sina<<", "<<y+a*cost*sina+b*sint*cosa<<") = ("<<xp.x()<<", "<<xp.y()<<") \n";
|
|
t=t+step;
|
|
}
|
|
if (x_end) *x_end=xp;
|
|
return result;
|
|
}
|
|
|
|
|