1 #ifndef INC_COORDS_H
2 #define INC_COORDS_H
3 
4 #include <cmath>
5 
6 #define PI 3.14159265
7 
8 struct RelCartCoord;
9 
10 // vertically upwards is 0, anticlockwise is positive; units are PI/2 radians.
11 struct Angle
12 {
13     float angle;
14 
15     Angle(float iangle=0) :
angleAngle16 	angle(iangle)
17     {
18 	normalise();
19     }
20 
21     operator float() const { return angle; }
22 
23     Angle operator += (const Angle& a)
24     {
25 	angle += a.angle;
26 	normalise();
27 	return *this;
28     }
29     Angle operator -= (const Angle& a)
30     {
31 	angle -= a.angle;
32 	normalise();
33 	return *this;
34     }
35     Angle operator *= (float m)
36     {
37 	angle *= m;
38 	normalise();
39 	return *this;
40     }
normaliseAngle41     void normalise()
42     {
43 	angle = fmod(angle,4);
44 	while (angle < 0)
45 	    angle += 4;
46     }
47 
sinfAngle48     float sinf() const
49     {
50 	// XXX: always use a.sinf() rather than sinf(a)!
51 	return ::sinf(angle*PI/2);
52     }
53 };
54 
55 struct RelPolarCoord
56 {
57     Angle angle;
58     float dist;
59 
60     RelPolarCoord(float iangle=0, float idist=0) :
angleRelPolarCoord61 	angle(iangle),dist(idist)
62     {}
63 
64     RelPolarCoord(const RelCartCoord& c);
65 
66     RelPolarCoord operator *= (float l)
67     {
68 	dist *= l;
69 	return *this;
70     }
71 
72     RelPolarCoord operator * (float l) const
73     {
74 	RelPolarCoord copy = *this;
75 	return (copy *= l);
76     }
77 
lengthsqRelPolarCoord78     float lengthsq() const
79     {
80 	return dist*dist;
81     }
82 
rotatedRelPolarCoord83     RelPolarCoord rotated(float angle) const
84     {
85 	RelPolarCoord copy = *this;
86 	copy.angle += angle;
87 	return copy;
88     }
89 };
90 
91 struct RelCartCoord
92 {
93     // dy increases upwards
94     float dx;
95     float dy;
96 
97     RelCartCoord(float idx=0, float idy=0) :
dxRelCartCoord98 	dx(idx),dy(idy)
99     {}
100 
101     RelCartCoord(const RelPolarCoord &rp);
102 
103     RelCartCoord operator *= (float l)
104     {
105 	dx *= l;
106 	dy *= l;
107 	return *this;
108     }
109 
110     RelCartCoord operator * (float l) const
111     {
112 	RelCartCoord copy = *this;
113 	return (copy *= l);
114     }
115 
116     RelCartCoord operator += (const RelCartCoord &rc)
117     {
118 	dx += rc.dx;
119 	dy += rc.dy;
120 	return *this;
121     }
122     RelCartCoord operator + (const RelCartCoord &rc) const
123     {
124 	RelCartCoord copy = *this;
125 	return (copy += rc);
126     }
127     RelCartCoord operator -= (const RelCartCoord &rc)
128     {
129 	dx -= rc.dx;
130 	dy -= rc.dy;
131 	return *this;
132     }
133     RelCartCoord operator - (const RelCartCoord &rc) const
134     {
135 	RelCartCoord copy = *this;
136 	return (copy -= rc);
137     }
138 
lengthsqRelCartCoord139     float lengthsq() const
140     {
141 	return dx*dx+dy*dy;
142     }
143 
144     RelCartCoord rotated(float angle) const;
145 };
146 
147 struct CartCoord
148 {
149     // y increases upwards
150     float x;
151     float y;
152 
153     CartCoord(float ix=0, float iy=0) :
xCartCoord154 	x(ix),y(iy) {}
155 
156     CartCoord operator += (const RelCartCoord &rc)
157     {
158 	x += rc.dx;
159 	y += rc.dy;
160 	return *this;
161     }
162 
163     CartCoord operator + (const RelCartCoord &rc) const
164     {
165 	CartCoord copy = *this;
166 	return (copy += rc);
167     }
168 
169     RelCartCoord operator - (const CartCoord &c) const
170     {
171 	RelCartCoord rc(x-c.x, y-c.y);
172 	return rc;
173     }
174 };
175 
176 struct ScreenCoord
177 {
178     // y increases *downwards*
179     int x;
180     int y;
181 
182     ScreenCoord(int ix=0, int iy=0) :
xScreenCoord183 	x(ix),y(iy)
184     {}
185 };
186 
187 float dist(RelPolarCoord c);
188 Angle angle(RelPolarCoord c);
189 
190 float angleDiff(Angle a1, Angle a2);
191 
192 #endif /* INC_COORDS_H */
193