-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbflib_planar.c
173 lines (160 loc) · 5.2 KB
/
bflib_planar.c
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
/******************************************************************************/
// Bullfrog Engine Emulation Library - for use to remake classic games like
// Syndicate Wars, Magic Carpet or Dungeon Keeper.
/******************************************************************************/
/** @file bflib_planar.c
* Basic planar integer geometry.
* @par Purpose:
* Simple geometry transformations unification.
* @par Comment:
* None.
* @author Tomasz Lis
* @date 24 Jan 2009 - 08 Mar 2009
* @par Copying and copyrights:
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
/******************************************************************************/
#include "bflib_planar.h"
#include "bflib_basics.h"
#include "globals.h"
#include "bflib_math.h"
#ifdef __cplusplus
extern "C" {
#endif
/******************************************************************************/
void LbSetRect(struct TbRect *rect, long xLeft, long yTop, long xRight, long yBottom)
{
if (rect == NULL)
return;
rect->left = xLeft;
rect->top = yTop;
rect->right = xRight;
rect->bottom = yBottom;
}
/**
* Returns symmetrical difference between angles, ranged -LbFPMath_PI to LbFPMath_PI.
* @param angle_a
* @param angle_b
*/
long get_angle_symmetric_difference(long angle_a, long angle_b)
{
long diff;
diff = (angle_a & LbFPMath_AngleMask) - (angle_b & LbFPMath_AngleMask);
if (diff > LbFPMath_PI)
diff = (2*LbFPMath_PI - diff);
else
if (diff < -LbFPMath_PI)
diff = (2*LbFPMath_PI + diff);
return diff;
}
/**
* Returns unsigned difference between angles, ranged 0 to LbFPMath_PI.
* Information about sign of the angle is not provided.
* @param angle_a
* @param angle_b
*/
long get_angle_difference(long angle_a, long angle_b)
{
long diff;
diff = abs((angle_a & LbFPMath_AngleMask) - (angle_b & LbFPMath_AngleMask));
if (diff > LbFPMath_PI)
diff = (2*LbFPMath_PI - diff);
return diff;
}
long get_angle_sign(long angle_a, long angle_b)
{
long diff;
diff = (angle_b & LbFPMath_AngleMask) - (angle_a & LbFPMath_AngleMask);
if (diff == 0)
return 0;
if (abs(diff) > LbFPMath_PI)
{
if (diff >= 0)
diff -= 2*LbFPMath_PI;
else
diff += 2*LbFPMath_PI;
}
if (diff == 0)
return 0;
return diff / abs(diff);
}
/**
* Gives X coordinate of a planar position shift by given distance into given direction.
* @param distance Specifies the distance to move.
* @param angle Specifies the movement direction.
*/
long distance_with_angle_to_coord_x(long distance, long angle)
{
long long val = (long long)distance * LbSinL(angle);
return val >> 16;
}
/**
* Gives Y coordinate of a planar position shift by given distance into given direction.
* @param distance Specifies the distance to move.
* @param angle Specifies the movement direction.
*/
long distance_with_angle_to_coord_y(long distance, long angle)
{
long long val = (long long)distance * LbCosL(angle);
return (-(val >> 8)) >> 8;
}
long get_distance_xy(long x1, long y1, long x2, long y2)
{
long dx, dy;
dx = abs(x1 - x2);
dy = abs(y1 - y2);
return LbDiagonalLength(dx, dy);
}
/**
* Gives X coordinate of a 3D position shift by given distance into given direction.
* @param distance Specifies the distance to move.
* @param angle_a Specifies the movement rotation a.
* @param angle_b Specifies the movement rotation b.
*/
long distance3d_with_angles_to_coord_x(long distance, long angle_a, long angle_b)
{
long long val = (LbSinL(angle_a)>> 8)
* (distance * LbCosL(angle_b) >> 8);
return val >> 16;
}
/**
* Gives Y coordinate of a 3D position shift by given distance into given direction.
* @param distance Specifies the distance to move.
* @param angle_a Specifies the movement rotation a.
* @param angle_b Specifies the movement rotation b.
*/
long distance3d_with_angles_to_coord_y(long distance, long angle_a, long angle_b)
{
long long val = (LbCosL(angle_a) >> 8)
* (distance * LbCosL(angle_b) >> 8);
return (-(val >> 8)) >> 8;
}
/**
* Gives new X coordinate after shifting planar position by given distance into given direction.
* @param pos_x The source coordinate to be shifted.
* @param distance Specifies the distance to move.
* @param angle Specifies the movement direction.
*/
long move_coord_with_angle_x(long pos_x, long distance, long angle)
{
long long val = (long long)distance * LbSinL(angle);
return pos_x + (val >> 16);
}
/**
* Gives new Y coordinate after shifting planar position by given distance into given direction.
* @param pos_y The source coordinate to be shifted.
* @param distance Specifies the distance to move.
* @param angle Specifies the movement direction.
*/
long move_coord_with_angle_y(long pos_y, long distance, long angle)
{
long long val = (long long)distance * LbCosL(angle);
return pos_y + ((-(val >> 8)) >> 8);
}
/******************************************************************************/
#ifdef __cplusplus
}
#endif