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