Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_Math2D.c
Go to the documentation of this file.
1
5{
6 //------------------------------------------------------------------------------------------------
10 static void Get2DPolygon(notnull array<vector> points3D, out notnull array<float> points2D)
11 {
12 points2D.Clear();
13 if (points3D.IsEmpty())
14 return;
15
16 points2D.Reserve(points3D.Count() * 2);
17
18 foreach (vector point3D : points3D)
19 {
20 points2D.Insert(point3D[0]);
21 points2D.Insert(point3D[2]);
22 }
23 }
24
25 //------------------------------------------------------------------------------------------------
30 // unused
31 static void Get3DPolygon(notnull array<float> points2D, out notnull array<vector> points3D)
32 {
33 int count = points2D.Count();
34 if (count & 1)
35 return;
36
37 points3D.Clear();
38
39 for (int i; i < count; i += 2)
40 {
41 points3D.Insert({ points2D[i], 0, points2D[i + 1] });
42 }
43 }
44
45 //------------------------------------------------------------------------------------------------
52 static bool GetMinMaxPolygon(notnull array<float> polygon, out float minX, out float maxX, out float minY, out float maxY)
53 {
54 if (!IsPolygonValid(polygon))
55 return false;
56
57 minX = polygon[0];
58 maxX = polygon[0];
59 minY = polygon[1];
60 maxY = polygon[1];
61 float x, y;
62
63 for (int i = 2, count = polygon.Count(); i < count; i += 2)
64 {
65 x = polygon[i];
66 y = polygon[i + 1];
67
68 if (x < minX)
69 minX = x;
70 else if (x > maxX)
71 maxX = x;
72
73 if (y < minY)
74 minY = y;
75 else if (y > maxY)
76 maxY = y;
77 }
78
79 return true;
80 }
81
82 //------------------------------------------------------------------------------------------------
86 static float GetPolygonArea(notnull array<float> polygon)
87 {
88 if (!IsPolygonValid(polygon))
89 return -1;
90
91 float result;
92
93 int j;
94 for (int i = 0, count = polygon.Count(); i < count; i += 2) // step 2
95 {
96 j = (i + 2) % count;
97 result += 0.5 * (polygon[i] * polygon[j + 1] - polygon[j] * polygon[i + 1]);
98 }
99
100 if (result < 0)
101 result = -result;
102
103 return result;
104 }
105
106 //------------------------------------------------------------------------------------------------
107 // TODO: better
108 // use SCR_Math.GetMathRandomGenerator().GenerateRandomPoint()?
114 // unused
115 static bool GetRandomPointInPolygon(notnull array<float> polygon, out float x, out float y)
116 {
117 float minX, minY, maxX, maxY;
118 if (!GetMinMaxPolygon(polygon, minX, maxX, minY, maxY))
119 return false;
120
121 GetRandomPointInRectangle(minX, maxX, minY, maxY, x, y);
122 while (!Math2D.IsPointInPolygon(polygon, x, y)) // ugh
123 {
124 GetRandomPointInRectangle(minX, maxX, minY, maxY, x, y);
125 }
126
127 return true;
128 }
129
130 //------------------------------------------------------------------------------------------------
139 // only used by GetRandomPointInPolygon
140 static bool GetRandomPointInRectangle(float minX, float maxX, float minY, float maxY, out float x, out float y)
141 {
142 x = Math.RandomFloat(minX, maxX);
143 y = Math.RandomFloat(minY, maxY);
144 return true;
145 }
146
147 //------------------------------------------------------------------------------------------------
157 static bool GetRandomPointInSector(float originX, float originY, float angleFrom, float angleTo, float radius, out float x, out float y)
158 {
159 float distance = radius * Math.Sqrt(Math.RandomFloat01()); // to have it uniformly distributed
160 float angle = Math.RandomFloat(angleFrom, angleTo);
161 x = originX + distance * Math.Cos(angle);
162 y = originY + distance * Math.Sin(angle);
163 return true;
164 }
165
166 //------------------------------------------------------------------------------------------------
170 static bool IsPolygonValid(notnull array<float> polygon)
171 {
172 int count = polygon.Count();
173
174 if (count < 6) // less than 3 points? not a polygon
175 return false;
176
177 if (count & 1) // odd number = one missing/extra point
178 return false;
179
180 return true;
181 }
182
183// //------------------------------------------------------------------------------------------------
184// //! Calculates squared distance of `point` to a line segment given by points `v0` and `v1`.
185// // unused
186// static float GetPointLineSegmentDistanceSqr(float pX, float pY, float x0, float y0, float x1, float y1)
187// {
188// return Math3D.PointLineSegmentDistanceSqr({ pX, 0, pY }, { x0, 0, y0 }, {x1, 0, y1 });
189// }
190
191// //------------------------------------------------------------------------------------------------
192// //! Calculates distance of `point` to a line segment given by points `v0` and `v1`.
193// static float GetPointLineSegmentDistance(float pX, float pY, float x0, float y0, float x1, float y1)
194// {
195// return Math3D.PointLineSegmentDistance({ pX, 0, pY }, { x0, 0, y0 }, { x1, 0, y1 });
196// // return Math.Sqrt(PointLineSegmentDistance(pX, pY, x0, y0, x1, y1));
197// }
198
199 //------------------------------------------------------------------------------------------------
206 protected static bool CartesianToPolar(float x, float y, out float angle, out float radius)
207 {
208 angle = Math.Atan2(y, x);
209 radius = Math.Sqrt(x + y);
210 return true;
211 }
212
213 //------------------------------------------------------------------------------------------------
220 static bool PolarToCartesian(float angle, float radius, out float x, out float y)
221 {
222 x = Math.Cos(angle) * radius;
223 y = Math.Sin(angle) * radius;
224 return true;
225 }
226
227// //------------------------------------------------------------------------------------------------
228// //! Get a clockwise degree angle value from counter-clockwise radians
229// //! \param[in] value angle in counter-clockwise radians
230// //! \return [0..360[ clockwise value
231// protected static float TrigoRadianToDegree(float value)
232// {
233// value = 90 - value * Math.RAD2DEG;
234//
235// if (value < 0 || value > 360)
236// value = Math.Repeat(value, 360);
237//
238// if (value < 0)
239// value += 360;
240//
241// if (float.AlmostEqual(value, 360))
242// value = 0;
243//
244// return value;
245// }
246
247 //------------------------------------------------------------------------------------------------
251 static float DegreeToTrigoRadian(float value)
252 {
253 value = Math.PI_HALF - value * Math.DEG2RAD;
254
255 if (value < 0 || value > Math.PI2)
256 value = Math.Repeat(value, Math.PI2);
257
258 if (value < 0)
259 value += Math.PI2;
260
261 if (float.AlmostEqual(value, Math.PI2))
262 value = 0;
263
264 return value;
265 }
266
267// //------------------------------------------------------------------------------------------------
268// //! Get the difference between two degree angles
269// //! \code
270// //! GetDegreeAngleDifference(0, 45) // returns 45
271// //! GetDegreeAngleDifference(0, 315) // returns -45
272// //! \code
273// //! \param[in] angleA
274// //! \param[in] angleB
275// //! \return angle difference in range ]-180..+180]
276// protected static float GetDegreeAngleDifference(float angleA, float angleB)
277// {
278// if (angleA <= -180 || angleA > 180)
279// angleA = Math.Repeat(angleA, 360);
280//
281// if (angleB <= -180 || angleB > 180)
282// angleB = Math.Repeat(angleB, 360);
283//
284// angleA = angleB - angleA; // variable reuse
285//
286// if (angleA <= -180)
287// angleA += 360;
288// else if (angleA > 180)
289// angleA -= 360;
290//
291// return angleA;
292// }
293//
294// //------------------------------------------------------------------------------------------------
295// //! Get the difference between two radian angles
296// //! \code
297// //! GetRadianAngleDifference(0, Math.PI) // returns Math.PI
298// //! GetRadianAngleDifference(0, Math.PI * 1.5) // returns -Math.PI_HALF
299// //! \code
300// //! \param[in] angleA
301// //! \param[in] angleB
302// //! \return angle difference in range ]-Math.PI..+Math.PI]
303// protected static float GetRadianAngleDifference(float angleA, float angleB)
304// {
305// if (angleA <= -Math.PI || angleA > Math.PI)
306// angleA = Math.Repeat(angleA, Math.PI2);
307//
308// if (angleB <= -Math.PI || angleB > Math.PI)
309// angleB = Math.Repeat(angleB, Math.PI2);
310//
311// angleA = angleB - angleA; // variable reuse
312//
313// if (angleA <= -Math.PI)
314// angleA += Math.PI2;
315// else if (angleA > Math.PI)
316// angleA -= Math.PI2;
317//
318// return angleA;
319// }
320//
321// //------------------------------------------------------------------------------------------------
322// //! in range [0..Math.PI2[
323// //! \param[in] from
324// //! \param[in] to
325// //! \return radian angle
326// protected static float GetRadianAngle(vector from, vector to)
327// {
328// to = to - from; // variable reuse
329// return Math.Atan2(to[2], to[0]);
330// }
331
332 //------------------------------------------------------------------------------------------------
342 static bool GetLinesIntersectionXZ(float x0, float y0, float angleRad0, float x1, float y1, float angleRad1, out float x, out float y)
343 {
344 if (angleRad0 < 0 || angleRad0 > Math.PI2)
345 angleRad0 = Math.Repeat(angleRad0, Math.PI2);
346
347 if (angleRad1 < 0 || angleRad1 > Math.PI2)
348 angleRad1 = Math.Repeat(angleRad1, Math.PI2);
349
350 // below is from https://www.geeksforgeeks.org/program-for-point-of-intersection-of-two-lines/
351 float a1 = Math.Sin(angleRad0);
352 float b1 = -Math.Cos(angleRad0);
353 float c1 = a1 * x0 + b1 * y0;
354
355 // Line CD represented as a2x + b2y = c2
356 float a2 = Math.Sin(angleRad1);
357 float b2 = -Math.Cos(angleRad1);
358 float c2 = a2 * x1 + b2 * y1;
359
360 float determinant = a1 * b2 - a2 * b1;
361
362 // lines are parallel
363 if (float.AlmostEqual(determinant, 0))
364 return false;
365
366 x = (b2 * c1 - b1 * c2) / determinant;
367 y = (a1 * c2 - a2 * c1) / determinant;
368
369 return true;
370 }
371
372 //------------------------------------------------------------------------------------------------
378 // unused
379 static vector GenerateRandomPoint(array<float> polygon, vector bbMin, vector bbMax)
380 {
381 return SCR_Math.GetMathRandomGenerator().GenerateRandomPoint(polygon, bbMin, bbMax);
382 }
383
384 //------------------------------------------------------------------------------------------------
391 // unused
392 static vector GenerateRandomPointInRadius(float minRadius, float maxRadius, vector center, bool uniform = true)
393 {
394 return SCR_Math.GetMathRandomGenerator().GenerateRandomPointInRadius(minRadius, maxRadius, center, uniform);
395 }
396}
float distance
Definition Math.c:13
static bool GetLinesIntersectionXZ(float x0, float y0, float angleRad0, float x1, float y1, float angleRad1, out float x, out float y)
Definition SCR_Math2D.c:342
static float DegreeToTrigoRadian(float value)
Definition SCR_Math2D.c:251
static bool CartesianToPolar(float x, float y, out float angle, out float radius)
Definition SCR_Math2D.c:206
static vector GenerateRandomPointInRadius(float minRadius, float maxRadius, vector center, bool uniform=true)
Definition SCR_Math2D.c:392
static bool PolarToCartesian(float angle, float radius, out float x, out float y)
Definition SCR_Math2D.c:220
static vector GenerateRandomPoint(array< float > polygon, vector bbMin, vector bbMax)
Definition SCR_Math2D.c:379
static RandomGenerator GetMathRandomGenerator()
Definition SCR_Math.c:270