Seamly2D
Code documentation
vgobject.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * *
3  * Copyright (C) 2017 Seamly, LLC *
4  * *
5  * https://github.com/fashionfreedom/seamly2d *
6  * *
7  ***************************************************************************
8  **
9  ** Seamly2D is free software: you can redistribute it and/or modify
10  ** it under the terms of the GNU General Public License as published by
11  ** the Free Software Foundation, either version 3 of the License, or
12  ** (at your option) any later version.
13  **
14  ** Seamly2D is distributed in the hope that it will be useful,
15  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  ** GNU General Public License for more details.
18  **
19  ** You should have received a copy of the GNU General Public License
20  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
21  **
22  **************************************************************************
23 
24  ************************************************************************
25  **
26  ** @file vgobject.cpp
27  ** @author Roman Telezhynskyi <dismine(at)gmail.com>
28  ** @date 27 12, 2013
29  **
30  ** @brief
31  ** @copyright
32  ** This source code is part of the Valentine project, a pattern making
33  ** program, whose allow create and modeling patterns of clothing.
34  ** Copyright (C) 2013-2015 Seamly2D project
35  ** <https://github.com/fashionfreedom/seamly2d> All Rights Reserved.
36  **
37  ** Seamly2D is free software: you can redistribute it and/or modify
38  ** it under the terms of the GNU General Public License as published by
39  ** the Free Software Foundation, either version 3 of the License, or
40  ** (at your option) any later version.
41  **
42  ** Seamly2D is distributed in the hope that it will be useful,
43  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
44  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45  ** GNU General Public License for more details.
46  **
47  ** You should have received a copy of the GNU General Public License
48  ** along with Seamly2D. If not, see <http://www.gnu.org/licenses/>.
49  **
50  *************************************************************************/
51 
52 #include "vgobject.h"
53 
54 #include <QLine>
55 #include <QLineF>
56 #include <QPoint>
57 #include <QPointF>
58 #include <QRectF>
59 #include <QTransform>
60 
61 #include "../vmisc/def.h"
62 #include "../vmisc/vmath.h"
63 #include "../ifc/ifcdef.h"
64 #include "vgobject_p.h"
65 
66 const double VGObject::accuracyPointOnLine = (0.1555/*mm*/ / 25.4) * 96.0;
67 
68 #ifdef Q_COMPILER_RVALUE_REFS
69 VGObject &VGObject::operator=(VGObject &&obj) Q_DECL_NOTHROW { Swap(obj); return *this; }
70 #endif
71 
72 void VGObject::Swap(VGObject &obj) Q_DECL_NOTHROW
73 { std::swap(d, obj.d); }
74 
75 //---------------------------------------------------------------------------------------------------------------------
76 /**
77  * @brief VGObject default constructor.
78  */
80  :d(new VGObjectData)
81 {}
82 
83 //---------------------------------------------------------------------------------------------------------------------
84 /**
85  * @brief VGObject constructor.
86  * @param type type graphical object.
87  * @param idObject id parent object.
88  * @param mode mode creation. Used in modeling mode.
89  */
90 VGObject::VGObject(const GOType &type, const quint32 &idObject, const Draw &mode)
91  :d(new VGObjectData(type, idObject, mode))
92 {}
93 
94 //---------------------------------------------------------------------------------------------------------------------
95 /**
96  * @brief VGObject copy constructor.
97  * @param obj object.
98  */
100  :d (obj.d)
101 {}
102 
103 //---------------------------------------------------------------------------------------------------------------------
104 /**
105  * @brief operator = assignment operator.
106  * @param obj object
107  * @return object
108  */
110 {
111  if ( &obj == this )
112  {
113  return *this;
114  }
115  d = obj.d;
116  return *this;
117 }
118 
119 //---------------------------------------------------------------------------------------------------------------------
121 {}
122 
123 //---------------------------------------------------------------------------------------------------------------------
124 /**
125  * @brief getIdObject return parent id.
126  * @return parent id or 0 if object don't have parent.
127  */
128 quint32 VGObject::getIdObject() const
129 {
130  return d->idObject;
131 }
132 
133 //---------------------------------------------------------------------------------------------------------------------
134 /**
135  * @brief setIdObject set parent id.
136  * @param value parent id.
137  */
138 void VGObject::setIdObject(const quint32 &value)
139 {
140  d->idObject = value;
141 }
142 
143 //---------------------------------------------------------------------------------------------------------------------
144 /**
145  * @brief name return name graphical object.
146  * @return name
147  */
148 QString VGObject::name() const
149 {
150  return d->_name;
151 }
152 
153 //---------------------------------------------------------------------------------------------------------------------
154 /**
155  * @brief setName set name graphical object.
156  * @param name name graphical object.
157  */
158 void VGObject::setName(const QString &name)
159 {
160  d->_name = name;
161 }
162 
163 //---------------------------------------------------------------------------------------------------------------------
164 /**
165  * @brief getMode return mode creation.
166  * @return mode.
167  */
169 {
170  return d->mode;
171 }
172 
173 //---------------------------------------------------------------------------------------------------------------------
174 /**
175  * @brief setMode set mode creation.
176  * @param value mode.
177  */
178 void VGObject::setMode(const Draw &value)
179 {
180  d->mode = value;
181 }
182 
183 //---------------------------------------------------------------------------------------------------------------------
184 /**
185  * @brief getType return object type.
186  * @return type.
187  */
189 {
190  return d->type;
191 }
192 
193 //---------------------------------------------------------------------------------------------------------------------
194 // cppcheck-suppress unusedFunction
195 void VGObject::setType(const GOType &type)
196 {
197  d->type = type;
198 }
199 
200 //---------------------------------------------------------------------------------------------------------------------
201 /**
202  * @brief id return id object.
203  * @return id
204  */
205 quint32 VGObject::id() const
206 {
207  return d->_id;
208 }
209 
210 //---------------------------------------------------------------------------------------------------------------------
211 /**
212  * @brief setId set id object.
213  * @param id id.
214  */
215 void VGObject::setId(const quint32 &id)
216 {
217  d->_id = id;
218 }
219 
220 //---------------------------------------------------------------------------------------------------------------------
221 quint32 VGObject::getIdTool() const
222 {
223  if (d->mode == Draw::Calculation)
224  {
225  if (d->idObject != NULL_ID)
226  {
227  return d->idObject;
228  }
229  else
230  {
231  return d->_id;
232  }
233  }
234  else
235  {
236  return d->_id;
237  }
238 }
239 
240 //---------------------------------------------------------------------------------------------------------------------
241 QLineF VGObject::BuildLine(const QPointF &p1, const qreal &length, const qreal &angle)
242 {
243  QLineF line = QLineF();
244  line.setP1(p1);
245  line.setAngle(angle);// First set angle then length. Length can have negative value.
246  line.setLength(length);
247  return line;
248 }
249 
250 //---------------------------------------------------------------------------------------------------------------------
251 QPointF VGObject::BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect)
252 {
253  QRectF rect = scRect;
254  if (rect.isValid() == false)
255  {
256  rect = QRectF(0, 0, 1200, 700);
257  }
258  if (rect.contains(firstPoint) == false)
259  {
260  // If point outside of scene rect create one around point and unite two rects.
261  QRectF rectangle(firstPoint.x()-rect.width()/2, firstPoint.y()-rect.height()/2, rect.width(), rect.height());
262  rect = rect.united(rectangle);
263  }
264  const qreal diagonal = qSqrt(pow(rect.height(), 2) + pow(rect.width(), 2));
265  const QLineF line = BuildLine(firstPoint, diagonal, angle);
266 
267  return LineIntersectRect(rect, line);
268 }
269 
270 //---------------------------------------------------------------------------------------------------------------------
271 QLineF VGObject::BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect)
272 {
273  const QPointF endP1 = BuildRay(p, angle+180, scRect);
274  const QPointF endP2 = BuildRay(p, angle, scRect);
275  return QLineF(endP1, endP2);
276 }
277 
278 //---------------------------------------------------------------------------------------------------------------------
279 QLineF VGObject::BuildAxis(const QPointF &p1, const QPointF &p2, const QRectF &scRect)
280 {
281  QLineF line(p1, p2);
282  return BuildAxis(p1, line.angle(), scRect);
283 }
284 
285 //---------------------------------------------------------------------------------------------------------------------
286 int VGObject::ContactPoints(const QPointF &p, const QPointF &center, qreal radius, QPointF &p1, QPointF &p2)
287 {
288  const int flag = PointInCircle(p, center, radius);
289 
290  if (flag == 0)
291  {
292  return 0;
293  }
294 
295  if (flag == 1)
296  {
297  p1 = p;
298  return 1;
299  }
300 
301  const double d = QLineF (p, center).length();
302  const double k = sqrt (d * d - radius * radius);
303  return IntersectionCircles(p, k, center, radius, p1, p2);
304 }
305 
306 //---------------------------------------------------------------------------------------------------------------------
307 /**
308  * @brief LineIntersectRect find point intersection line and rect.
309  * @param rec rect.
310  * @param line line.
311  * @return point intersection.
312  */
313 QPointF VGObject::LineIntersectRect(const QRectF &rec, const QLineF &line)
314 {
315  qreal x1, y1, x2, y2;
316  rec.getCoords(&x1, &y1, &x2, &y2);
317  QPointF point;
318  QLineF::IntersectType type = line.intersects(QLineF(QPointF(x1, y1), QPointF(x1, y2)), &point);
319  if ( type == QLineF::BoundedIntersection )
320  {
321  return point;
322  }
323  type = line.intersects(QLineF(QPointF(x1, y1), QPointF(x2, y1)), &point);
324  if ( type == QLineF::BoundedIntersection )
325  {
326  return point;
327  }
328  type = line.intersects(QLineF(QPointF(x1, y2), QPointF(x2, y2)), &point);
329  if ( type == QLineF::BoundedIntersection )
330  {
331  return point;
332  }
333  type = line.intersects(QLineF(QPointF(x2, y1), QPointF(x2, y2)), &point);
334  if ( type == QLineF::BoundedIntersection )
335  {
336  return point;
337  }
338  return point;
339 }
340 
341 //---------------------------------------------------------------------------------------------------------------------
342 int VGObject::IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1, QPointF &p2)
343 {
344  if (VFuzzyComparePossibleNulls(c1.x(), c2.x()) && VFuzzyComparePossibleNulls(c1.y(), c2.y())
345  && VFuzzyComparePossibleNulls(r1, r2))
346  {
347  return 3;// Circles are equal
348  }
349  const double a = - 2.0 * (c2.x() - c1.x());
350  const double b = - 2.0 * (c2.y() - c1.y());
351  const double c = (c2.x() - c1.x())* (c2.x() - c1.x()) + (c2.y() - c1.y()) * (c2.y() - c1.y()) + r1 * r1 - r2 * r2;
352 
353  const double x0 = -a*c/(a*a+b*b);
354  const double y0 = -b*c/(a*a+b*b);
355 
356  if (c*c > r1*r1*(a*a+b*b))
357  {
358  return 0;
359  }
360  else if (VFuzzyComparePossibleNulls(c*c, r1*r1*(a*a+b*b)))
361  {
362  p1 = QPointF(x0 + c1.x(), y0 + c1.y());
363  return 1;
364  }
365  else
366  {
367  const double d = r1*r1 - c*c/(a*a+b*b);
368  const double mult = sqrt (d / (a*a+b*b));
369 
370  const double ax = x0 + b * mult;
371  const double bx = x0 - b * mult;
372  const double ay = y0 - a * mult;
373  const double by = y0 + a * mult;
374 
375  p1 = QPointF(ax + c1.x(), ay + c1.y());
376  p2 = QPointF(bx + c1.x(), by + c1.y());
377  return 2;
378  }
379 }
380 
381 //---------------------------------------------------------------------------------------------------------------------
382 /**
383  * @brief LineIntersectCircle find point intersection line and circle.
384  * @param center arc center.
385  * @param radius arc radius.
386  * @param line line
387  * @param p1 first intersection point.
388  * @param p2 second intersection point.
389  * @return 0 - intersection doesn't exist, 1 - one intersection point, 2 - two intersection points.
390  */
391 qint32 VGObject::LineIntersectCircle(const QPointF &center, qreal radius, const QLineF &line, QPointF &p1, QPointF &p2)
392 {
393  if (qFuzzyIsNull(line.length()))
394  {
395  return 0;
396  }
397 
398  //coefficient for equation of segment
399  qreal a = 0, b = 0, c = 0;
400  LineCoefficients(line, &a, &b, &c);
401  // projection center of circle on to line
402  const QPointF p = ClosestPoint (line, center);
403  // how many solutions?
404  qint32 flag = 0;
405  const qreal d = QLineF (center, p).length();
406  if (VFuzzyComparePossibleNulls(d, radius))
407  {
408  flag = 1;
409  }
410  else
411  {
412  if (radius > d)
413  {
414  flag = 2;
415  }
416  else
417  {
418  return 0;
419  }
420  }
421  // find distance from projection to points of intersection
422  const qreal k = qSqrt (qAbs(radius * radius - d * d));
423  const qreal t = QLineF (QPointF (0, 0), QPointF (b, - a)).length();
424  // add to projection a vectors aimed to points of intersection
425  p1 = addVector (p, QPointF (0, 0), QPointF (- b, a), k / t);
426  p2 = addVector (p, QPointF (0, 0), QPointF (b, - a), k / t);
427  return flag;
428 }
429 
430 //---------------------------------------------------------------------------------------------------------------------
431 /**
432  * @brief ClosestPoint find point projection of point onto line.
433  * @param line line.
434  * @return point on line or extended line if origin size too small.
435  */
436 QPointF VGObject::ClosestPoint(const QLineF &line, const QPointF &point)
437 {
438  qreal a = 0, b = 0, c = 0;
439  LineCoefficients(line, &a, &b, &c);
440  qreal x = point.x() + a;
441  qreal y = b + point.y();
442  QLineF lin (point, QPointF(x, y));
443  QPointF p;
444  QLineF::IntersectType intersect = line.intersects(lin, &p);
445  if (intersect == QLineF::UnboundedIntersection || intersect == QLineF::BoundedIntersection)
446  {
447  return p;
448  }
449  else
450  {
451  return point;
452  }
453 }
454 
455 //---------------------------------------------------------------------------------------------------------------------
456 QPointF VGObject::addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k)
457 {
458  return QPointF (p.x() + (p2.x() - p1.x()) * k, p.y() + (p2.y() - p1.y()) * k);
459 }
460 
461 //---------------------------------------------------------------------------------------------------------------------
462 /**
463  * @brief LineCoefficients coefficient for equation of segment. Segment equestion ax+by+c=0.
464  * @param line line
465  * @param a a value
466  * @param b b value
467  * @param c c value
468  */
469 void VGObject::LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c)
470 {
471  //coefficient for equation of segment
472  QPointF p1 = line.p1();
473  *a = line.p2().y() - p1.y();
474  *b = p1.x() - line.p2().x();
475  *c = - *a * p1.x() - *b * p1.y();
476 }
477 
478 //---------------------------------------------------------------------------------------------------------------------
479 /**
480  * @brief IsPointOnLineSegment Check if the point is on the line segment.
481  *
482  * Original idea http://www.sunshine2k.de/coding/java/PointOnLine/PointOnLine.html
483  */
484 bool VGObject::IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2)
485 {
486  // The test point must lie inside the bounding box spanned by the two line points.
487  if (not ( (p1.x() <= t.x() && t.x() <= p2.x()) || (p2.x() <= t.x() && t.x() <= p1.x()) ))
488  {
489  if (not (qAbs(p1.x() - t.x()) <= accuracyPointOnLine) && not (qAbs(p2.x() - t.x()) <= accuracyPointOnLine))
490  {
491  // test point not in x-range
492  return false;
493  }
494  }
495 
496  if (not ( (p1.y() <= t.y() && t.y() <= p2.y()) || (p2.y() <= t.y() && t.y() <= p1.y()) ))
497  {
498  if (not (qAbs(p1.y() - t.y()) <= accuracyPointOnLine) && not (qAbs(p2.y() - t.y()) <= accuracyPointOnLine))
499  {
500  // test point not in y-range
501  return false;
502  }
503  }
504 
505  // Test via the perp dot product (PDP)
506  return IsPointOnLineviaPDP(t, p1, p2);
507 }
508 
509 //---------------------------------------------------------------------------------------------------------------------
510 /**
511  * @brief IsPointOnLineviaPDP use the perp dot product (PDP) way.
512  *
513  * The pdp is zero only if the t lies on the line e1 = vector from p1 to p2.
514  * @return true if point is on line
515  */
516 bool VGObject::IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2)
517 {
518  const double p = qAbs(PerpDotProduct(p1, p2, t));
519  const double e = GetEpsilon(p1, p2);
520  // We can't use common "<=" here because of the floating-point accuraccy problem
521  return p < e || VFuzzyComparePossibleNulls(p, e);
522 }
523 
524 //---------------------------------------------------------------------------------------------------------------------
525 /**
526  * @brief PerpDotProduct Calculates the area of the parallelogram of the three points.
527  * This is actually the same as the area of the triangle defined by the three points, multiplied by 2.
528  * @return 2 * triangleArea(a,b,c)
529  */
530 double VGObject::PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t)
531 {
532  return (p1.x() - t.x()) * (p2.y() - t.y()) - (p1.y() - t.y()) * (p2.x() - t.x());
533 }
534 
535 //---------------------------------------------------------------------------------------------------------------------
536 /**
537  * @brief GetEpsilon solve the floating-point accuraccy problem.
538  *
539  * There is the floating-point accuraccy problem, so instead of checking against zero, some epsilon value has to be
540  * used. Because the size of the pdp value depends on the length of the vectors, no static value can be used. One
541  * approach is to compare the pdp/area value to the fraction of another area which also depends on the length of the
542  * line e1=(p1, p2), e.g. the minimal area calucalted with PerpDotProduc() if point still not on the line. This distance
543  * is controled by variable accuracyPointOnLine
544  */
545 double VGObject::GetEpsilon(const QPointF &p1, const QPointF &p2)
546 {
547  QLineF line(p1, p2);
548  line.setAngle(line.angle() + 90);
549  line.setLength(accuracyPointOnLine); // less than accuracy means the same point
550 
551  return qAbs(PerpDotProduct(p1, p2, line.p2()));
552 }
553 
554 //---------------------------------------------------------------------------------------------------------------------
555 int VGObject::PointInCircle(const QPointF &p, const QPointF &center, qreal radius)
556 {
557  const double d = QLineF (p, center).length();
558  if (VFuzzyComparePossibleNulls(radius, d))
559  {
560  return 1; // on circle
561  }
562  if (radius > d)
563  {
564  return 0; // outside circle
565  }
566  return 2; // inside circle
567 }
568 
569 //---------------------------------------------------------------------------------------------------------------------
570 /**
571  * @brief GetLengthContour return length of contour.
572  * @param contour container with points of contour.
573  * @param newPoints point whos we try to add to contour.
574  * @return length length of contour.
575  */
576 // cppcheck-suppress unusedFunction
577 int VGObject::GetLengthContour(const QVector<QPointF> &contour, const QVector<QPointF> &newPoints)
578 {
579  qreal length = 0;
580  QVector<QPointF> points;
581  points << contour << newPoints;
582  for (qint32 i = 0; i < points.size()-1; ++i)
583  {
584  QLineF line(points.at(i), points.at(i+1));
585  length += line.length();
586  }
587  return qFloor(length);
588 }
589 
590 //---------------------------------------------------------------------------------------------------------------------
591 QTransform VGObject::flipTransform(const QLineF &axis)
592 {
593  QTransform transform;
594 
595  if (axis.isNull())
596  {
597  return transform;
598  }
599 
600  const QLineF axisOX = QLineF(axis.x2(), axis.y2(), axis.x2() + 100, axis.y2()); // Ox axis
601 
602  const qreal angle = axis.angleTo(axisOX);
603  const QPointF p2 = axis.p2();
604 
605  QTransform m;
606  m.translate(p2.x(), p2.y());
607  m.rotate(-angle);
608  m.translate(-p2.x(), -p2.y());
609  transform *= m;
610 
611  m.reset();
612  m.translate(p2.x(), p2.y());
613  m.scale(m.m11(), m.m22()*-1);
614  m.translate(-p2.x(), -p2.y());
615  transform *= m;
616 
617  m.reset();
618  m.translate(p2.x(), p2.y());
619  m.rotate(-(360-angle));
620  m.translate(-p2.x(), -p2.y());
621  transform *= m;
622 
623  return transform;
624 }
The VGObject class keep information graphical objects.
Definition: vgobject.h:74
static bool IsPointOnLineSegment(const QPointF &t, const QPointF &p1, const QPointF &p2)
IsPointOnLineSegment Check if the point is on the line segment.
Definition: vgobject.cpp:484
static double PerpDotProduct(const QPointF &p1, const QPointF &p2, const QPointF &t)
PerpDotProduct Calculates the area of the parallelogram of the three points. This is actually the sam...
Definition: vgobject.cpp:530
GOType getType() const
getType return object type.
Definition: vgobject.cpp:188
static double GetEpsilon(const QPointF &p1, const QPointF &p2)
GetEpsilon solve the floating-point accuraccy problem.
Definition: vgobject.cpp:545
void setMode(const Draw &value)
setMode set mode creation.
Definition: vgobject.cpp:178
void setType(const GOType &type)
Definition: vgobject.cpp:195
void setIdObject(const quint32 &value)
setIdObject set parent id.
Definition: vgobject.cpp:138
static QLineF BuildAxis(const QPointF &p, const qreal &angle, const QRectF &scRect)
Definition: vgobject.cpp:271
static qint32 LineIntersectCircle(const QPointF &center, qreal radius, const QLineF &line, QPointF &p1, QPointF &p2)
LineIntersectCircle find point intersection line and circle.
Definition: vgobject.cpp:391
VGObject()
VGObject default constructor.
Definition: vgobject.cpp:79
static QPointF ClosestPoint(const QLineF &line, const QPointF &point)
ClosestPoint find point projection of point onto line.
Definition: vgobject.cpp:436
virtual QString name() const
name return name graphical object.
Definition: vgobject.cpp:148
VGObject & operator=(const VGObject &obj)
operator = assignment operator.
Definition: vgobject.cpp:109
static QTransform flipTransform(const QLineF &axis)
Definition: vgobject.cpp:591
static void LineCoefficients(const QLineF &line, qreal *a, qreal *b, qreal *c)
LineCoefficients coefficient for equation of segment. Segment equestion ax+by+c=0.
Definition: vgobject.cpp:469
static int IntersectionCircles(const QPointF &c1, double r1, const QPointF &c2, double r2, QPointF &p1, QPointF &p2)
Definition: vgobject.cpp:342
static bool IsPointOnLineviaPDP(const QPointF &t, const QPointF &p1, const QPointF &p2)
IsPointOnLineviaPDP use the perp dot product (PDP) way.
Definition: vgobject.cpp:516
static int PointInCircle(const QPointF &p, const QPointF &center, qreal radius)
Definition: vgobject.cpp:555
static QPointF BuildRay(const QPointF &firstPoint, const qreal &angle, const QRectF &scRect)
Definition: vgobject.cpp:251
virtual ~VGObject()
Definition: vgobject.cpp:120
static QLineF BuildLine(const QPointF &p1, const qreal &length, const qreal &angle)
Definition: vgobject.cpp:241
QSharedDataPointer< VGObjectData > d
Definition: vgobject.h:130
void Swap(VGObject &obj) Q_DECL_NOTHROW
Definition: vgobject.cpp:72
quint32 getIdObject() const
getIdObject return parent id.
Definition: vgobject.cpp:128
static QPointF LineIntersectRect(const QRectF &rec, const QLineF &line)
LineIntersectRect find point intersection line and rect.
Definition: vgobject.cpp:313
void setName(const QString &name)
setName set name graphical object.
Definition: vgobject.cpp:158
Draw getMode() const
getMode return mode creation.
Definition: vgobject.cpp:168
quint32 id() const
id return id object.
Definition: vgobject.cpp:205
virtual void setId(const quint32 &id)
setId set id object.
Definition: vgobject.cpp:215
static QPointF addVector(const QPointF &p, const QPointF &p1, const QPointF &p2, qreal k)
Definition: vgobject.cpp:456
static int GetLengthContour(const QVector< QPointF > &contour, const QVector< QPointF > &newPoints)
GetLengthContour return length of contour.
Definition: vgobject.cpp:577
static int ContactPoints(const QPointF &p, const QPointF &center, qreal radius, QPointF &p1, QPointF &p2)
Definition: vgobject.cpp:286
quint32 getIdTool() const
Definition: vgobject.cpp:221
static const double accuracyPointOnLine
Definition: vgobject.h:126
static Q_REQUIRED_RESULT bool VFuzzyComparePossibleNulls(double p1, double p2)
Definition: def.h:490
#define NULL_ID
Definition: ifcdef.h:76
GOType
Definition: vgeometrydef.h:56
Draw
Definition: vgeometrydef.h:55
@ Calculation