lottie/vector: move line related api to its own class .

Change-Id: Ib9072653cf534e558eedd88242535bc9a8e028fe
This commit is contained in:
subhransu mohanty 2018-08-29 11:36:10 +09:00
parent c87e393308
commit adef38c0e7
6 changed files with 81 additions and 96 deletions

View File

@ -1,4 +1,5 @@
#include "lottiemodel.h"
#include "vline.h"
#include <cassert>
#include <stack>
@ -242,7 +243,7 @@ void LOTGradient::update(std::unique_ptr<VGradient> &grad, int frameNo)
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.

View File

@ -1,23 +1,9 @@
#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)
{
@ -40,11 +26,11 @@ float VBezier::length() const
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 */

View File

@ -1,60 +1,9 @@
#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";
@ -104,6 +53,7 @@ void VDasher::moveTo(const VPointF &p)
} else {
mCurrentLength = mDashArray[mIndex].length;
}
if (vIsZero(mCurrentLength)) updateActiveSegment();
}
void VDasher::addLine(const VPointF &p)
@ -129,6 +79,7 @@ void VDasher::updateActiveSegment()
mDiscard = true;
mCurrentLength = mDashArray[mIndex].gap;
}
if (vIsZero(mCurrentLength)) updateActiveSegment();
}
void VDasher::lineTo(const VPointF &p)

View File

@ -110,20 +110,6 @@ static inline bool vIsZero(double f)
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;

65
src/vector/vline.h Normal file
View File

@ -0,0 +1,65 @@
#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

View File

@ -4,6 +4,7 @@
#include "vbezier.h"
#include "vdebug.h"
#include "vrect.h"
#include "vline.h"
V_BEGIN_NAMESPACE
@ -38,19 +39,14 @@ float VPath::VPathData::length() const
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: