Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
mathutil.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19//
20// Filename: mathutil.cpp
21// Project: wwutil
22// Author: Tom Spencer-Smith
23// Date: June 1998
24// Description:
25//
26//-----------------------------------------------------------------------------
27#include "mathutil.h" // I WANNA BE FIRST!
28
29#include <math.h>
30#include <stdlib.h>
31#include "wwmath.h"
32#include "miscutil.h"
33#include "wwdebug.h"
34
35const double cMathUtil::PI_1 = 3.1415927;
36const double cMathUtil::PI_2 = 1.5707963;
37
38//-----------------------------------------------------------------------------
39//
40// Returns a unit vector
41//
42void cMathUtil::Angle_To_Vector(double angle, double & dx, double & dy)
43{
44 WWASSERT(angle > -WWMATH_EPSILON && angle < 360.0 + WWMATH_EPSILON);
45
46 double angleRadians;
47
48 if (angle >= 0 && angle < 90) {
49 angleRadians = angle * PI_1 / 180.0;
50 dx = WWMath::Sin(angleRadians);
51 dy = WWMath::Cos(angleRadians);
52 } else if (angle >= 90 && angle < 180) {
53 angleRadians = (angle - 90) * PI_1 / 180.0;
54 dx = WWMath::Cos(angleRadians);
55 dy = -WWMath::Sin(angleRadians);
56 } else if (angle >= 180 && angle < 270) {
57 angleRadians = (angle - 180) * PI_1 / 180.0;
58 dx = -WWMath::Sin(angleRadians);
59 dy = -WWMath::Cos(angleRadians);
60 } else {
61 angleRadians = (angle - 270) * PI_1 / 180.0;
62 dx = -WWMath::Cos(angleRadians);
63 dy = WWMath::Sin(angleRadians);
64 }
65
66 double len;
67 len = ::sqrt(dx * dx + dy * dy);
68 WWASSERT(::fabs(len - 1) < 0.0005);
69
70 //
71 // Correction for Irish nature of windows y coords
72 //
73 dy *= -1;
74}
75
76//-----------------------------------------------------------------------------
77void cMathUtil::Vector_To_Angle(double dx, double dy, double & angle)
78{
79 double theta;
80
81 if (dx == 0 && dy == 0) {
82 theta = 0;
83 }
84
85 if (dx == 0) {
86 if (dy <= 0) {
87 theta = 0;
88 } else {
89 theta = PI_1;
90 }
91 } else {
92 theta = WWMath::Atan(-dy / dx);
93 if (dx < 0) {
94 theta += PI_1;
95 }
96 theta += 3 * PI_2;
97 if (theta >= 2 * PI_1) {
98 theta -= 2 * PI_1;
99 }
100 theta = 2 * PI_1 - theta;
101 if (theta == 2 * PI_1) {
102 theta = 0;
103 }
104 }
105
106 angle = theta * 180.0 / PI_1;
107}
108
109//-----------------------------------------------------------------------------
110double cMathUtil::Simple_Distance(double x1, double y1, double x2, double y2)
111{
112 double dx = x2 - x1;
113 double dy = y2 - y1;
114 return(::sqrt(dx * dx + dy * dy));
115}
116
117//-----------------------------------------------------------------------------
118int cMathUtil::Round(double arg)
119{
120 //return (int)(arg + 0.5);
121
122 if (arg > MISCUTIL_EPSILON) {
123 return (int) (arg + 0.5f);
124 } else if (arg < -MISCUTIL_EPSILON) {
125 return (int) (arg - 0.5f);
126 } else {
127 return 0;
128 }
129}
130
131//-----------------------------------------------------------------------------
132void cMathUtil::Rotate_Vector(double & vx, double & vy, double angle)
133{
134 double angle_radians = angle * PI_1 / 180.0;
135
136 double vx1 = vx;
137 double vy1 = vy;
138
139 vx = vx1 * ::WWMath::Cos(angle_radians) - vy1 * ::WWMath::Sin(angle_radians);
140 vy = vx1 * ::WWMath::Sin(angle_radians) + vy1 * ::WWMath::Cos(angle_radians);
141}
142
143
144
145//-----------------------------------------------------------------------------
146double cMathUtil::Get_Uniform_Pdf_Double(double lower, double upper)
147{
148 WWASSERT(upper - lower > -MISCUTIL_EPSILON);
149
150 double x = lower + ::rand() / (double) RAND_MAX * (upper - lower);
151
152 WWASSERT(x - lower > -MISCUTIL_EPSILON && upper - x > -MISCUTIL_EPSILON);
153
154 return x;
155}
156
157//-----------------------------------------------------------------------------
162
163//-----------------------------------------------------------------------------
164int cMathUtil::Get_Uniform_Pdf_Int(int lower, int upper)
165{
166 WWASSERT(lower <= upper);
167 int x = lower + ::rand() % (upper - lower + 1);
168
169 WWASSERT(x >= lower && upper >= x);
170
171 return x;
172}
173
174//-----------------------------------------------------------------------------
175double cMathUtil::Get_Hat_Pdf_Double(double lower, double upper)
176{
177 WWASSERT(upper - lower > -MISCUTIL_EPSILON);
178
179 double x;
180
181 if (::fabs(upper - lower) < MISCUTIL_EPSILON) {
182 x = lower;
183 } else {
184
185 double dx = (upper - lower) / 2.0f;
186 double dy = 1 / dx;
187 double m = dy / dx;
188 double c = -m * lower;
189
190 x = Get_Uniform_Pdf_Double(lower, lower + dx);
191 double y = Get_Uniform_Pdf_Double(0, dy);
192
193 if (y > m * x + c) {
194 x += dx;
195 }
196 }
197
198 WWASSERT(x - lower > -MISCUTIL_EPSILON && upper - x > -MISCUTIL_EPSILON);
199
200 return x;
201}
202
203//-----------------------------------------------------------------------------
208
209//-----------------------------------------------------------------------------
210int cMathUtil::Get_Hat_Pdf_Int(int lower, int upper)
211{
212 return Round(Get_Hat_Pdf_Double(lower, upper));
213}
214
215
216
217
218
219
220
221
222
223
224
#define WWASSERT
#define WWMATH_EPSILON
Definition wwmath.h:54
static float Atan(float x)
Definition wwmath.h:149
static float Sin(float val)
Definition wwmath.h:378
static float Cos(float val)
Definition wwmath.h:356
static void Angle_To_Vector(double angle, double &dx, double &dy)
Definition mathutil.cpp:42
static double Get_Normalized_Uniform_Pdf_Double()
Definition mathutil.cpp:158
static void Rotate_Vector(double &vx, double &vy, double angle)
Definition mathutil.cpp:132
static double Simple_Distance(double x1, double y1, double x2, double y2)
Definition mathutil.cpp:110
static double Get_Normalized_Hat_Pdf_Double()
Definition mathutil.cpp:204
static int Get_Uniform_Pdf_Int(int lower, int upper)
Definition mathutil.cpp:164
static const double PI_1
Definition mathutil.h:54
static int Round(double arg)
Definition mathutil.cpp:118
static int Get_Hat_Pdf_Int(int lower, int upper)
Definition mathutil.cpp:210
static double Get_Hat_Pdf_Double(double lower, double upper)
Definition mathutil.cpp:175
static void Vector_To_Angle(double dx, double dy, double &angle)
Definition mathutil.cpp:77
static double Get_Uniform_Pdf_Double(double lower, double upper)
Definition mathutil.cpp:146
static const double PI_2
Definition mathutil.h:55
const float MISCUTIL_EPSILON
Definition miscutil.h:41