#include "lottiemodel.h"
+#include "vline.h"
#include <cassert>
#include <stack>
grad->radial.cx = start.x();
grad->radial.cy = start.y();
grad->radial.cradius =
- vLineLength(start.x(), start.y(), end.x(), end.y());
+ VLine::length(start.x(), start.y(), end.x(), end.y());
/*
* Focal point is the point lives in highlight length distance from
* center along the line (start, end) and rotated by highlight angle.
#include "vbezier.h"
-
+#include "vline.h"
#include <cmath>
V_BEGIN_NAMESPACE
-// Approximate sqrt(x*x + y*y) using the alpha max plus beta min algorithm.
-// This uses alpha = 1, beta = 3/8, which results in a maximum error of less
-// than 7% compared to the correct value.
-static inline float lineLength(float x1, float y1, float x2, float y2)
-{
- float x = x2 - x1;
- float y = y2 - y1;
-
- x = x < 0 ? -x : x;
- y = y < 0 ? -y : y;
-
- return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
VBezier VBezier::fromPoints(const VPointF &p1, const VPointF &p2,
const VPointF &p3, const VPointF &p4)
{
float chord; /* chord length */
float length;
- len = len + lineLength(x1, y1, x2, y2);
- len = len + lineLength(x2, y2, x3, y3);
- len = len + lineLength(x3, y3, x4, y4);
+ len = len + VLine::length(x1, y1, x2, y2);
+ len = len + VLine::length(x2, y2, x3, y3);
+ len = len + VLine::length(x3, y3, x4, y4);
- chord = lineLength(x1, y1, x4, y4);
+ chord = VLine::length(x1, y1, x4, y4);
if (!vCompare(len, chord)) {
split(&left, &right); /* split in two */
#include "vdasher.h"
#include "vbezier.h"
+#include "vline.h"
V_BEGIN_NAMESPACE
-class VLine {
-public:
- VLine() : mX1(0), mY1(0), mX2(0), mY2(0) {}
- VLine(float x1, float y1, float x2, float y2)
- : mX1(x1), mY1(y1), mX2(x2), mY2(y2)
- {
- }
- VLine(const VPointF &p1, const VPointF &p2)
- : mX1(p1.x()), mY1(p1.y()), mX2(p2.x()), mY2(p2.y())
- {
- }
- float length() const;
- void splitAtLength(float length, VLine &left, VLine &right) const;
- VPointF p1() const { return VPointF(mX1, mY1); }
- VPointF p2() const { return VPointF(mX2, mY2); }
-
-private:
- float mX1;
- float mY1;
- float mX2;
- float mY2;
-};
-
-// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
-// With alpha = 1, beta = 3/8, giving results with the largest error less
-// than 7% compared to the exact value.
-float VLine::length() const
-{
- float x = mX2 - mX1;
- float y = mY2 - mY1;
- x = x < 0 ? -x : x;
- y = y < 0 ? -y : y;
- return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
-void VLine::splitAtLength(float lengthAt, VLine &left, VLine &right) const
-{
- float len = length();
- double dx = ((mX2 - mX1) / len) * lengthAt;
- double dy = ((mY2 - mY1) / len) * lengthAt;
-
- left.mX1 = mX1;
- left.mY1 = mY1;
- left.mX2 = left.mX1 + dx;
- left.mY2 = left.mY1 + dy;
-
- right.mX1 = left.mX2;
- right.mY1 = left.mY2;
- right.mX2 = mX2;
- right.mY2 = mY2;
-}
-
VDasher::VDasher(const float *dashArray, int size)
{
if (!(size % 2)) vCritical << "invalid dashArray format";
} else {
mCurrentLength = mDashArray[mIndex].length;
}
+ if (vIsZero(mCurrentLength)) updateActiveSegment();
}
void VDasher::addLine(const VPointF &p)
mDiscard = true;
mCurrentLength = mDashArray[mIndex].gap;
}
+ if (vIsZero(mCurrentLength)) updateActiveSegment();
}
void VDasher::lineTo(const VPointF &p)
return (std::abs(f) <= EPSILON_DOUBLE);
}
-// Approximate sqrt(x*x + y*y) using the alpha max plus beta min algorithm.
-// This uses alpha = 1, beta = 3/8, which results in a maximum error of less
-// than 7% compared to the correct value.
-static inline float vLineLength(float x1, float y1, float x2, float y2)
-{
- float x = x2 - x1;
- float y = y2 - y1;
-
- x = x < 0 ? -x : x;
- y = y < 0 ? -y : y;
-
- return (x > y ? x + 0.375 * y : y + 0.375 * x);
-}
-
class vFlagHelper {
int i;
--- /dev/null
+#ifndef VLINE_H
+#define VLINE_H
+
+#include "vglobal.h"
+#include "vpoint.h"
+
+V_BEGIN_NAMESPACE
+
+class VLine {
+public:
+ VLine() = default;
+ VLine(float x1, float y1, float x2, float y2)
+ : mX1(x1), mY1(y1), mX2(x2), mY2(y2)
+ {
+ }
+ VLine(const VPointF &p1, const VPointF &p2)
+ : mX1(p1.x()), mY1(p1.y()), mX2(p2.x()), mY2(p2.y())
+ {
+ }
+ float length() const { return length(mX1, mY1, mX2, mY2);}
+ void splitAtLength(float length, VLine &left, VLine &right) const;
+ VPointF p1() const { return VPointF(mX1, mY1); }
+ VPointF p2() const { return VPointF(mX2, mY2); }
+
+ static float length(float x1, float y1, float x2, float y2);
+
+private:
+ float mX1{0};
+ float mY1{0};
+ float mX2{0};
+ float mY2{0};
+};
+
+// approximate sqrt(x*x + y*y) using alpha max plus beta min algorithm.
+// With alpha = 1, beta = 3/8, giving results with the largest error less
+// than 7% compared to the exact value.
+inline float VLine::length(float x1, float y1, float x2, float y2)
+{
+ float x = x2 - x1;
+ float y = y2 - y1;
+
+ x = x < 0 ? -x : x;
+ y = y < 0 ? -y : y;
+
+ return (x > y ? x + 0.375 * y : y + 0.375 * x);
+}
+
+inline void VLine::splitAtLength(float lengthAt, VLine &left, VLine &right) const
+{
+ float len = length();
+ float dx = ((mX2 - mX1) / len) * lengthAt;
+ float dy = ((mY2 - mY1) / len) * lengthAt;
+
+ left.mX1 = mX1;
+ left.mY1 = mY1;
+ left.mX2 = left.mX1 + dx;
+ left.mY2 = left.mY1 + dy;
+
+ right.mX1 = left.mX2;
+ right.mY1 = left.mY2;
+ right.mX2 = mX2;
+ right.mY2 = mY2;
+}
+
+#endif //VLINE_H
\ No newline at end of file
#include "vbezier.h"
#include "vdebug.h"
#include "vrect.h"
+#include "vline.h"
V_BEGIN_NAMESPACE
i++;
break;
case VPath::Element::LineTo: {
- VPointF p0 = m_points[i - 1];
- VPointF p = m_points[i++];
- VBezier b = VBezier::fromPoints(p0, p0, p, p);
- len += b.length();
+ len += VLine( m_points[i-1], m_points[i]).length();
+ i++;
break;
}
case VPath::Element::CubicTo: {
- VPointF p0 = m_points[i - 1];
- VPointF p = m_points[i++];
- VPointF p1 = m_points[i++];
- VPointF p2 = m_points[i++];
- VBezier b = VBezier::fromPoints(p0, p, p1, p2);
- len += b.length();
+ len += VBezier::fromPoints(m_points[i-1], m_points[i],
+ m_points[i+1], m_points[i+2]).length();
+ i += 3;
break;
}
case VPath::Element::Close: