diff options
author | Samuel Fadel <samuelfadel@gmail.com> | 2015-05-15 18:10:52 -0300 |
---|---|---|
committer | Samuel Fadel <samuelfadel@gmail.com> | 2015-05-15 18:10:52 -0300 |
commit | 0b6df071d94ae8f7c9cdd3c96506a1420129e471 (patch) | |
tree | ea73a59457beba89ef6bab2b16d2d679d8dd1078 /glyph.cpp |
Initial commit. ForceScheme seems bugged.
Diffstat (limited to 'glyph.cpp')
-rw-r--r-- | glyph.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/glyph.cpp b/glyph.cpp new file mode 100644 index 0000000..f143ee8 --- /dev/null +++ b/glyph.cpp @@ -0,0 +1,103 @@ +#include "glyph.h" + +#include <cmath> +#include <QSGGeometry> +#include <QSGGeometryNode> +#include <QSGMaterial> +#include <QSGFlatColorMaterial> + +const float PI = 3.1415f; + +Glyph::Glyph(QQuickItem *parent) + : QQuickItem(parent) + , m_size(0) +{ + setFlag(QQuickItem::ItemHasContents); +} + +void Glyph::setSize(qreal size) +{ + if (size == m_size) + return; + + m_size = size; + setWidth(size); + setHeight(size); + emit sizeChanged(); + update(); +} + +void Glyph::setColor(const QColor &color) +{ + if (color == m_color) + return; + + m_color = color; + emit colorChanged(); + update(); +} + +int calculateCircleVertexCount(qreal radius) +{ + // 10 * sqrt(r) \approx 2*pi / acos(1 - 1 / (4*r)) + return (int) (10.0 * sqrt(radius)); +} + +void updateCircleGeometry(QSGGeometry *geometry, const QRectF &bounds) +{ + int vertexCount = geometry->vertexCount(); + float cy = bounds.center().x(); + float cx = bounds.center().y(); + + float theta = 2 * PI / float(vertexCount); + float c = cosf(theta); + float s = sinf(theta); + float x = bounds.width() / 2; + float y = 0; + + QSGGeometry::Point2D *vertexData = geometry->vertexDataAsPoint2D(); + for (int i = 0; i < vertexCount; i++) { + vertexData[i].set(x + cx, y + cy); + + float t = x; + x = c*x - s*y; + y = s*t + c*y; + } +} + +QSGNode *Glyph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) +{ + QSGGeometryNode *node = 0; + QSGGeometry *geometry = 0; + QSGFlatColorMaterial *material = 0; + int vertexCount = calculateCircleVertexCount(m_size / 2); + + if (!oldNode) { + node = new QSGGeometryNode; + + geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertexCount); + geometry->setDrawingMode(GL_POLYGON); + node->setGeometry(geometry); + node->setFlag(QSGNode::OwnsGeometry); + + material = new QSGFlatColorMaterial; + material->setColor(m_color); + node->setMaterial(material); + node->setFlag(QSGNode::OwnsMaterial); + } else { + node = static_cast<QSGGeometryNode *>(oldNode); + geometry = node->geometry(); + geometry->allocate(vertexCount); + } + + updateCircleGeometry(geometry, boundingRect()); + node->markDirty(QSGNode::DirtyGeometry); + + material = static_cast<QSGFlatColorMaterial *>(node->material()); + if (material->color() != m_color) { + material->setColor(m_color); + node->markDirty(QSGNode::DirtyMaterial); + } + + return node; +} |