Mon, 16 May 2022 01:40:49 +0300
work on circle tool
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
1 | #include <glm/gtc/matrix_transform.hpp> |
55 | 2 | #include "geometry.h" |
123 | 3 | #include "main.h" |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
4 | #include "ring.h" |
55 | 5 | |
6 | /** | |
7 | * @brief Computes line-plane intersection | |
8 | * @param line | |
9 | * @param plane | |
10 | * @return point of intersection. Does not return a value if the line is in parallel to the plane. | |
11 | */ | |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
12 | std::optional<glm::vec3> geom::linePlaneIntersection( |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
13 | const geom::Line<3>& line, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
14 | const geom::Plane& plane, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
15 | const float epsilon) |
55 | 16 | { |
17 | const float denominator = glm::dot(line.direction, plane.normal); | |
58
b7841cd31fb7
use glm::project instead of figuring out the conversion manually...
Teemu Piippo <teemu@hecknology.net>
parents:
55
diff
changeset
|
18 | if (std::abs(denominator) < epsilon) |
55 | 19 | { |
20 | return {}; | |
21 | } | |
22 | else | |
23 | { | |
24 | const float d = glm::dot(plane.anchor - line.anchor, plane.normal) / denominator; | |
25 | return line.anchor + d * line.direction; | |
26 | } | |
27 | } | |
28 | ||
29 | /** | |
30 | * @brief Computes the plane of a triangle | |
31 | * @param triangle | |
32 | * @return plane | |
33 | */ | |
34 | geom::Plane geom::planeFromTriangle(const geom::Triangle& triangle) | |
35 | { | |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
36 | return geom::Plane{normalVector(triangle), triangle.points[0]}; |
55 | 37 | } |
38 | ||
39 | /** | |
40 | * @brief Computes the normal vector of a triangle | |
41 | * @param triangle | |
42 | * @return normal vector | |
43 | */ | |
44 | glm::vec3 geom::normalVector(const geom::Triangle& triangle) | |
45 | { | |
46 | return glm::normalize( | |
47 | glm::cross( | |
48 | triangle.points[1] - triangle.points[0], | |
49 | triangle.points[2] - triangle.points[0])); | |
50 | } | |
64
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
51 | |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
52 | /** |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
53 | * @brief Extracts the scaling component of the specified matrix into a vector and returns both the scaling |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
54 | * components as well as the unscaled matrix. |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
55 | * @param matrix Matrix to compute |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
56 | * @return scaling vector and unscaled matrix |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
57 | */ |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
58 | geom::ScalingExtract geom::extractScaling(const glm::mat4& matrix) |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
59 | { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
60 | geom::ScalingExtract result; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
61 | result.scaling = geom::scalingVector(matrix); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
62 | result.unscaled = glm::scale(matrix, 1.0f / result.scaling); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
63 | return result; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
64 | } |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
65 | |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
66 | /** |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
67 | * @brief Computes the scaling vector, which contains the scaling of the specified matrix |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
68 | * @param matrix |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
69 | * @return scaling vector |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
70 | */ |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
71 | glm::vec3 geom::scalingVector(const glm::mat4 matrix) |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
72 | { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
73 | auto component = [](const glm::mat4& matrix, const int i) -> float |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
74 | { |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
75 | return std::hypot(std::hypot(matrix[i][0], matrix[i][1]), matrix[i][2]); |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
76 | }; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
77 | return glm::vec3{component(matrix, 0), component(matrix, 1), component(matrix, 2)}; |
f99d52b1646b
grid snapping now also works with transformed grids
Teemu Piippo <teemu@hecknology.net>
parents:
58
diff
changeset
|
78 | } |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
79 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
80 | std::optional<glm::vec2> geom::lineLineIntersection(const Line<2>& line_1, const Line<2>& line_2) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
81 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
82 | const float denominator = (line_1.direction.x * line_2.direction.y) - (line_1.direction.y * line_2.direction.x); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
83 | constexpr float epsilon = 1e-6f; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
84 | if (std::abs(denominator) < epsilon) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
85 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
86 | return {}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
87 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
88 | else |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
89 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
90 | const glm::vec2 p1 = line_1.anchor + line_1.direction; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
91 | const glm::vec2& p2 = line_1.anchor; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
92 | const glm::vec2 p3 = line_2.anchor + line_2.direction; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
93 | const glm::vec2& p4 = line_2.anchor; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
94 | const float a = glm::determinant(glm::mat2{{p1.x, p2.x}, {p1.y, p2.y}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
95 | const float b = glm::determinant(glm::mat2{{p3.x, p4.x}, {p3.y, p4.y}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
96 | const float c_x = glm::determinant(glm::mat2{{p1.x, p2.x}, {1, 1}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
97 | const float c_y = glm::determinant(glm::mat2{{p1.y, p2.y}, {1, 1}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
98 | const float d_x = glm::determinant(glm::mat2{{p3.x, p4.x}, {1, 1}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
99 | const float d_y = glm::determinant(glm::mat2{{p3.y, p4.y}, {1, 1}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
100 | const float x = glm::determinant(glm::mat2{{a, b}, {c_x, d_x}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
101 | const float y = glm::determinant(glm::mat2{{a, b}, {c_y, d_y}}); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
102 | return glm::vec2{x / denominator, y / denominator}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
103 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
104 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
105 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
106 | std::optional<glm::vec2> geom::rayLineSegmentIntersection(const Ray<2>& ray, const LineSegment2D& line) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
107 | { |
115 | 108 | std::optional<glm::vec2> result = lineLineIntersection( |
109 | rayToLine(ray), | |
110 | lineFromPoints(line.points[0], line.points[1])); | |
71
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
111 | if (result.has_value()) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
112 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
113 | const float d1 = glm::dot(*result - ray.anchor, ray.direction); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
114 | if (d1 < 0) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
115 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
116 | result.reset(); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
117 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
118 | else |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
119 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
120 | const float d2 = glm::dot(*result - line.points[0], *result - line.points[1]); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
121 | if (d2 > 0) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
122 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
123 | result.reset(); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
124 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
125 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
126 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
127 | return result; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
128 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
129 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
130 | std::optional<geom::PointOnRectagle> geom::rayRectangleIntersection(const Ray<2>& ray, const QRectF& rectangle) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
131 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
132 | std::optional<glm::vec2> position; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
133 | std::optional<PointOnRectagle> result; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
134 | // Try top |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
135 | position = rayLineSegmentIntersection(ray, top(rectangle)); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
136 | if (position.has_value()) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
137 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
138 | result = {*position, RectangleSide::Top}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
139 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
140 | else |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
141 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
142 | // Try bottom |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
143 | position = rayLineSegmentIntersection(ray, bottom(rectangle)); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
144 | if (position.has_value()) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
145 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
146 | result = {*position, RectangleSide::Bottom}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
147 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
148 | else |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
149 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
150 | // Try left |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
151 | position = rayLineSegmentIntersection(ray, left(rectangle)); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
152 | if (position.has_value()) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
153 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
154 | result = {*position, RectangleSide::Left}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
155 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
156 | else |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
157 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
158 | // Try right |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
159 | position = rayLineSegmentIntersection(ray, right(rectangle)); |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
160 | if (position.has_value()) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
161 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
162 | result = {*position, RectangleSide::Right}; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
163 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
164 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
165 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
166 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
167 | return result; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
168 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
169 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
170 | geom::LineSegment2D geom::top(const QRectF& rectangle) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
171 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
172 | return { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
173 | glm::vec2{rectangle.left(), rectangle.top()}, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
174 | glm::vec2{rectangle.right(), rectangle.top()} |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
175 | }; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
176 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
177 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
178 | geom::LineSegment2D geom::bottom(const QRectF& rectangle) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
179 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
180 | return { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
181 | glm::vec2{rectangle.left(), rectangle.bottom()}, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
182 | glm::vec2{rectangle.right(), rectangle.bottom()} |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
183 | }; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
184 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
185 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
186 | geom::LineSegment2D geom::left(const QRectF& rectangle) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
187 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
188 | return { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
189 | glm::vec2{rectangle.left(), rectangle.top()}, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
190 | glm::vec2{rectangle.left(), rectangle.bottom()} |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
191 | }; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
192 | } |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
193 | |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
194 | geom::LineSegment2D geom::right(const QRectF& rectangle) |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
195 | { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
196 | return { |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
197 | glm::vec2{rectangle.right(), rectangle.top()}, |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
198 | glm::vec2{rectangle.right(), rectangle.bottom()} |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
199 | }; |
198d25fe4e21
show axis directions on the screen
Teemu Piippo <teemu@hecknology.net>
parents:
64
diff
changeset
|
200 | } |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
201 | |
123 | 202 | bool geom::isConvex(const std::vector<glm::vec3>& polygon) |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
203 | { |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
204 | const int n = polygon.size(); |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
205 | auto polygonRing = iter::ring(polygon, n); |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
206 | std::vector<glm::vec3> crosses; |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
207 | crosses.resize(n); |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
208 | for (int i = 0; i < n; i += 1) |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
209 | { |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
210 | crosses[i] = glm::cross(polygonRing[i - 1] - polygonRing[i], polygonRing[i + 1] - polygonRing[i]); |
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
211 | } |
123 | 212 | return not std::any_of( |
213 | crosses.begin() + 1, | |
214 | crosses.end(), | |
215 | [&crosses](const glm::vec3& vector) | |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
216 | { |
123 | 217 | return glm::dot(crosses[0], vector) < 1e-6; |
218 | }); | |
122
b54b350dff5d
Show concave polygons as red while drawing
Teemu Piippo <teemu@hecknology.net>
parents:
115
diff
changeset
|
219 | } |
168
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
220 | |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
221 | /** |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
222 | * @brief Determines the winding of a 2d polygon |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
223 | * @param polygon |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
224 | * @return winding |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
225 | */ |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
226 | Winding geom::winding(const QPolygonF &polygon) |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
227 | { |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
228 | // based on https://stackoverflow.com/a/1165943 |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
229 | double sum = 0.0; |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
230 | for (int i = 0; i < polygon.size(); i += 1) |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
231 | { |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
232 | const QPointF& p1 = polygon[i]; |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
233 | const QPointF& p2 = polygon[(i + 1) % polygon.size()]; |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
234 | sum += (p2.x() - p1.x()) * (p2.y() + p1.y()); |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
235 | } |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
236 | return (sum < 0) ? Winding::Anticlockwise : Winding::Clockwise; |
24590af32ad6
Draw tool now renders the winding of the new polygon
Teemu Piippo <teemu@hecknology.net>
parents:
123
diff
changeset
|
237 | } |
187 | 238 | |
239 | /** | |
240 | * @brief computes the point on a Bezier curve | |
241 | * @param curve | |
242 | * @param t scalar between 0 and 1, with t=0 being P0 and t=1 being P3 | |
243 | * @return point on curve | |
244 | */ | |
245 | glm::vec3 geom::pointOnCurve(const BezierCurve &curve, float t) | |
246 | { | |
247 | // clamp t as rounding errors might make it slightly out of bounds | |
248 | t = std::clamp(t, 0.0f, 1.0f); | |
249 | const float t_2 = t * t; | |
250 | const float t_3 = t * t * t; | |
251 | const float coeffs[3] = { | |
252 | -1*t_3 +3*t_2 -3*t +1, | |
253 | +3*t_3 -6*t_2 +3*t, | |
254 | -3*t_3 +3*t_2, | |
255 | }; | |
256 | return coeffs[0] * curve[0] + coeffs[1] * curve[1] + coeffs[2] * curve[2] + t_3 * curve[3]; | |
257 | } | |
258 | ||
259 | /** | |
260 | * @brief computes the derivative of a point on a Bezier curve | |
261 | * @param curve | |
262 | * @param t scalar between 0 and 1, with t=0 being P0 and t=1 being P3 | |
263 | * @return point on curve | |
264 | */ | |
265 | glm::vec3 geom::derivativeOnCurve(const BezierCurve &curve, float t) | |
266 | { | |
267 | // clamp t as rounding errors might make it slightly out of bounds | |
268 | t = std::clamp(t, 0.0f, 1.0f); | |
269 | const float t_2 = t * t; | |
270 | const float coeffs[4] = { | |
271 | -3*t_2 + 6*t -3, | |
272 | +9*t_2 -12*t +3, | |
273 | -9*t_2 + 6*t, | |
274 | +3*t_2 | |
275 | }; | |
276 | return coeffs[0] * curve[0] + coeffs[1] * curve[1] + coeffs[2] * curve[2] + coeffs[3] * curve[3]; | |
277 | } |