See More

#include "wplot/PolarLineGraph2D.h" #include "wplot/Plot2D.h" #include "wplot/PolarPlot2D.h" #include #include namespace WPlot { /////////////////////////////////////////////////////////////////////////////// // PUBLIC SECTION // /////////////////////////////////////////////////////////////////////////////// PolarLineGraph2D::PolarLineGraph2D() : PolarScalarGraph2D(), m_lineColor(Qt::black), m_fillColor(0, 0, 0, 0), m_lineWidth(1.0), m_fillColorYCoordinate(0.0) { m_pen.setColor(m_lineColor); m_pen.setWidthF(m_lineWidth); } /** * Set the color of the line. * * @param[in] color Color. */ void PolarLineGraph2D::setLineColor(const QColor &color) { m_lineColor = color; m_pen.setColor(color); m_colorFunctionDefined = false; } void PolarLineGraph2D::setLineStyle(const Qt::PenStyle &style) { m_style = style; m_pen.setStyle(style); } /** * Set the color for filling. * * @param[in] color Color. */ void PolarLineGraph2D::setFillColor(const QColor &color) { m_fillColor = color; } /** * Set the coordinate that must be used in order to create the filling. * * @param[in] coordinate Coordinate. */ void PolarLineGraph2D::setFillYCoordinate(const double &coordinate) { m_fillColorYCoordinate = coordinate; } /** * Set the width of the line in pixels. * * @param[in] width Width. */ void PolarLineGraph2D::setLineWidth(const double &width) { m_lineWidth = width; m_pen.setWidthF(width); } /////////////////////////////////////////////////////////////////////////////// // VIRTUAL PUBLIC SECTION // /////////////////////////////////////////////////////////////////////////////// /** * Draw the graph into specified plot. * * @param[inout] plot Plot. * * @internal It's not possible do define */ void PolarLineGraph2D::draw(Plot2D *plot) { if (m_fillColor.alpha() != 0) { drawFilling(plot); } if (false == m_colorFunctionDefined) { drawSolidColorLine(plot); } else { drawGradientLine(plot); } } /////////////////////////////////////////////////////////////////////////////// // PRIVATE SECTION // /////////////////////////////////////////////////////////////////////////////// void PolarLineGraph2D::drawSolidColorLine(Plot2D *plot) { PolarPlot2D *polarPlot = dynamic_cast(plot); if (nullptr == polarPlot) { return; } if (m_data.size() < 2) { return; } QPolygonF points; QPainter painter(plot); plot->initializePainter(painter); painter.setPen(m_pen); for (const auto& it : m_data) { points.append(polarPlot->scalePolarPoint(it)); } painter.drawPolyline(points); } void PolarLineGraph2D::drawGradientLine(Plot2D *plot) { PolarPlot2D *polarPlot = dynamic_cast(plot); if (nullptr == polarPlot) { return; } if (m_data.size() < 2) { return; } QImage image(plot->size(), QImage::Format_ARGB32_Premultiplied); QPolygonF points; QPainter painter(&image); plot->initializePainter(painter); m_pen.setColor(Qt::white); painter.setCompositionMode(QPainter::CompositionMode_Source); painter.setPen(m_pen); for (auto& it : m_data) { points.append(polarPlot->scalePolarPoint(it)); } painter.drawPolyline(points); //Draw gradient painter.setCompositionMode(QPainter::CompositionMode_SourceIn); // For every line segment draw the corresponding gradient region const int size = m_data.size(); for (int i = 1; i < size; i++) { const auto firstCorner = polarPlot->scalePolarPoint(m_data.at(i-1)); const auto secondCorner = polarPlot->scalePolarPoint(m_data.at(i)); const int xMin = std::min(firstCorner.x(), secondCorner.x()) - 2.0 * m_lineWidth; const int xMax = std::max(firstCorner.x(), secondCorner.x()) + 2.0 * m_lineWidth; const int yMin = std::min(firstCorner.y(), secondCorner.y()) - 2.0 * m_lineWidth; const int yMax = std::max(firstCorner.y(), secondCorner.y()) + 2.0 * m_lineWidth; const QPoint topLeftCorner(xMin, yMin); const QPoint bottomRightCorner(xMax, yMax); QImage gradientImage(xMax - xMin, yMax - yMin, QImage::Format_ARGB32); int lineNumber = 0; int columnNumber = 0; for (int y = yMin; y < yMax; y++) { QRgb *colorLine = reinterpret_cast(gradientImage.scanLine(lineNumber)); for (int x = xMin; x < xMax; x++) { const QPointF colorPoint(plot->inverseScalePoint(x, y)); QRgb color = m_colorFunction(colorPoint.x(), colorPoint.y()).rgba(); colorLine[columnNumber] = color; columnNumber++; } lineNumber++; columnNumber = 0; } painter.drawImage(QRect(topLeftCorner, bottomRightCorner), gradientImage); } QPainter plotPainter(plot); plot->initializePainter(plotPainter); plotPainter.drawImage(0, 0, image); } void PolarLineGraph2D::drawFilling(Plot2D *plot) { PolarPlot2D *polarPlot = dynamic_cast(plot); if (nullptr == polarPlot) { return; } if (m_data.size() < 2) { return; } QPainter painter(plot); QPen pen; QPolygonF polygon; QBrush brush; brush.setColor(m_fillColor); brush.setStyle(Qt::SolidPattern); painter.setBrush(brush); pen.setBrush(brush); painter.setPen(pen); for (const auto& it : m_data) { polygon << polarPlot->scalePolarPoint(it); } polygon << polarPlot->scalePolarPoint(m_data.back().x(), m_fillColorYCoordinate); polygon << polarPlot->scalePolarPoint(m_data.front().x(), m_fillColorYCoordinate); painter.drawPolygon(polygon); } } // namespace WPlot