Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_Math2D.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
5 //------------------------------------------------------------------------------------------------
6 class SCR_Math2D
7 {
8  //------------------------------------------------------------------------------------------------
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  foreach (vector point3D : points3D)
17  {
18  points2D.Insert(point3D[0]);
19  points2D.Insert(point3D[2]);
20  }
21  }
22 
23  //------------------------------------------------------------------------------------------------
28  // unused
29  static void Get3DPolygon(notnull array<float> points2D, out notnull array<vector> points3D)
30  {
31  int count = points2D.Count();
32  if (count & 1)
33  return;
34 
35  points3D.Clear();
36 
37  for (int i; i < count; i += 2)
38  {
39  points3D.Insert({ points2D[i], 0, points2D[i + 1] });
40  }
41  }
42 
43  //------------------------------------------------------------------------------------------------
44 
46  static bool GetMinMaxPolygon(notnull array<float> polygon, out float minX, out float maxX, out float minY, out float maxY)
47  {
48  if (!IsPolygonValid(polygon))
49  return false;
50 
51  minX = polygon[0];
52  maxX = polygon[0];
53  minY = polygon[1];
54  maxY = polygon[1];
55  float x, y;
56 
57  for (int i = 2, count = polygon.Count(); i < count; i += 2)
58  {
59  x = polygon[i];
60  y = polygon[i + 1];
61 
62  if (x < minX)
63  minX = x;
64  else if (x > maxX)
65  maxX = x;
66 
67  if (y < minY)
68  minY = y;
69  else if (y > maxY)
70  maxY = y;
71  }
72 
73  return true;
74  }
75 
76  //------------------------------------------------------------------------------------------------
79  static float GetPolygonArea(notnull array<float> polygon)
80  {
81  if (!IsPolygonValid(polygon))
82  return -1;
83 
84  float result;
85 
86  int j;
87  for (int i = 0, count = polygon.Count(); i < count; i += 2) // step 2
88  {
89  j = (i + 2) % count;
90  result += 0.5 * (polygon[i] * polygon[j + 1] - polygon[j] * polygon[i + 1]);
91  }
92 
93  if (result < 0)
94  result = -result;
95 
96  return result;
97  }
98 
99  //------------------------------------------------------------------------------------------------
100  // TODO: better
101  // use SCR_Math.GetMathRandomGenerator().GenerateRandomPoint()?
107  // unused
108  static bool GetRandomPointInPolygon(notnull array<float> polygon, out float x, out float y)
109  {
110  float minX, minY, maxX, maxY;
111  if (!GetMinMaxPolygon(polygon, minX, maxX, minY, maxY))
112  return false;
113 
114  GetRandomPointInRectangle(minX, maxX, minY, maxY, x, y);
115  while (!Math2D.IsPointInPolygon(polygon, x, y)) // ugh
116  {
117  GetRandomPointInRectangle(minX, maxX, minY, maxY, x, y);
118  }
119 
120  return true;
121  }
122 
123  //------------------------------------------------------------------------------------------------
125  // only used by GetRandomPointInPolygon
126  static bool GetRandomPointInRectangle(float minX, float maxX, float minY, float maxY, out float x, out float y)
127  {
128  x = Math.RandomFloat(minX, maxX);
129  y = Math.RandomFloat(minY, maxY);
130  return true;
131  }
132 
133  //------------------------------------------------------------------------------------------------
137  static bool GetRandomPointInSector(float originX, float originY, float angleFrom, float angleTo, float radius, out float x, out float y)
138  {
139  float distance = radius * Math.Sqrt(Math.RandomFloat01()); // to have it uniformly distributed
140  float angle = Math.RandomFloat(angleFrom,angleTo);
141  x = originX + distance * Math.Cos(angle);
142  y = originY + distance * Math.Sin(angle);
143  return true;
144  }
145 
146  //------------------------------------------------------------------------------------------------
148  static bool IsPolygonValid(notnull array<float> polygon)
149  {
150  int count = polygon.Count();
151 
152  if (count < 6) // less than 3 points? not a polygon
153  return false;
154 
155  if (count & 1) // odd number = one missing/extra point
156  return false;
157 
158  return true;
159  }
160 /*
161  //------------------------------------------------------------------------------------------------
163  // unused
164  static float GetPointLineSegmentDistanceSqr(float pX, float pY, float x0, float y0, float x1, float y1)
165  {
166  return Math3D.PointLineSegmentDistanceSqr({ pX, 0, pY }, { x0, 0, y0 }, {x1, 0, y1 });
167  }
168 
169  //------------------------------------------------------------------------------------------------
171  static float GetPointLineSegmentDistance(float pX, float pY, float x0, float y0, float x1, float y1)
172  {
173  return Math3D.PointLineSegmentDistance({ pX, 0, pY }, { x0, 0, y0 }, { x1, 0, y1 });
174  // return Math.Sqrt(PointLineSegmentDistance(pX, pY, x0, y0, x1, y1));
175  }
176 
177  //------------------------------------------------------------------------------------------------
183  protected static bool CartesianToPolar(float x, float y, out float angle, out float radius)
184  {
185  angle = Math.Atan2(y, x);
186  radius = Math.Sqrt(x + y);
187  return true;
188  }
189 */
190  //------------------------------------------------------------------------------------------------
196  static bool PolarToCartesian(float angle, float radius, out float x, out float y)
197  {
198  x = Math.Cos(angle) * radius;
199  y = Math.Sin(angle) * radius;
200  return true;
201  }
202 /*
203  //------------------------------------------------------------------------------------------------
207  protected static float TrigoRadianToDegree(float value)
208  {
209  value = 90 - value * Math.RAD2DEG;
210 
211  if (value < 0 || value > 360)
212  value = Math.Repeat(value, 360);
213 
214  if (value < 0)
215  value += 360;
216 
217  if (float.AlmostEqual(value, 360))
218  value = 0;
219 
220  return value;
221  }
222 
223  //------------------------------------------------------------------------------------------------
227  protected static float DegreeToTrigoRadian(float value)
228  {
229  value = Math.PI_HALF - value * Math.DEG2RAD;
230 
231  if (value < 0 || value > Math.PI2)
232  value = Math.Repeat(value, Math.PI2);
233 
234  if (value < 0)
235  value += Math.PI2;
236 
237  if (float.AlmostEqual(value, Math.PI2))
238  value = 0;
239 
240  return value;
241  }
242 
243  //------------------------------------------------------------------------------------------------
250  protected static float GetDegreeAngleDifference(float angleA, float angleB)
251  {
252  if (angleA <= -180 || angleA > 180)
253  angleA = Math.Repeat(angleA, 360);
254 
255  if (angleB <= -180 || angleB > 180)
256  angleB = Math.Repeat(angleB, 360);
257 
258  angleA = angleB - angleA; // variable reuse
259 
260  if (angleA <= -180)
261  angleA += 360;
262  else if (angleA > 180)
263  angleA -= 360;
264 
265  return angleA;
266  }
267 
268  //------------------------------------------------------------------------------------------------
275  protected static float GetRadianAngleDifference(float angleA, float angleB)
276  {
277  if (angleA <= -Math.PI || angleA > Math.PI)
278  angleA = Math.Repeat(angleA, Math.PI2);
279 
280  if (angleB <= -Math.PI || angleB > Math.PI)
281  angleB = Math.Repeat(angleB, Math.PI2);
282 
283  angleA = angleB - angleA; // variable reuse
284 
285  if (angleA <= -Math.PI)
286  angleA += Math.PI2;
287  else if (angleA > Math.PI)
288  angleA -= Math.PI2;
289 
290  return angleA;
291  }
292 
293  //------------------------------------------------------------------------------------------------
295  protected static float GetRadianAngle(vector from, vector to)
296  {
297  to = to - from; // variable reuse
298  return Math.Atan2(to[2], to[0]);
299  }
300 
301  //------------------------------------------------------------------------------------------------
305  static bool GetLinesIntersection(float x0, float y0, float angleRad0, float x1, float y1, float angleRad1, out float x, out float y)
306  {
307  if (angleRad0 < 0 || angleRad0 > Math.PI2)
308  angleRad0 = Math.Repeat(angleRad0, Math.PI2);
309 
310  if (angleRad1 < 0 || angleRad1 > Math.PI2)
311  angleRad1 = Math.Repeat(angleRad1, Math.PI2);
312 
313  // below is from https://www.geeksforgeeks.org/program-for-point-of-intersection-of-two-lines/
314  float a1 = Math.Sin(angleRad0);
315  float b1 = -Math.Cos(angleRad0);
316  float c1 = a1 * x0 + b1 * y0;
317 
318  // Line CD represented as a2x + b2y = c2
319  float a2 = Math.Sin(angleRad1);
320  float b2 = -Math.Cos(angleRad1);
321  float c2 = a2 * x1 + b2 * y1;
322 
323  float determinant = a1 * b2 - a2 * b1;
324 
325  // lines are parallel
326  if (determinant == 0)
327  return false;
328 
329  x = (b2 * c1 - b1 * c2) / determinant;
330  y = (a1 * c2 - a2 * c1) / determinant;
331 
332  return true;
333  }
334 */
335  //------------------------------------------------------------------------------------------------
343  static vector GenerateRandomPoint(array<float> polygon, vector bbMin, vector bbMax)
344  {
345  return SCR_Math.GetMathRandomGenerator().GenerateRandomPoint(polygon, bbMin, bbMax);
346  }
347 
348  //------------------------------------------------------------------------------------------------
357  static vector GenerateRandomPointInRadius(float minRadius, float maxRadius, vector center, bool uniform = true)
358  {
359  return SCR_Math.GetMathRandomGenerator().GenerateRandomPointInRadius(minRadius, maxRadius, center, uniform);
360  }
361 }
SCR_Math
Definition: SCR_Math.c:1
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29