From ca70fec5797749746e300ce8a99784b251a77c13 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Sat, 4 Feb 2023 11:53:54 +0100 Subject: [PATCH] caching some values for faster valueAt calculations --- src/common/QskGradientDirection.cpp | 24 ++++++++++++++++++--- src/common/QskGradientDirection.h | 33 ++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/common/QskGradientDirection.cpp b/src/common/QskGradientDirection.cpp index 82434d5c..b387283a 100644 --- a/src/common/QskGradientDirection.cpp +++ b/src/common/QskGradientDirection.cpp @@ -40,6 +40,7 @@ void QskLinearDirection::setVector( const QLineF& vector ) noexcept m_y1 = vector.y1(); m_x2 = vector.x2(); m_y2 = vector.y2(); + m_dot = -1.0; } void QskLinearDirection::setVector( const QPointF& start, const QPointF& stop ) noexcept @@ -48,6 +49,7 @@ void QskLinearDirection::setVector( const QPointF& start, const QPointF& stop ) m_y1 = start.y(); m_x2 = stop.x(); m_y2 = stop.y(); + m_dot = -1.0; } void QskLinearDirection::setVector( qreal x1, qreal y1, qreal x2, qreal y2 ) noexcept @@ -56,50 +58,59 @@ void QskLinearDirection::setVector( qreal x1, qreal y1, qreal x2, qreal y2 ) noe m_y1 = y1; m_x2 = x2; m_y2 = y2; + m_dot = -1.0; } void QskLinearDirection::setStart( const QPointF& pos ) noexcept { m_x1 = pos.x(); m_y1 = pos.y(); + m_dot = -1.0; } void QskLinearDirection::setStart( qreal x, qreal y ) noexcept { m_x1 = x; m_y1 = y; + m_dot = -1.0; } void QskLinearDirection::setStop( const QPointF& pos ) noexcept { m_x2 = pos.x(); m_y2 = pos.y(); + m_dot = -1.0; } void QskLinearDirection::setStop( qreal x, qreal y ) noexcept { m_x2 = x; m_y2 = y; + m_dot = -1.0; } void QskLinearDirection::setX1( qreal x ) noexcept { m_x1 = x; + m_dot = -1.0; } void QskLinearDirection::setY1( qreal y ) noexcept { m_y1 = y; + m_dot = -1.0; } void QskLinearDirection::setX2( qreal x ) noexcept { m_x2 = x; + m_dot = -1.0; } void QskLinearDirection::setY2( qreal y ) noexcept { m_y2 = y; + m_dot = -1.0; } void QskLinearDirection::setInterval( Qt::Orientation orientation, qreal from, qreal to ) @@ -114,6 +125,14 @@ void QskLinearDirection::setInterval( Qt::Orientation orientation, qreal from, q m_x1 = from; m_x2 = to; } + m_dot = -1.0; +} + +void QskLinearDirection::precalculate() const noexcept +{ + m_dx = m_x2 - m_x1; + m_dy = m_y2 - m_y1; + m_dot = m_dx * m_dx + m_dy * m_dy; } static inline bool qskIntersectsTop( @@ -133,14 +152,14 @@ static inline bool qskIntersectsBottom( static inline bool qskIntersectsLeft( qreal vx, qreal vy, qreal m, const QRectF& rect ) { - const qreal cy = vy - ( vx - rect.left() ) * m; + const auto cy = vy - ( vx - rect.left() ) * m; return ( cy > rect.top() && cy < rect.bottom() ); } static inline bool qskIntersectsRight( qreal vx, qreal vy, qreal m, const QRectF& rect ) { - const qreal cy = vy - ( vx - rect.right() ) * m; + const auto cy = vy - ( vx - rect.right() ) * m; return ( cy > rect.top() && cy < rect.bottom() ); } @@ -152,7 +171,6 @@ bool QskLinearDirection::contains( const QRectF& rect ) const || ( m_x1 >= rect.right() && m_x2 <= rect.left() ); } - if ( m_x1 == m_x2 ) { return ( m_y1 <= rect.top() && m_y2 >= rect.bottom() ) diff --git a/src/common/QskGradientDirection.h b/src/common/QskGradientDirection.h index 1ed60913..239890fe 100644 --- a/src/common/QskGradientDirection.h +++ b/src/common/QskGradientDirection.h @@ -68,6 +68,9 @@ class QSK_EXPORT QskLinearDirection constexpr qreal y2() const noexcept; void setY2( qreal ) noexcept; + qreal dx() const noexcept; + qreal dy() const noexcept; + /* In direction of the gradient vector, where 0.0 corresponds to points on the perpendicular at the start and 1.0 to points on @@ -82,10 +85,16 @@ class QSK_EXPORT QskLinearDirection bool contains( const QRectF& ) const; private: + void precalculate() const noexcept; + qreal m_x1 = 0.0; qreal m_y1 = 0.0; qreal m_x2 = 0.0; qreal m_y2 = 1.0; + + mutable qreal m_dx = 0.0; + mutable qreal m_dy = 0.0; + mutable qreal m_dot = -1.0; }; class QSK_EXPORT QskConicDirection @@ -219,6 +228,22 @@ inline constexpr qreal QskLinearDirection::y2() const noexcept return m_y2; } +inline qreal QskLinearDirection::dx() const noexcept +{ + if ( m_dot < 0.0 ) + precalculate(); + + return m_dx; +} + +inline qreal QskLinearDirection::dy() const noexcept +{ + if ( m_dot < 0.0 ) + precalculate(); + + return m_dy; +} + inline constexpr QLineF QskLinearDirection::vector() const noexcept { return QLineF( m_x1, m_y1, m_x2, m_y2 ); @@ -262,12 +287,10 @@ inline qreal QskLinearDirection::valueAt( const QPointF& pos ) const inline qreal QskLinearDirection::valueAt( qreal x, qreal y ) const { - // we could cache these values TODO .. - const qreal dx = m_x2 - m_x1; - const qreal dy = m_y2 - m_y1; - const qreal dot = dx * dx + dy * dy; + if ( m_dot < 0.0 ) + precalculate(); - return ( ( x - m_x1 ) * dx + ( y - m_y1 ) * dy ) / dot; + return ( ( x - m_x1 ) * m_dx + ( y - m_y1 ) * m_dy ) / m_dot; } inline constexpr QskConicDirection::QskConicDirection(