/* Copyright (c) 2008-2019 Jan W. Krieger () 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.1 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 . */ #include "jkqtplotter/jkqtpgraphsgeometric.h" #include "jkqtplotter/jkqtpbaseplotter.h" #include "jkqtplotter/jkqtplotter.h" #include #include #include #define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgzcolor=color; this->lineWidth=lineWidth; this->style=style; title=""; } JKQTPGeoBaseLine::JKQTPGeoBaseLine(QColor color, double lineWidth, Qt::PenStyle style, JKQTPlotter* parent): JKQTPPlotObject(parent) { this->color=color; this->lineWidth=lineWidth; this->style=style; title=""; } void JKQTPGeoBaseLine::setAlpha(float alpha) { color.setAlphaF(alpha); } QPen JKQTPGeoBaseLine::getPen(JKQTPEnhancedPainter& painter) { QPen p; p.setColor(color); p.setStyle(style); p.setWidthF(qMax(JKQTPlotterDrawinTools::ABS_MIN_LINEWIDTH, parent->pt2px(painter, lineWidth*parent->getLineWidthMultiplier()))); return p; } void JKQTPGeoBaseLine::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getPen(painter)); double y=rect.top()+rect.height()/2.0; if (rect.width()>0) painter.drawLine(QLineF(rect.left(), y, rect.right(), y)); } QColor JKQTPGeoBaseLine::getKeyLabelColor() { return color; } JKQTPGeoBaseFilled::JKQTPGeoBaseFilled(QColor color, QColor fillColor, double lineWidth, Qt::PenStyle style, Qt::BrushStyle fillStyle, JKQTBasePlotter* parent): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->fillColor=fillColor; this->fillStyle=fillStyle; } JKQTPGeoBaseFilled::JKQTPGeoBaseFilled(QColor color, QColor fillColor, double lineWidth, Qt::PenStyle style, Qt::BrushStyle fillStyle, JKQTPlotter* parent): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->fillColor=fillColor; this->fillStyle=fillStyle; } JKQTPGeoBaseFilled::JKQTPGeoBaseFilled(QColor color, QColor fillColor, double lineWidth, Qt::PenStyle style, JKQTPlotter* parent): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->fillColor=fillColor; this->fillStyle=Qt::SolidPattern; } JKQTPGeoBaseFilled::JKQTPGeoBaseFilled(QColor color, QColor fillColor, double lineWidth, JKQTPlotter* parent): JKQTPGeoBaseLine(color, lineWidth, Qt::SolidLine, parent) { this->fillColor=fillColor; this->fillStyle=Qt::SolidPattern; } JKQTPGeoBaseFilled::JKQTPGeoBaseFilled(QColor color, QColor fillColor, JKQTPlotter* parent): JKQTPGeoBaseLine(color, 2.0, Qt::SolidLine, parent) { this->fillColor=fillColor; this->fillStyle=Qt::SolidPattern; } void JKQTPGeoBaseFilled::setAlpha(float alpha) { JKQTPGeoBaseLine::setAlpha(alpha); fillColor.setAlphaF(alpha); } void JKQTPGeoBaseFilled::setAlpha(float alphaLine, float alphaFill) { JKQTPGeoBaseLine::setAlpha(alphaLine); fillColor.setAlphaF(alphaFill); } QBrush JKQTPGeoBaseFilled::getBrush(JKQTPEnhancedPainter &/*painter*/) { QBrush b; b.setColor(fillColor); b.setStyle(fillStyle); return b; } void JKQTPGeoBaseFilled::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getPen(painter)); painter.setBrush(getBrush(painter)); painter.drawRect(rect); } JKQTPGeoText::JKQTPGeoText(JKQTBasePlotter* parent, double x, double y, const QString& text, double fontSize, QColor color): JKQTPPlotObject(parent) { this->x=x; this->y=y; this->text=text; this->fontSize=fontSize; this->fontName=QApplication::font().family()+"+XITS"; this->color=color; if (parent) { this->fontSize=parent->getCurrentPlotterStyle().defaultFontSize; this->fontName=parent->getCurrentPlotterStyle().defaultFontName; } } JKQTPGeoText::JKQTPGeoText(JKQTPlotter* parent, double x, double y, const QString& text, double fontSize, QColor color): JKQTPGeoText(parent->getPlotter(),x,y,text,fontSize,color) { } bool JKQTPGeoText::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { minx=maxx=x; smallestGreaterZero=0; if (x>10.0*DBL_MIN) smallestGreaterZero=x; return true; } bool JKQTPGeoText::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) { miny=maxy=y; smallestGreaterZero=0; if (y>10.0*DBL_MIN) smallestGreaterZero=y; return true; } void JKQTPGeoText::draw(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); parent->getMathText()->setFontRomanOrSpecial(fontName); parent->getMathText()->setFontSize(fontSize*parent->getFontSizeMultiplier()); parent->getMathText()->setFontColor(color); parent->getMathText()->parse(text); parent->getMathText()->draw(painter, transformX(x), transformY(y)); } void JKQTPGeoText::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getPen(painter)); double y=rect.top()+rect.height()/2.0; if (rect.width()>0) painter.drawLine(QLineF(rect.left(), y, rect.right(), y)); } QColor JKQTPGeoText::getKeyLabelColor() { return color; } QPen JKQTPGeoText::getPen(JKQTPEnhancedPainter &/*painter*/) { QPen p; p.setColor(color); return p; } JKQTPGeoLine::JKQTPGeoLine(JKQTBasePlotter* parent, double x1, double y1, double x2, double y2, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->x1=x1; this->y1=y1; this->x2=x2; this->y2=y2; } JKQTPGeoLine::JKQTPGeoLine(JKQTPlotter* parent, double x1, double y1, double x2, double y2, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->x1=x1; this->y1=y1; this->x2=x2; this->y2=y2; } bool JKQTPGeoLine::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { minx=qMin(x1, x2); maxx=qMax(x1, x2); smallestGreaterZero=0; double xvsgz; xvsgz=x1; SmallestGreaterZeroCompare_xvsgz(); xvsgz=x2; SmallestGreaterZeroCompare_xvsgz(); return true; } bool JKQTPGeoLine::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) { miny=qMin(y1, y2); maxy=qMax(y1, y2); smallestGreaterZero=0; double xvsgz; xvsgz=y1; SmallestGreaterZeroCompare_xvsgz(); xvsgz=y2; SmallestGreaterZeroCompare_xvsgz(); return true; } void JKQTPGeoLine::draw(JKQTPEnhancedPainter& painter) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getPen(painter)); QLineF l(QPointF(transformX(x1), transformY(y1)), QPointF(transformX(x2), transformY(y2))); if (l.length()>0) painter.drawLine(l); } JKQTPGeoInfiniteLine::JKQTPGeoInfiniteLine(JKQTBasePlotter* parent, double x, double y, double dx, double dy, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->x=x; this->y=y; this->dx=dx; this->dy=dy; this->two_sided=false; } JKQTPGeoInfiniteLine::JKQTPGeoInfiniteLine(JKQTPlotter* parent, double x, double y, double dx, double dy, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->x=x; this->y=y; this->dx=dx; this->dy=dy; this->two_sided=false; } bool JKQTPGeoInfiniteLine::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { minx=x; maxx=x; smallestGreaterZero=0; if (x>10.0*DBL_MIN) smallestGreaterZero=x; return true; } bool JKQTPGeoInfiniteLine::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) { miny=y; maxy=y; smallestGreaterZero=0; if (y>10.0*DBL_MIN) smallestGreaterZero=y; return true; } void JKQTPGeoInfiniteLine::draw(JKQTPEnhancedPainter& painter) { double xmin=parent->getXAxis()->getMin(); double xmax=parent->getXAxis()->getMax(); double ymin=parent->getYAxis()->getMin(); double ymax=parent->getYAxis()->getMax(); QRectF bbox(QPointF(xmin, ymin), QPointF(xmax, ymax)); bool doDraw=false; double x2=x, y2=y; double x1=x, y1=y; // normalize lengh of direction double dl=sqrt(dx*dx+dy*dy); dx=dx/dl; dy=dy/dl; // first catch cases where we are parallel to one coordinate axis if (dy==0) { doDraw=((y>=ymin)&&(y<=ymax)); x1=xmin; x2=xmax; if (!two_sided) { if ((dx>0)&&(x>xmin)) { x1=x; } else if ((dx<0)&&(x=xmin)&&(x<=xmax)); y1=ymin; y2=ymax; if (!two_sided) { if ((dy>0)&&(y>ymin)) { y1=y; } else if ((dy<0)&&(yxmin)&&(xymin use it t1=tymin; if (two_sided) { doDraw=true; } else if (t1>0) { doDraw=true; } else { t1=0; } } else if (xymin0) { doDraw=true; } else { t1=0; } } else if (xymin>xmax) { //(xymin,ymin) is on the right, next to the rectangle, so we have to intersect with x=xmax t1=(xmax-x)/dx; if (two_sided) { doDraw=true; } else if (t1>0) { doDraw=true; } else { t1=0; } } if ((xymax>xmin)&&(xymax use it t2=tymax; if (two_sided) { doDraw=true; } else if (t2>0) { doDraw=true; } else { t2=0; } } else if (xymax0) { doDraw=true; } else { t2=0; } } else if (xymax>xmax) { //(xymax,ymax) is on the right, next to the rectangle, so we have to intersect with x=xmax t2=(xmax-x)/dx; if (two_sided) { doDraw=true; } else if (t2>0) { doDraw=true; } else { t2=0; } } x1=x+t1*dx; y1=y+t1*dy; x2=x+t2*dx; y2=y+t2*dy; } if (doDraw) { painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.setPen(getPen(painter)); QLineF l(QPointF(transformX(x1), transformY(y1)), QPointF(transformX(x2), transformY(y2))); if (l.length()>0) painter.drawLine(l); } } JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTBasePlotter* parent, const QVector& points, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->points=points; } JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTPlotter* parent, const QVector& points, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { this->points=points; } JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTBasePlotter *parent, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { } JKQTPGeoPolyLines::JKQTPGeoPolyLines(JKQTPlotter *parent, QColor color, double lineWidth, Qt::PenStyle style): JKQTPGeoBaseLine(color, lineWidth, style, parent) { } bool JKQTPGeoPolyLines::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { minx=0; maxx=0; smallestGreaterZero=0; if (points.size()>0) { minx=points[0].x(); maxx=points[0].x(); for (int i=1; imaxx) maxx=x; if (x0) { miny=points[0].y(); maxy=points[0].y(); for (int i=1; imaxy) maxy=y; if (yx=x; this->y=y; angle=0; this->width=width; this->height=height; } JKQTPGeoRectangle::JKQTPGeoRectangle(JKQTPlotter* parent, double x, double y, double width, double height, QColor color, double lineWidth, Qt::PenStyle style, QColor fillColor, Qt::BrushStyle fillStyle): JKQTPGeoBaseFilled(color, fillColor, lineWidth, style, fillStyle, parent) { this->x=x; this->y=y; angle=0; this->width=width; this->height=height; } JKQTPGeoRectangle::JKQTPGeoRectangle(JKQTBasePlotter *parent, double x, double y, double width, double height, double angle, QColor color, double lineWidth, Qt::PenStyle style, QColor fillColor, Qt::BrushStyle fillStyle): JKQTPGeoBaseFilled(color, fillColor, lineWidth, style, fillStyle, parent) { this->x=x; this->y=y; this->angle=angle; this->width=width; this->height=height; } JKQTPGeoRectangle::JKQTPGeoRectangle(JKQTPlotter *parent, double x, double y, double width, double height, double angle, QColor color, double lineWidth, Qt::PenStyle style, QColor fillColor, Qt::BrushStyle fillStyle): JKQTPGeoBaseFilled(color, fillColor, lineWidth, style, fillStyle, parent) { this->x=x; this->y=y; this->angle=angle; this->width=width; this->height=height; } JKQTPGeoRectangle::JKQTPGeoRectangle(JKQTBasePlotter *parent, QPointF bottomleft, QPointF topright, QColor color, double lineWidth, Qt::PenStyle style, QColor fillColor, Qt::BrushStyle fillStyle): JKQTPGeoBaseFilled(color, fillColor, lineWidth, style, fillStyle, parent) { this->angle=0; this->width=fabs(topright.x()-bottomleft.x()); this->height=fabs(topright.y()-bottomleft.y()); this->x=bottomleft.x()+this->width/2.0; this->y=bottomleft.y()+this->height/2.0; } JKQTPGeoRectangle::JKQTPGeoRectangle(JKQTPlotter *parent, QPointF bottomleft, QPointF topright, QColor color, double lineWidth, Qt::PenStyle style, QColor fillColor, Qt::BrushStyle fillStyle): JKQTPGeoBaseFilled(color, fillColor, lineWidth, style, fillStyle, parent) { this->angle=0; this->width=fabs(topright.x()-bottomleft.x()); this->height=fabs(topright.y()-bottomleft.y()); this->x=bottomleft.x()+this->width/2.0; this->y=bottomleft.y()+this->height/2.0; } QMatrix JKQTPGeoRectangle::getMatrix() { QMatrix trans; trans.rotate(angle); return trans; } bool JKQTPGeoRectangle::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) { QRectF bound=getPolygon().boundingRect(); //std::cout<<"JKQTPGeoRectangle::getXMinMax: b.left="<