1 /************************************************************************
2 **
3 ** @file vspline.cpp
4 ** @author Roman Telezhynskyi <dismine(at)gmail.com>
5 ** @date November 15, 2013
6 **
7 ** @brief
8 ** @copyright
9 ** This source code is part of the Valentina project, a pattern making
10 ** program, whose allow create and modeling patterns of clothing.
11 ** Copyright (C) 2013-2015 Valentina project
12 ** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
13 **
14 ** Valentina is free software: you can redistribute it and/or modify
15 ** it under the terms of the GNU General Public License as published by
16 ** the Free Software Foundation, either version 3 of the License, or
17 ** (at your option) any later version.
18 **
19 ** Valentina is distributed in the hope that it will be useful,
20 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ** GNU General Public License for more details.
23 **
24 ** You should have received a copy of the GNU General Public License
25 ** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
26 **
27 *************************************************************************/
28
29 #include "vspline.h"
30
31 #include <QJsonObject>
32 #include <QLineF>
33
34 #include "vabstractcurve.h"
35 #include "vspline_p.h"
36 #include "../vmisc/vmath.h"
37
38 //---------------------------------------------------------------------------------------------------------------------
39 /**
40 * @brief VSpline default constructor
41 */
VSpline()42 VSpline::VSpline()
43 :VAbstractCubicBezier(GOType::Spline), d(new VSplineData)
44 {}
45
46 //---------------------------------------------------------------------------------------------------------------------
47 /**
48 * @brief VSpline constructor.
49 * @param spline spline from which the copy.
50 */
VSpline(const VSpline & spline)51 VSpline::VSpline ( const VSpline & spline )
52 :VAbstractCubicBezier(spline), d(spline.d)
53 {}
54
55 //---------------------------------------------------------------------------------------------------------------------
56 /**
57 * @brief VSpline constructor.
58 * @param p1 first point spline.
59 * @param p4 last point spline.
60 * @param angle1 angle from first point to first control point.
61 * @param angle2 angle from second point to second control point.
62 * @param kCurve coefficient of curvature spline.
63 * @param kAsm1 coefficient of length first control line.
64 * @param kAsm2 coefficient of length second control line.
65 */
VSpline(const VPointF & p1,const VPointF & p4,qreal angle1,qreal angle2,qreal kAsm1,qreal kAsm2,qreal kCurve,quint32 idObject,Draw mode)66 VSpline::VSpline (const VPointF &p1, const VPointF &p4, qreal angle1, qreal angle2, qreal kAsm1, qreal kAsm2,
67 qreal kCurve, quint32 idObject, Draw mode)
68 : VAbstractCubicBezier(GOType::Spline, idObject, mode),
69 d(new VSplineData(p1, p4, angle1, angle2, kAsm1, kAsm2, kCurve))
70 {
71 CreateName();
72 }
73
74 //---------------------------------------------------------------------------------------------------------------------
75 /**
76 * @brief VSpline constructor.
77 * @param p1 first point spline.
78 * @param p2 first control point.
79 * @param p3 second control point.
80 * @param p4 second point spline.
81 */
VSpline(const VPointF & p1,const QPointF & p2,const QPointF & p3,const VPointF & p4,quint32 idObject,Draw mode)82 VSpline::VSpline (const VPointF &p1, const QPointF &p2, const QPointF &p3, const VPointF &p4, quint32 idObject,
83 Draw mode)
84 :VAbstractCubicBezier(GOType::Spline, idObject, mode), d(new VSplineData(p1, p2, p3, p4))
85 {
86 CreateName();
87 }
88
89
90 //---------------------------------------------------------------------------------------------------------------------
91 /**
92 * @brief VSpline constructor
93 * @param p1 first point spline.
94 * @param p4 first control point.
95 * @param angle1 angle from first point to first control point.
96 * @param angle1Formula formula angle from first point to first control point.
97 * @param angle2 angle from second point to second control point.
98 * @param angle2Formula formula angle from second point to second control point.
99 * @param c1Length length from first point to first control point.
100 * @param c1LengthFormula formula length from first point to first control point.
101 * @param c2Length length from second point to first control point.
102 * @param c2LengthFormula formula length from second point to first control point.
103 */
VSpline(const VPointF & p1,const VPointF & p4,qreal angle1,const QString & angle1Formula,qreal angle2,const QString & angle2Formula,qreal c1Length,const QString & c1LengthFormula,qreal c2Length,const QString & c2LengthFormula,quint32 idObject,Draw mode)104 VSpline::VSpline(const VPointF &p1, const VPointF &p4, qreal angle1, const QString &angle1Formula, qreal angle2,
105 const QString &angle2Formula, qreal c1Length, const QString &c1LengthFormula, qreal c2Length,
106 const QString &c2LengthFormula, quint32 idObject, Draw mode)
107 : VAbstractCubicBezier(GOType::Spline, idObject, mode),
108 d(new VSplineData(p1, p4, angle1, angle1Formula, angle2, angle2Formula, c1Length, c1LengthFormula, c2Length,
109 c2LengthFormula))
110 {
111 CreateName();
112 }
113
114 //---------------------------------------------------------------------------------------------------------------------
Rotate(const QPointF & originPoint,qreal degrees,const QString & prefix) const115 VSpline VSpline::Rotate(const QPointF &originPoint, qreal degrees, const QString &prefix) const
116 {
117 const VPointF p1 = GetP1().Rotate(originPoint, degrees);
118 const VPointF p4 = GetP4().Rotate(originPoint, degrees);
119
120 const QPointF p2 = VPointF::RotatePF(originPoint, static_cast<QPointF>(GetP2()), degrees);
121 const QPointF p3 = VPointF::RotatePF(originPoint, static_cast<QPointF>(GetP3()), degrees);
122
123 VSpline spl(p1, p2, p3, p4);
124 spl.setName(name() + prefix);
125
126 if (not GetAliasSuffix().isEmpty())
127 {
128 spl.SetAliasSuffix(GetAliasSuffix() + prefix);
129 }
130
131 spl.SetColor(GetColor());
132 spl.SetPenStyle(GetPenStyle());
133 spl.SetApproximationScale(GetApproximationScale());
134 return spl;
135 }
136
137 //---------------------------------------------------------------------------------------------------------------------
Flip(const QLineF & axis,const QString & prefix) const138 VSpline VSpline::Flip(const QLineF &axis, const QString &prefix) const
139 {
140 const VPointF p1 = GetP1().Flip(axis);
141 const VPointF p4 = GetP4().Flip(axis);
142
143 const QPointF p2 = VPointF::FlipPF(axis, static_cast<QPointF>(GetP2()));
144 const QPointF p3 = VPointF::FlipPF(axis, static_cast<QPointF>(GetP3()));
145
146 VSpline spl(p1, p2, p3, p4);
147 spl.setName(name() + prefix);
148
149 if (not GetAliasSuffix().isEmpty())
150 {
151 spl.SetAliasSuffix(GetAliasSuffix() + prefix);
152 }
153
154 spl.SetColor(GetColor());
155 spl.SetPenStyle(GetPenStyle());
156 spl.SetApproximationScale(GetApproximationScale());
157 return spl;
158 }
159
160 //---------------------------------------------------------------------------------------------------------------------
Move(qreal length,qreal angle,const QString & prefix) const161 VSpline VSpline::Move(qreal length, qreal angle, const QString &prefix) const
162 {
163 const VPointF p1 = GetP1().Move(length, angle);
164 const VPointF p4 = GetP4().Move(length, angle);
165
166 const QPointF p2 = VPointF::MovePF(static_cast<QPointF>(GetP2()), length, angle);
167 const QPointF p3 = VPointF::MovePF(static_cast<QPointF>(GetP3()), length, angle);
168
169 VSpline spl(p1, p2, p3, p4);
170 spl.setName(name() + prefix);
171
172 if (not GetAliasSuffix().isEmpty())
173 {
174 spl.SetAliasSuffix(GetAliasSuffix() + prefix);
175 }
176
177 spl.SetColor(GetColor());
178 spl.SetPenStyle(GetPenStyle());
179 spl.SetApproximationScale(GetApproximationScale());
180 return spl;
181 }
182
183 //---------------------------------------------------------------------------------------------------------------------
~VSpline()184 VSpline::~VSpline()
185 {}
186
187 //---------------------------------------------------------------------------------------------------------------------
188 /**
189 * @brief GetLength return length of spline.
190 * @return length.
191 */
GetLength() const192 qreal VSpline::GetLength () const
193 {
194 return LengthBezier ( static_cast<QPointF>(GetP1()), static_cast<QPointF>(GetP2()), static_cast<QPointF>(GetP3()),
195 static_cast<QPointF>(GetP4()), GetApproximationScale());
196 }
197
198 //---------------------------------------------------------------------------------------------------------------------
CutSpline(qreal length,VSpline & spl1,VSpline & spl2) const199 QPointF VSpline::CutSpline(qreal length, VSpline &spl1, VSpline &spl2) const
200 {
201 QPointF spl1p2;
202 QPointF spl1p3;
203 QPointF spl2p2;
204 QPointF spl2p3;
205 const QPointF cutPoint = CutSpline (length, spl1p2, spl1p3, spl2p2, spl2p3 );
206
207 spl1 = VSpline(GetP1(), spl1p2, spl1p3, VPointF(cutPoint));
208 spl1.SetApproximationScale(GetApproximationScale());
209
210 spl2 = VSpline(VPointF(cutPoint), spl2p2, spl2p3, GetP4());
211 spl2.SetApproximationScale(GetApproximationScale());
212 return cutPoint;
213 }
214
215 //---------------------------------------------------------------------------------------------------------------------
216 /**
217 * @brief GetPoints return list with spline points.
218 * @return list of points.
219 */
GetPoints() const220 QVector<QPointF> VSpline::GetPoints () const
221 {
222 return GetCubicBezierPoints(static_cast<QPointF>(GetP1()), static_cast<QPointF>(GetP2()),
223 static_cast<QPointF>(GetP3()), static_cast<QPointF>(GetP4()), GetApproximationScale());
224 }
225
226 //---------------------------------------------------------------------------------------------------------------------
227 /**
228 * @brief SplinePoints return list with spline points.
229 * @param p1 first spline point.
230 * @param p4 last spline point.
231 * @param angle1 angle from first point to first control point.
232 * @param angle2 angle from second point to second control point.
233 * @param kAsm1 coefficient of length first control line.
234 * @param kAsm2 coefficient of length second control line.
235 * @param kCurve coefficient of curvature spline.
236 * @return list with spline points.
237 */
238 // cppcheck-suppress unusedFunction
SplinePoints(const QPointF & p1,const QPointF & p4,qreal angle1,qreal angle2,qreal kAsm1,qreal kAsm2,qreal kCurve,qreal approximationScale)239 QVector<QPointF> VSpline::SplinePoints(const QPointF &p1, const QPointF &p4, qreal angle1, qreal angle2, qreal kAsm1,
240 qreal kAsm2, qreal kCurve, qreal approximationScale)
241 {
242 QLineF p1pX(p1.x(), p1.y(), p1.x() + 100, p1.y());
243 p1pX.setAngle( angle1 );
244 qreal L = 0, radius = 0, angle = 90;
245 radius = QLineF(QPointF(p1.x(), p4.y()), p4).length();
246 L = kCurve * radius * 4 / 3 * tan( angle * M_PI_4 / 180.0 );
247 QLineF p1p2(p1.x(), p1.y(), p1.x() + L * kAsm1, p1.y());
248 p1p2.setAngle(angle1);
249 QLineF p4p3(p4.x(), p4.y(), p4.x() + L * kAsm2, p4.y());
250 p4p3.setAngle(angle2);
251 QPointF p2 = p1p2.p2();
252 QPointF p3 = p4p3.p2();
253 return GetCubicBezierPoints(p1, p2, p3, p4, approximationScale);
254 }
255
256 //---------------------------------------------------------------------------------------------------------------------
operator =(const VSpline & spline)257 VSpline &VSpline::operator =(const VSpline &spline)
258 {
259 if ( &spline == this )
260 {
261 return *this;
262 }
263 VAbstractCubicBezier::operator=(spline);
264 d = spline.d;
265 return *this;
266 }
267
268 #ifdef Q_COMPILER_RVALUE_REFS
269 //---------------------------------------------------------------------------------------------------------------------
VSpline(const VSpline && spline)270 VSpline::VSpline(const VSpline &&spline) Q_DECL_NOTHROW
271 :VAbstractCubicBezier(spline), d(spline.d)
272 {}
273
274 //---------------------------------------------------------------------------------------------------------------------
operator =(VSpline && spline)275 VSpline &VSpline::operator=(VSpline &&spline) Q_DECL_NOTHROW
276 {
277 VAbstractCubicBezier::operator=(spline);
278 std::swap(d, spline.d);
279 return *this;
280 }
281 #endif
282
283 //---------------------------------------------------------------------------------------------------------------------
284 /**
285 * @brief GetP1 return first spline point.
286 * @return first point.
287 */
GetP1() const288 VPointF VSpline::GetP1() const
289 {
290 return d->p1;
291 }
292
293 //---------------------------------------------------------------------------------------------------------------------
SetP1(const VPointF & p)294 void VSpline::SetP1(const VPointF &p)
295 {
296 d->p1 = p;
297 }
298
299 //---------------------------------------------------------------------------------------------------------------------
300 /**
301 * @brief GetP2 return first control point.
302 * @return first control point.
303 */
GetP2() const304 VPointF VSpline::GetP2() const
305 {
306 QLineF p1p2(d->p1.x(), d->p1.y(), d->p1.x() + d->c1Length, d->p1.y());
307 p1p2.setAngle(d->angle1);
308 return VPointF(p1p2.p2());
309 }
310
311 //---------------------------------------------------------------------------------------------------------------------
312 /**
313 * @brief GetP3 return second control point.
314 * @return second control point.
315 */
GetP3() const316 VPointF VSpline::GetP3() const
317 {
318 QLineF p4p3(d->p4.x(), d->p4.y(), d->p4.x() + d->c2Length, d->p4.y());
319 p4p3.setAngle(d->angle2);
320 return VPointF(p4p3.p2());
321 }
322
323 //---------------------------------------------------------------------------------------------------------------------
324 /**
325 * @brief GetP4 return last spline point.
326 * @return остання точка сплайну.
327 */
GetP4() const328 VPointF VSpline::GetP4() const
329 {
330 return d->p4;
331 }
332
333 //---------------------------------------------------------------------------------------------------------------------
SetP4(const VPointF & p)334 void VSpline::SetP4(const VPointF &p)
335 {
336 d->p4 = p;
337 }
338
339 //---------------------------------------------------------------------------------------------------------------------
340 /**
341 * @brief GetAngle1 return first angle control line.
342 * @return angle.
343 */
GetStartAngle() const344 qreal VSpline::GetStartAngle() const
345 {
346 return d->angle1;
347 }
348
349 //---------------------------------------------------------------------------------------------------------------------
350 /**
351 * @brief GetAngle2 return second angle control line.
352 * @return angle.
353 */
GetEndAngle() const354 qreal VSpline::GetEndAngle() const
355 {
356 return d->angle2;
357 }
358
359 //---------------------------------------------------------------------------------------------------------------------
GetStartAngleFormula() const360 QString VSpline::GetStartAngleFormula() const
361 {
362 return d->angle1F;
363 }
364
365 //---------------------------------------------------------------------------------------------------------------------
GetEndAngleFormula() const366 QString VSpline::GetEndAngleFormula() const
367 {
368 return d->angle2F;
369 }
370
371 //---------------------------------------------------------------------------------------------------------------------
SetStartAngle(qreal angle,const QString & formula)372 void VSpline::SetStartAngle(qreal angle, const QString &formula)
373 {
374 d->angle1 = angle;
375 d->angle1F = formula;
376 }
377
378 //---------------------------------------------------------------------------------------------------------------------
SetEndAngle(qreal angle,const QString & formula)379 void VSpline::SetEndAngle(qreal angle, const QString &formula)
380 {
381 d->angle2 = angle;
382 d->angle2F = formula;
383 }
384
385 //---------------------------------------------------------------------------------------------------------------------
GetC1Length() const386 qreal VSpline::GetC1Length() const
387 {
388 return d->c1Length;
389 }
390
391 //---------------------------------------------------------------------------------------------------------------------
GetC2Length() const392 qreal VSpline::GetC2Length() const
393 {
394 return d->c2Length;
395 }
396
397 //---------------------------------------------------------------------------------------------------------------------
GetC1LengthFormula() const398 QString VSpline::GetC1LengthFormula() const
399 {
400 return d->c1LengthF;
401 }
402
403 //---------------------------------------------------------------------------------------------------------------------
GetC2LengthFormula() const404 QString VSpline::GetC2LengthFormula() const
405 {
406 return d->c2LengthF;
407 }
408
409 //---------------------------------------------------------------------------------------------------------------------
SetC1Length(qreal length,const QString & formula)410 void VSpline::SetC1Length(qreal length, const QString &formula)
411 {
412 d->c1Length = length;
413 d->c1LengthF = formula;
414 }
415
416 //---------------------------------------------------------------------------------------------------------------------
SetC2Length(qreal length,const QString & formula)417 void VSpline::SetC2Length(qreal length, const QString &formula)
418 {
419 d->c2Length = length;
420 d->c2LengthF = formula;
421 }
422
423 //---------------------------------------------------------------------------------------------------------------------
424 /**
425 * @brief GetKasm1 return coefficient of length first control line.
426 * @return coefficient.
427 */
GetKasm1() const428 qreal VSpline::GetKasm1() const
429 {
430 return QLineF(static_cast<QPointF>(d->p1), static_cast<QPointF>(GetP2())).length() /
431 VSplineData::GetL(static_cast<QPointF>(d->p1), static_cast<QPointF>(d->p4), d->kCurve);
432 }
433
434 //---------------------------------------------------------------------------------------------------------------------
435 /**
436 * @brief GetKasm2 return coefficient of length second control line.
437 * @return coefficient.
438 */
GetKasm2() const439 qreal VSpline::GetKasm2() const
440 {
441 return QLineF(static_cast<QPointF>(d->p4), static_cast<QPointF>(GetP3())).length() /
442 VSplineData::GetL(static_cast<QPointF>(d->p1), static_cast<QPointF>(d->p4), d->kCurve);
443 }
444
445 //---------------------------------------------------------------------------------------------------------------------
446 /**
447 * @brief GetKcurve return coefficient of curvature spline.
448 * @return coefficient
449 */
GetKcurve() const450 qreal VSpline::GetKcurve() const
451 {
452 return d->kCurve;
453 }
454
455 //---------------------------------------------------------------------------------------------------------------------
Sign(long double ld)456 int VSpline::Sign(long double ld)
457 {
458 if (qAbs(ld)<0.00000000001)
459 {
460 return 0;
461 }
462 return (ld>0) ? 1 : -1;
463 }
464
465 //---------------------------------------------------------------------------------------------------------------------
466 /**
467 * @brief Cubic Cubic equation solution. Real coefficients case.
468 *
469 * This method use method Vieta-Cardano for eval cubic equations.
470 * Cubic equation write in form x3+a*x2+b*x+c=0.
471 *
472 * Output:
473 * 3 real roots -> then x is filled with them;
474 * 1 real + 2 complex -> x[0] is real, x[1] is real part of complex roots, x[2] - non-negative imaginary part.
475 *
476 * @param x solution array (size 3).
477 * @param a coefficient
478 * @param b coefficient
479 * @param c coefficient
480 * @return 3 - 3 real roots;
481 * 1 - 1 real root + 2 complex;
482 * 2 - 1 real root + complex roots imaginary part is zero (i.e. 2 real roots).
483 */
Cubic(QVector<qreal> & x,qreal a,qreal b,qreal c)484 qint32 VSpline::Cubic(QVector<qreal> &x, qreal a, qreal b, qreal c)
485 {
486 //To find cubic equation roots in the case of real coefficients, calculated at the beginning
487 const qreal q = (pow(a, 2) - 3*b)/9.;
488 const qreal r = (2*pow(a, 3) - 9*a*b + 27.*c)/54.;
489 if (pow(r, 2) < pow(q, 3))
490 { // equation has three real roots, use formula Vieta
491 const qreal t = acos(r/sqrt(pow(q, 3)))/3.;
492 x.insert(0, -2.*sqrt(q)*cos(t)-a/3);
493 x.insert(1, -2.*sqrt(q)*cos(t + (2*M_2PI/3.)) - a/3.);
494 x.insert(2, -2.*sqrt(q)*cos(t - (2*M_2PI/3.)) - a/3.);
495 return(3);
496 }
497 else
498 { // 1 real root + 2 complex
499 //Formula Cardano
500 const qreal aa = -Sign(r)*pow(fabs(r)+sqrt(pow(r, 2)-pow(q, 3)), 1./3.);
501 const qreal bb = Sign(aa) == 0 ? 0 : q/aa;
502
503 x.insert(0, aa+bb-a/3.); // Real root
504 x.insert(1, (-0.5)*(aa+bb)-a/3.); //Complex root
505 x.insert(2, (sqrt(3.)*0.5)*fabs(aa-bb)); // Complex root
506 if (qFuzzyIsNull(x.at(2)))
507 {
508 return(2);
509 }
510 return(1);
511 }
512 }
513
514 //---------------------------------------------------------------------------------------------------------------------
CalcT(qreal curveCoord1,qreal curveCoord2,qreal curveCoord3,qreal curveCoord4,qreal pointCoord) const515 QVector<qreal> VSpline::CalcT (qreal curveCoord1, qreal curveCoord2, qreal curveCoord3,
516 qreal curveCoord4, qreal pointCoord) const
517 {
518 const qreal a = -curveCoord1 + 3*curveCoord2 - 3*curveCoord3 + curveCoord4;
519 const qreal b = 3*curveCoord1 - 6*curveCoord2 + 3*curveCoord3;
520 const qreal c = -3*curveCoord1 + 3*curveCoord2;
521 const qreal d = -pointCoord + curveCoord1;
522
523 QVector<qreal> t = QVector<qreal>(3, -1);
524 Cubic(t, b/a, c/a, d/a);
525
526 QVector<qreal> retT;
527 for (int i=0; i < t.size(); ++i)
528 {
529 if ( t.at(i) >= 0 && t.at(i) <= 1 )
530 {
531 retT.append(t.at(i));
532 }
533 }
534
535 return retT;
536 }
537
538 //---------------------------------------------------------------------------------------------------------------------
539 /**
540 * @brief VSpline::ParamT calculate t coeffient that reprezent point on curve.
541 *
542 * Each point that belongs to Cubic Bézier curve can be shown by coefficient in interval [0; 1].
543 *
544 * @param pBt point on curve
545 * @return t coeffient that reprezent this point on curve. Return -1 if point doesn't belongs to curve.
546 */
ParamT(const QPointF & pBt) const547 qreal VSpline::ParamT (const QPointF &pBt) const
548 {
549 QVector<qreal> ts;
550 // Calculate t coefficient for each axis
551 ts += CalcT (GetP1().x(), GetP2().x(), GetP3().x(), GetP4().x(), pBt.x());
552 ts += CalcT (GetP1().y(), GetP2().y(), GetP3().y(), GetP4().y(), pBt.y());
553
554 if (ts.isEmpty())
555 {
556 return -1; // We don't have candidates
557 }
558
559 qreal tx = -1;
560 qreal eps = 3; // Error calculation
561
562 // In morst case we will have 6 result in interval [0; 1].
563 // Here we try find closest to our point.
564 for (auto t : qAsConst(ts))
565 {
566 const QPointF p0 = static_cast<QPointF>(GetP1());
567 const QPointF p1 = static_cast<QPointF>(GetP2());
568 const QPointF p2 = static_cast<QPointF>(GetP3());
569 const QPointF p3 = static_cast<QPointF>(GetP4());
570 //The explicit form of the Cubic Bézier curve
571 const qreal pointX = pow(1-t, 3)*p0.x() + 3*pow(1-t, 2)*t*p1.x() + 3*(1-t)*pow(t, 2)*p2.x() + pow(t, 3)*p3.x();
572 const qreal pointY = pow(1-t, 3)*p0.y() + 3*pow(1-t, 2)*t*p1.y() + 3*(1-t)*pow(t, 2)*p2.y() + pow(t, 3)*p3.y();
573
574 const QLineF line(pBt, QPointF(pointX, pointY));
575 if (line.length() <= eps)
576 {
577 tx = t;
578 eps = line.length(); //Next point should be even closest
579 }
580 }
581
582 return tx;
583 }
584
585 //---------------------------------------------------------------------------------------------------------------------
ToJson() const586 QJsonObject VSpline::ToJson() const
587 {
588 QJsonObject object = VAbstractCubicBezier::ToJson();
589 object[QLatin1String("aScale")] = GetApproximationScale();
590 object[QLatin1String("p1")] = GetP1().ToJson();
591 object[QLatin1String("p4")] = GetP4().ToJson();
592 object[QLatin1String("angle1")] = GetStartAngle();
593 object[QLatin1String("angle1Formula")] = GetStartAngleFormula();
594 object[QLatin1String("angle2")] = GetEndAngle();
595 object[QLatin1String("angle2Formula")] = GetEndAngleFormula();
596 object[QLatin1String("c1Length")] = GetC1Length();
597 object[QLatin1String("c1LengthFormula")] = GetC1LengthFormula();
598 object[QLatin1String("c2Length")] = GetC2Length();
599 object[QLatin1String("c2LengthFormula")] = GetC2LengthFormula();
600 return object;
601 }
602
603 //---------------------------------------------------------------------------------------------------------------------
GetControlPoint1() const604 QPointF VSpline::GetControlPoint1() const
605 {
606 return static_cast<QPointF>(GetP2 ());
607 }
608
609 //---------------------------------------------------------------------------------------------------------------------
GetControlPoint2() const610 QPointF VSpline::GetControlPoint2() const
611 {
612 return static_cast<QPointF>(GetP3 ());
613 }
614