From e1e268ebbcd8f0d29b8faa187dde6981f82b027f Mon Sep 17 00:00:00 2001 From: Samuel Fadel Date: Mon, 5 Oct 2015 13:02:23 -0300 Subject: Initial (rudimentary) animation implementation. Animation plays when setXY() is called on Scatterplot, providing a "smooth" transition for the new position of each point. --- scatterplot.cpp | 37 +++++++++++++++++++++++++++++++------ scatterplot.h | 7 ++++++- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/scatterplot.cpp b/scatterplot.cpp index e22eafd..35639e6 100644 --- a/scatterplot.cpp +++ b/scatterplot.cpp @@ -57,16 +57,21 @@ void Scatterplot::setXY(const arma::mat &xy) } if (m_xy.n_elem != xy.n_elem) { + m_oldXY = xy; m_selectedGlyphs.clear(); + } else { + m_oldXY = m_xy; } m_xy = xy; - m_sx.setDomain(m_xy.col(0).min(), m_xy.col(0).max()); - m_sy.setDomain(m_xy.col(1).min(), m_xy.col(1).max()); + m_sx.setDomain(m_oldXY.col(0).min(), m_oldXY.col(0).max()); + m_sy.setDomain(m_oldXY.col(1).min(), m_oldXY.col(1).max()); updateGeometry(); emit xyChanged(m_xy); + + startAnimation(); } void Scatterplot::setColorData(const arma::vec &colorData) @@ -168,7 +173,8 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) QSGNode *node = root->firstChild()->firstChild(); for (arma::uword i = 0; i < m_xy.n_rows; i++) { - arma::rowvec row = m_xy.row(i); + const arma::rowvec &oldRow = m_oldXY.row(i); + const arma::rowvec &row = m_xy.row(i); bool isSelected = m_selectedGlyphs.contains(i); QSGOpacityNode *glyphOpacityNode = static_cast(node); @@ -178,8 +184,8 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) QSGGeometryNode *glyphNode = static_cast(node->firstChild()->nextSibling()); if (m_shouldUpdateGeometry) { moveTranslationF = isSelected ? 1.0 : 0.0; - x = m_sx(row[0]) + tx * moveTranslationF; - y = m_sy(row[1]) + ty * moveTranslationF; + x = m_sx(m_t*row[0] + (1 - m_t)*oldRow[0]) + tx * moveTranslationF; + y = m_sy(m_t*row[1] + (1 - m_t)*oldRow[1]) + ty * moveTranslationF; QSGGeometry *geometry = glyphOutlineNode->geometry(); updateCircleGeometry(geometry, GLYPH_SIZE / 2, x, y); @@ -222,15 +228,34 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) } else { node = root->firstChild()->nextSibling(); if (node) { - // node->markDirty(QSGNode::DirtyGeometry); root->removeChildNode(node); delete node; } } + animationTick(); return root; } +void Scatterplot::resetAnimation() +{ + m_t = 0; +} + +void Scatterplot::startAnimation() +{ + resetAnimation(); + update(); +} + +void Scatterplot::animationTick() +{ + if (m_t < 1.f) { + m_t += 0.1f; + updateGeometry(); + } +} + void Scatterplot::mousePressEvent(QMouseEvent *event) { switch (m_currentInteractionState) { diff --git a/scatterplot.h b/scatterplot.h index 2dc031a..63a7e6e 100644 --- a/scatterplot.h +++ b/scatterplot.h @@ -44,7 +44,11 @@ private: void updateGeometry(); void updateMaterials(); - arma::mat m_xy; + void resetAnimation(); + void startAnimation(); + void animationTick(); + + arma::mat m_oldXY, m_xy; LinearScale m_sx, m_sy; enum InteractionState { @@ -63,6 +67,7 @@ private: arma::vec m_colorData; ColorScale *m_colorScale; + float m_t; }; #endif // SCATTERPLOT_H -- cgit v1.2.3