src/geometry.h

changeset 201
5d201ee4a9c3
parent 200
ca23936b455b
child 206
654661eab7f3
equal deleted inserted replaced
200:ca23936b455b 201:5d201ee4a9c3
1 #pragma once 1 #pragma once
2 #include <QPolygonF> 2 #include <QPolygonF>
3 #include "basics.h" 3 #include "basics.h"
4 4
5 namespace geom 5 struct Plane
6 { 6 {
7 struct Plane 7 glm::vec3 normal;
8 glm::vec3 anchor;
9 };
10
11 template<int N, typename T = float, glm::qualifier Q = glm::defaultp>
12 struct Line
13 {
14 glm::vec<N, T, Q> direction;
15 glm::vec<N, T, Q> anchor;
16 };
17
18 template<int N, typename T = float, glm::qualifier Q = glm::defaultp>
19 struct Ray
20 {
21 glm::vec<N, T, Q> direction;
22 glm::vec<N, T, Q> anchor;
23 };
24
25 inline const glm::vec3 origin = {0, 0, 0};
26 inline const Plane XY = {{0, 0, 1}, origin};
27 inline const Plane XZ = {{0, 1, 0}, origin};
28 inline const Plane YZ = {{1, 0, 0}, origin};
29
30 struct LineSegment
31 {
32 glm::vec3 p1, p2;
33 };
34 struct Triangle
35 {
36 glm::vec3 p1, p2, p3;
37 };
38 struct Quadrilateral
39 {
40 glm::vec3 p1, p2, p3, p4;
41 };
42 struct ConditionalEdge
43 {
44 glm::vec3 p1, p2;
45 glm::vec3 c1, c2;
46 };
47 struct LineSegment2D
48 {
49 glm::vec2 p1, p2;
50 };
51
52 // get polygon type from amount of points
53 template<int N>
54 struct PolygonType {};
55 template<>
56 struct PolygonType<2> { using type = LineSegment; };
57 template<>
58 struct PolygonType<3> { using type = Triangle; };
59 template<>
60 struct PolygonType<4> { using type = Quadrilateral; };
61 template<int N>
62 using Polygon = typename PolygonType<N>::type;
63
64 /**
65 * @brief Computes a line from two points
66 * @param point_1
67 * @param point_2
68 * @return line
69 */
70 template<int N, typename T, glm::qualifier Q>
71 Line<N, T, Q> lineFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
72 {
73 return {point_2 - point_1, point_1};
74 }
75
76 template<int N, typename T, glm::qualifier Q>
77 Ray<N, T, Q> rayFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
78 {
79 return {point_2 - point_1, point_1};
80 }
81
82 template<int N, typename T, glm::qualifier Q>
83 Line<N, T, Q> rayToLine(const Ray<N, T, Q>& ray)
84 {
85 return {ray.direction, ray.anchor};
86 }
87
88 enum class RectangleSide
89 {
90 Top,
91 Left,
92 Bottom,
93 Right
94 };
95
96 struct PointOnRectagle
97 {
98 glm::vec2 position;
99 RectangleSide side;
100 };
101
102 std::optional<glm::vec2> lineLineIntersection(const Line<2>& line_1, const Line<2>& line_2);
103 std::optional<glm::vec2> rayLineSegmentIntersection(const Ray<2>& ray, const LineSegment2D& line);
104 std::optional<PointOnRectagle> rayRectangleIntersection(const Ray<2>& ray, const QRectF& rectangle);
105 Plane planeFromTriangle(const Triangle& triangle);
106 glm::vec3 normalVector(const Triangle& triangle);
107 std::optional<glm::vec3> linePlaneIntersection(
108 const Line<3>& line,
109 const Plane& plane, const float epsilon = 1e-6f);
110 glm::vec3 scalingVector(const glm::mat4 matrix);
111 LineSegment2D top(const QRectF& rectangle);
112 LineSegment2D bottom(const QRectF& rectangle);
113 LineSegment2D left(const QRectF& rectangle);
114 LineSegment2D right(const QRectF& rectangle);
115 bool isConvex(const std::vector<glm::vec3>& polygon);
116 Winding winding(const QPolygonF& polygon);
117 struct ScalingExtract
118 {
119 glm::vec3 scaling;
120 glm::mat4 unscaled;
121 };
122 ScalingExtract extractScaling(const glm::mat4& matrix);
123
124 struct NPolygon
125 {
126 std::vector<glm::vec3> points;
127 };
128
129 inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b)
130 {
131 return qFuzzyCompare(a.x, b.x)
132 and qFuzzyCompare(a.y, b.y)
133 and qFuzzyCompare(a.z, b.z);
134 }
135
136 struct CircleF
137 {
138 QPointF center;
139 qreal radius;
140 };
141
142 /**
143 * @brief Inscribes a circle
144 * @param circle
145 * @return a QRectF that inscribes the specified circle
146 */
147 inline constexpr QRectF inscribe(const CircleF& circle)
148 {
149 return {
150 circle.center.x() - circle.radius,
151 circle.center.y() - circle.radius,
152 circle.radius * 2,
153 circle.radius * 2
154 };
155 }
156
157 struct BezierCurve
158 {
159 glm::vec3 points[4];
160 const glm::vec3& operator[](int x) const
8 { 161 {
9 glm::vec3 normal; 162 Q_ASSERT(x >= 0 and x < 4);
10 glm::vec3 anchor; 163 return this->points[x];
11 }; 164 }
165 glm::vec3& operator[](int x)
166 {
167 Q_ASSERT(x >= 0 and x < 4);
168 return this->points[x];
169 }
170 };
12 171
13 template<int N, typename T = float, glm::qualifier Q = glm::defaultp> 172 glm::vec3 pointOnCurve(const BezierCurve& curve, float t);
14 struct Line 173 glm::vec3 derivativeOnCurve(const BezierCurve& curve, float t);
15 {
16 glm::vec<N, T, Q> direction;
17 glm::vec<N, T, Q> anchor;
18 };
19
20 template<int N, typename T = float, glm::qualifier Q = glm::defaultp>
21 struct Ray
22 {
23 glm::vec<N, T, Q> direction;
24 glm::vec<N, T, Q> anchor;
25 };
26
27 inline const glm::vec3 origin = {0, 0, 0};
28 inline const Plane XY = {{0, 0, 1}, origin};
29 inline const Plane XZ = {{0, 1, 0}, origin};
30 inline const Plane YZ = {{1, 0, 0}, origin};
31
32 struct LineSegment
33 {
34 glm::vec3 p1, p2;
35 };
36 struct Triangle
37 {
38 glm::vec3 p1, p2, p3;
39 };
40 struct Quadrilateral
41 {
42 glm::vec3 p1, p2, p3, p4;
43 };
44 struct ConditionalEdge
45 {
46 glm::vec3 p1, p2;
47 glm::vec3 c1, c2;
48 };
49 struct LineSegment2D
50 {
51 glm::vec2 p1, p2;
52 };
53
54 // get polygon type from amount of points
55 template<int N>
56 struct PolygonType {};
57 template<>
58 struct PolygonType<2> { using type = LineSegment; };
59 template<>
60 struct PolygonType<3> { using type = Triangle; };
61 template<>
62 struct PolygonType<4> { using type = Quadrilateral; };
63 template<int N>
64 using Polygon = typename PolygonType<N>::type;
65
66 /**
67 * @brief Computes a line from two points
68 * @param point_1
69 * @param point_2
70 * @return line
71 */
72 template<int N, typename T, glm::qualifier Q>
73 Line<N, T, Q> lineFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
74 {
75 return {point_2 - point_1, point_1};
76 }
77
78 template<int N, typename T, glm::qualifier Q>
79 Ray<N, T, Q> rayFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2)
80 {
81 return {point_2 - point_1, point_1};
82 }
83
84 template<int N, typename T, glm::qualifier Q>
85 Line<N, T, Q> rayToLine(const Ray<N, T, Q>& ray)
86 {
87 return {ray.direction, ray.anchor};
88 }
89
90 enum class RectangleSide
91 {
92 Top,
93 Left,
94 Bottom,
95 Right
96 };
97
98 struct PointOnRectagle
99 {
100 glm::vec2 position;
101 RectangleSide side;
102 };
103
104 std::optional<glm::vec2> lineLineIntersection(const Line<2>& line_1, const Line<2>& line_2);
105 std::optional<glm::vec2> rayLineSegmentIntersection(const Ray<2>& ray, const LineSegment2D& line);
106 std::optional<PointOnRectagle> rayRectangleIntersection(const Ray<2>& ray, const QRectF& rectangle);
107 Plane planeFromTriangle(const Triangle& triangle);
108 glm::vec3 normalVector(const Triangle& triangle);
109 std::optional<glm::vec3> linePlaneIntersection(
110 const Line<3>& line,
111 const Plane& plane, const float epsilon = 1e-6f);
112 glm::vec3 scalingVector(const glm::mat4 matrix);
113 LineSegment2D top(const QRectF& rectangle);
114 LineSegment2D bottom(const QRectF& rectangle);
115 LineSegment2D left(const QRectF& rectangle);
116 LineSegment2D right(const QRectF& rectangle);
117 bool isConvex(const std::vector<glm::vec3>& polygon);
118 Winding winding(const QPolygonF& polygon);
119 struct ScalingExtract
120 {
121 glm::vec3 scaling;
122 glm::mat4 unscaled;
123 };
124 ScalingExtract extractScaling(const glm::mat4& matrix);
125
126 struct NPolygon
127 {
128 std::vector<glm::vec3> points;
129 };
130
131 inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b)
132 {
133 return qFuzzyCompare(a.x, b.x)
134 and qFuzzyCompare(a.y, b.y)
135 and qFuzzyCompare(a.z, b.z);
136 }
137
138 struct CircleF
139 {
140 QPointF center;
141 qreal radius;
142 };
143
144 /**
145 * @brief Inscribes a circle
146 * @param circle
147 * @return a QRectF that inscribes the specified circle
148 */
149 inline constexpr QRectF inscribe(const CircleF& circle)
150 {
151 return {
152 circle.center.x() - circle.radius,
153 circle.center.y() - circle.radius,
154 circle.radius * 2,
155 circle.radius * 2
156 };
157 }
158
159 struct BezierCurve
160 {
161 glm::vec3 points[4];
162 const glm::vec3& operator[](int x) const
163 {
164 Q_ASSERT(x >= 0 and x < 4);
165 return this->points[x];
166 }
167 glm::vec3& operator[](int x)
168 {
169 Q_ASSERT(x >= 0 and x < 4);
170 return this->points[x];
171 }
172 };
173
174 glm::vec3 pointOnCurve(const BezierCurve& curve, float t);
175 glm::vec3 derivativeOnCurve(const BezierCurve& curve, float t);
176 }
177 using namespace geom;

mercurial