src/algorithms/geometry.cpp

Sat, 24 Mar 2018 12:51:24 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 24 Mar 2018 12:51:24 +0200
changeset 1325
f9abfc7ba676
parent 1319
39d7a9642eea
child 1326
69a90bd2dba2
permissions
-rw-r--r--

Use 4 points of precision for circle point coordinates

1319
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 #include "geometry.h"
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
2
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
3 /*
1325
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
4 * LDraw uses 4 points of precision for sin and cos values. Primitives must be generated
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
5 * accordingly.
1319
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6 */
1325
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
7 double ldrawsin(double angle)
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
8 {
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
9 return roundToDecimals(sin(angle), 4);
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
10 }
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
11
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
12 double ldrawcos(double angle)
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
13 {
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
14 return roundToDecimals(cos(angle), 4);
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
15 }
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
16
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
17 /*
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
18 * Returns a point on a circumference. LDraw precision is used.
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
19 */
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
20 QPointF pointOnLDrawCircumference(int segment, int divisions)
1319
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 double angle = (segment * 2 * pi) / divisions;
1325
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
23 return {ldrawcos(angle), ldrawsin(angle)};
1319
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
25
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 /*
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27 * makeCircle
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29 * Creates a possibly partial circle rim.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30 * Divisions is how many segments the circle makes if up if it's full.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 * Segments is now many segments are added.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
32 * Radius is the radius of the circle.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
33 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
34 * If divisions == segments, this yields a full circle rim.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35 * The rendered circle is returned as a vector of lines.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 */
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 QVector<QLineF> makeCircle(int segments, int divisions, double radius)
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 QVector<QLineF> lines;
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41 for (int i = 0; i < segments; i += 1)
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42 {
1325
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
43 QPointF p0 = radius * ::pointOnLDrawCircumference(i, divisions);
f9abfc7ba676 Use 4 points of precision for circle point coordinates
Teemu Piippo <teemu@hecknology.net>
parents: 1319
diff changeset
44 QPointF p1 = radius * ::pointOnLDrawCircumference(i + 1, divisions);
1319
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 lines.append({p0, p1});
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 return lines;
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 /*
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 * Computes the shortest distance from a point to a rectangle.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 * The code originates from the Unity3D wiki, and was translated from C# to Qt by me (Teemu Piippo):
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 * Original code:
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 * http://wiki.unity3d.com/index.php/Distance_from_a_point_to_a_rectangle
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 * Copyright 2013 Philip Peterson.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 * Permission is hereby granted, free of charge, to any person obtaining a copy
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 * of this software and associated documentation files (the "Software"), to
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 * deal in the Software without restriction, including without limitation the
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 * sell copies of the Software, and to permit persons to whom the Software is
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 * furnished to do so, subject to the following conditions:
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 * The above copyright notice and this permission notice shall be included in
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 * all copies or substantial portions of the Software.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 *
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 * IN THE SOFTWARE.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 */
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79 qreal distanceFromPointToRectangle(const QPointF& point, const QRectF& rectangle)
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 // Calculate a distance between a point and a rectangle.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 // The area around/in the rectangle is defined in terms of
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 // several regions:
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 //
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 // O--x
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 // |
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 // y
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 //
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 //
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 // I | II | III
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 // ======+==========+====== --yMin
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 // VIII | IX (in) | IV
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 // ======+==========+====== --yMax
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 // VII | VI | V
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 //
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 //
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 // Note that the +y direction is down because of Unity's GUI coordinates.
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
98 // - I don't care which way is +y in this function because I want a distance --TP
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
100 if (point.x() < rectangle.left())
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 // Region I, VIII, or VII
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
103 if (point.y() < rectangle.top()) // I
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 return QLineF {point, rectangle.topLeft()}.length();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 else if (point.y() > rectangle.bottom()) // VII
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 return QLineF {point, rectangle.bottomLeft()}.length();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 else // VIII
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
108 return rectangle.left() - point.x();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 else if (point.x() > rectangle.right())
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 // Region III, IV, or V
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 if (point.y() < rectangle.top()) // III
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 return QLineF {point, rectangle.topRight()}.length();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 else if (point.y() > rectangle.bottom()) // V
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 return QLineF {point, rectangle.bottomRight()}.length();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 else // IV
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 return point.x() - rectangle.right();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
120 else
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 {
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
122 // Region II, IX, or VI
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123 if (point.y() < rectangle.top()) // II
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 return rectangle.top() - point.y();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 else if (point.y() > rectangle.bottom()) // VI
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 return point.y() - rectangle.bottom();
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 else // IX
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
128 return 0;
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
129 }
39d7a9642eea reorganized headers
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 }

mercurial