55 #include <QMessageLogger>
59 #include "../vmisc/def.h"
60 #include "../vmisc/vmath.h"
61 #include "../vgeometry/vpointf.h"
102 QPointF &spl2p3)
const
108 if (fullLength <= minLength)
110 spl1p2 = spl1p3 = spl2p2 = spl2p3 = QPointF();
114 const qreal maxLength = fullLength - minLength;
116 if (length < minLength)
120 else if (length > maxLength)
125 const qreal parT =
GetParmT(length);
128 seg1_2.setLength(seg1_2.length () * parT);
129 const QPointF p12 = seg1_2.p2();
132 seg2_3.setLength(seg2_3.length () * parT);
133 const QPointF p23 = seg2_3.p2();
135 QLineF seg12_23 ( p12, p23 );
136 seg12_23.setLength(seg12_23.length () * parT);
137 const QPointF p123 = seg12_23.p2();
140 seg3_4.setLength(seg3_4.length () * parT);
141 const QPointF p34 = seg3_4.p2();
143 QLineF seg23_34 ( p23, p34 );
144 seg23_34.setLength(seg23_34.length () * parT);
145 const QPointF p234 = seg23_34.p2();
147 QLineF seg123_234 ( p123, p234 );
148 seg123_234.setLength(seg123_234.length () * parT);
149 const QPointF p1234 = seg123_234.p2();
181 const qreal eps = 0.001 * length;
184 qreal splLength =
LengthT(parT);
186 while (qAbs(splLength - length) > eps)
189 splLength > length ? parT -= step : parT += step;
218 const qreal dx = x2 - x1;
219 const qreal dy = y2 - y1;
220 return dx * dx + dy * dy;
243 for (
int i=1; i < px.size(); ++i)
245 if (QPointF(px.at(i-1), py.at(i-1)) == QPointF(px.at(i), py.at(i)))
247 qDebug(
"All neighbors points in path must be unique.");
252 const double curve_collinearity_epsilon = 1e-30;
253 const double curve_angle_tolerance_epsilon = 0.01;
254 const double m_angle_tolerance = 0.0;
255 enum curve_recursion_limit_e { curve_recursion_limit = 32 };
256 const double m_cusp_limit = 0.0;
257 double m_approximation_scale = 1.0;
258 double m_distance_tolerance_square;
260 m_distance_tolerance_square = 0.5 / m_approximation_scale;
261 m_distance_tolerance_square *= m_distance_tolerance_square;
263 if (level > curve_recursion_limit)
270 const double x12 = (x1 + x2) / 2;
271 const double y12 = (y1 + y2) / 2;
272 const double x23 = (x2 + x3) / 2;
273 const double y23 = (y2 + y3) / 2;
274 const double x34 = (x3 + x4) / 2;
275 const double y34 = (y3 + y4) / 2;
276 const double x123 = (x12 + x23) / 2;
277 const double y123 = (y12 + y23) / 2;
278 const double x234 = (x23 + x34) / 2;
279 const double y234 = (y23 + y34) / 2;
280 const double x1234 = (x123 + x234) / 2;
281 const double y1234 = (y123 + y234) / 2;
286 const double dx = x4-x1;
287 const double dy = y4-y1;
289 double d2 = fabs((x2 - x4) * dy - (y2 - y4) * dx);
290 double d3 = fabs((x3 - x4) * dy - (y3 - y4) * dx);
292 switch ((
static_cast<int>(d2 > curve_collinearity_epsilon) << 1) +
293 static_cast<int>(d3 > curve_collinearity_epsilon))
299 double k = dx*dx + dy*dy;
309 const double da1 = x2 - x1;
310 const double da2 = y2 - y1;
311 d2 = k * (da1*dx + da2*dy);
314 const double da1 = x3 - x1;
315 const double da2 = y3 - y1;
316 d3 = k * (da1*dx + da2*dy);
318 if (d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1)
352 if (d2 < m_distance_tolerance_square)
361 if (d3 < m_distance_tolerance_square)
374 if (d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy))
376 if (m_angle_tolerance < curve_angle_tolerance_epsilon)
385 double da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2));
391 if (da1 < m_angle_tolerance)
401 if (m_cusp_limit > 0.0 || m_cusp_limit < 0.0)
403 if (da1 > m_cusp_limit)
417 if (d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy))
419 if (m_angle_tolerance < curve_angle_tolerance_epsilon)
428 double da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1));
434 if (da1 < m_angle_tolerance)
444 if (m_cusp_limit > 0.0 || m_cusp_limit < 0.0)
446 if (da1 > m_cusp_limit)
460 if ((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy))
465 if (m_angle_tolerance < curve_angle_tolerance_epsilon)
474 const double k = atan2(y3 - y2, x3 - x2);
475 double da1 = fabs(k - atan2(y2 - y1, x2 - x1));
476 double da2 = fabs(atan2(y4 - y3, x4 - x3) - k);
486 if (da1 + da2 < m_angle_tolerance)
496 if (m_cusp_limit > 0.0 || m_cusp_limit < 0.0)
498 if (da1 > m_cusp_limit)
505 if (da2 > m_cusp_limit)
521 PointBezier_r(x1, y1, x12, y12, x123, y123, x1234, y1234,
static_cast<qint16
>(level + 1), px, py);
522 PointBezier_r(x1234, y1234, x234, y234, x34, y34, x4, y4,
static_cast<qint16
>(level + 1), px, py);
542 x.append ( p1.x () );
543 y.append ( p1.y () );
545 p3.x (), p3.y (), p4.x (), p4.y (), 0, wx, wy );
546 x.append ( p4.x () );
547 y.append ( p4.y () );
548 for ( qint32 i = 0; i < x.count(); ++i )
550 pvector.append( QPointF ( x.at(i), y.at(i)) );
574 qDebug()<<
"Wrong value t.";
578 seg1_2.setLength(seg1_2.length () * t);
579 const QPointF p12 = seg1_2.p2();
582 seg2_3.setLength(seg2_3.length () * t);
583 const QPointF p23 = seg2_3.p2();
585 QLineF seg12_23 ( p12, p23 );
586 seg12_23.setLength(seg12_23.length () * t);
587 const QPointF p123 = seg12_23.p2();
590 seg3_4.setLength(seg3_4.length () * t);
591 const QPointF p34 = seg3_4.p2();
593 QLineF seg23_34 ( p23, p34 );
594 seg23_34.setLength(seg23_34.length () * t);
595 const QPointF p234 = seg23_34.p2();
597 QLineF seg123_234 ( p123, p234 );
598 seg123_234.setLength(seg123_234.length () * t);
599 const QPointF p1234 = seg123_234.p2();
VAbstractBezier & operator=(const VAbstractBezier &curve)
VAbstractCubicBezier & operator=(const VAbstractCubicBezier &curve)
virtual VPointF GetP1() const =0
qreal LengthT(qreal t) const
VAbstractCubicBezier(const GOType &type, const quint32 &idObject=null_id, const Draw &mode=Draw::Calculation)
static qreal LengthBezier(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
LengthBezier return spline length using 4 spline point.
virtual void CreateName() Q_DECL_OVERRIDE
qreal GetParmT(qreal length) const
QPointF CutSpline(qreal length, QPointF &spl1p2, QPointF &spl1p3, QPointF &spl2p2, QPointF &spl2p3) const
CutSpline cut spline.
static qreal CalcSqDistance(qreal x1, qreal y1, qreal x2, qreal y2)
CalcSqDistance calculate squared distance.
virtual QPointF GetControlPoint2() const =0
static QVector< QPointF > GetCubicBezierPoints(const QPointF &p1, const QPointF &p2, const QPointF &p3, const QPointF &p4)
GetCubicBezierPoints return list with cubic bezier curve points.
virtual QPointF GetControlPoint1() const =0
static void PointBezier_r(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4, qint16 level, QVector< qreal > &px, QVector< qreal > &py)
PointBezier_r find spline point using four point of spline.
virtual QString NameForHistory(const QString &toolName) const Q_DECL_OVERRIDE
virtual VPointF GetP4() const =0
virtual ~VAbstractCubicBezier()
static qreal PathLength(const QVector< QPointF > &path)
quint32 GetDuplicate() const
virtual qreal GetLength() const =0
virtual QString name() const
name return name graphical object.
void setName(const QString &name)
setName set name graphical object.
double ToPixel(double val, const Unit &unit)