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