-
Notifications
You must be signed in to change notification settings - Fork 0
/
Math.cpp
181 lines (132 loc) · 4.45 KB
/
Math.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*-----------------------------------------------------------------------------
Math.cpp
2009 Shamus Young
-------------------------------------------------------------------------------
Various useful math functions.
-----------------------------------------------------------------------------*/
#include <math.h>
#include "macro.h"
#include "math.h"
/*-----------------------------------------------------------------------------
Keep an angle between 0 and 360
-----------------------------------------------------------------------------*/
float MathAngle (float angle)
{
if (angle < 0.0f)
angle = 360.0f - (float)fmod (fabs (angle), 360.0f);
else
angle = (float)fmod (angle, 360.0f);
return angle;
}
/*-----------------------------------------------------------------------------
Get an angle between two given points on a grid
-----------------------------------------------------------------------------*/
float MathAngle (float x1, float y1, float x2, float y2)
{
float x_delta;
float z_delta;
float angle;
z_delta = (y1 - y2);
x_delta = (x1 - x2);
if (x_delta == 0) {
if (z_delta > 0)
return 0.0f;
else
return 180.0f;
}
if (fabs (x_delta) < fabs (z_delta)) {
angle = 90 - (float)atan (z_delta / x_delta) * RADIANS_TO_DEGREES;
if (x_delta < 0)
angle -= 180.0f;
} else {
angle = (float)atan (x_delta / z_delta) * RADIANS_TO_DEGREES;
if (z_delta < 0.0f)
angle += 180.0f;
}
if (angle< 0.0f)
angle += 360.0f;
return angle;
}
/*-----------------------------------------------------------------------------
Get distance (squared) between 2 points on a plane
-----------------------------------------------------------------------------*/
float MathDistance2 (float x1, float y1, float x2, float y2)
{
float dx;
float dy;
dx = x1 - x2;
dy = y1 - y2;
return dx * dx + dy * dy;
}
/*-----------------------------------------------------------------------------
Get distance between 2 points on a plane. This is slightly slower than
MathDistance2 ()
-----------------------------------------------------------------------------*/
float MathDistance (float x1, float y1, float x2, float y2)
{
float dx;
float dy;
dx = x1 - x2;
dy = y1 - y2;
return (float)sqrt (dx * dx + dy * dy);
}
/*-----------------------------------------------------------------------------
difference between two angles
-----------------------------------------------------------------------------*/
float MathAngleDifference (float a1, float a2)
{
float result;
result = (float)fmod (a1 - a2, 360.0f);
if (result > 180.0)
return result - 360.0F;
if (result < -180.0)
return result + 360.0F;
return result;
}
/*-----------------------------------------------------------------------------
interpolate between two values
-----------------------------------------------------------------------------*/
float MathInterpolate (float n1, float n2, float delta)
{
return n1 * (1.0f - delta) + n2 * delta;
}
/*-----------------------------------------------------------------------------
return a scalar of 0.0 to 1.0, based an the given values position within a range
-----------------------------------------------------------------------------*/
float MathSmoothStep (float val, float a, float b)
{
if (b == a)
return 0.0f;
val -= a;
val /= (b - a);
return CLAMP (val, 0.0f, 1.0f);
}
/*-----------------------------------------------------------------------------
Average two values
-----------------------------------------------------------------------------*/
float MathAverage (float n1, float n2)
{
return (n1 + n2) / 2.0f;
}
/*-----------------------------------------------------------------------------
This will take linear input values from 0.0 to 1.0 and convert them to
values along a curve. This could also be acomplished with sin (), but this
way avoids converting to radians and back.
-----------------------------------------------------------------------------*/
float MathScalarCurve (float val)
{
float sign;
val = (val - 0.5f) * 2.0f;
if (val < 0.0f)
sign = -1.0f;
else
sign = 1.0f;
if (val < 0.0f)
val = -val;
val = 1.0f - val;
val *= val;
val = 1.0f - val;
val *= sign;
val = (val + 1.0f) / 2.0f;
return val;
}