gwnavruntime/math/vec2f.h Source File

vec2f.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 #pragma once
8 
12 
13 namespace Kaim
14 {
15 
18 class Vec2f
19 {
20  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
21 
22 public:
23  // ------------------------------ Functions -----------------------------
24 
25  Vec2f() : x(0.0f), y(0.0f) {}
26  Vec2f(KyFloat32 _x, KyFloat32 _y) : x(_x), y(_y) {}
27  explicit Vec2f(KyFloat32* coords) { Set(coords); }
28 
29  void Set(KyFloat32 _x, KyFloat32 _y) { x = _x; y = _y; }
30  void Set(const KyFloat32* coords) { x = coords[0]; y = coords[1]; }
31 
32  void Clear() { x = 0.0f; y = 0.0f; }
33 
34  // ------------------------------ Operators -----------------------------
35 
36  KyFloat32& operator[](KyInt32 i) { return (&x)[i]; }
37  KyFloat32 operator[](KyInt32 i) const { return (&x)[i]; }
38 
39  bool operator==(const Vec2f& v) const { return x == v.x && y == v.y; }
40  bool operator!=(const Vec2f& v) const { return x != v.x || y != v.y; }
41 
43  bool operator<(const Vec2f& v) const { return (x != v.x) ? x < v.x : y < v.y; };
44  bool operator>(const Vec2f& v) const { return (x != v.x) ? x < v.x : y <= v.y; };
45  bool operator<=(const Vec2f& v) const { return (x != v.x) ? x > v.x : y > v.y; };
46  bool operator>=(const Vec2f& v) const { return (x != v.x) ? x < v.x : y >= v.y; };
47 
48  Vec2f& operator*=(KyFloat32 s) { x *= s; y *= s; return *this; }
49  Vec2f& operator/=(KyFloat32 d) { return operator*=(1.0f / d); }
50  Vec2f& operator+=(const Vec2f& v) { x += v.x; y += v.y; return *this; }
51  Vec2f& operator-=(const Vec2f& v) { x -= v.x; y -= v.y; return *this; }
52 
53  Vec2f operator*(KyFloat32 s)const { return Vec2f(x * s, y * s); }
54  Vec2f operator/(KyFloat32 d) const { return operator*(1.0f / d); }
55  Vec2f operator+(const Vec2f& v) const { return Vec2f(x + v.x, y + v.y); }
56  Vec2f operator-(const Vec2f& v) const { return Vec2f(x - v.x, y - v.y); }
57  Vec2f operator-() const { return Vec2f(-x, -y); }
58 
59  KyFloat32 operator*(const Vec2f& v) const { return x * v.x + y * v.y; }
60  KyFloat32 operator^(const Vec2f& v) const { return x * v.y - y * v.x; }
61 
62  // ------------------------------ Length -----------------------------
63 
64  KyFloat32 GetSquareLength() const { return x * x + y * y; }
65  KyFloat32 GetLength() const { return Sqrtf(x * x + y * y); }
66  KyFloat32 Normalize();
67  KyFloat32 GetNormalized(Vec2f& normalized) const;
68  Vec2f GetNormalized() const;
69 
70  // ------------------------------ Length Shorter Names -----------------------------
71 
72  KyFloat32 SqLength() const { return x * x + y * y; }
73  KyFloat32 Length() const { return Sqrtf(x * x + y * y); }
74  Vec2f Dir() const { return GetNormalized(); }
75 
76  // ------------------------------ Rotation -----------------------------
77 
78  Vec2f PerpCW() const { return Vec2f( y, -x); }
79  Vec2f PerpCCW() const { return Vec2f(-y, x); }
80 
81  void RotateCCW(KyFloat32 cosAngle, KyFloat32 sinAngle) { Set(cosAngle * x - sinAngle * y, sinAngle * x + cosAngle * y); }
82  Vec2f GetRotatedCCW(KyFloat32 cosAngle, KyFloat32 sinAngle) const { return Vec2f(cosAngle * x - sinAngle * y, sinAngle * x + cosAngle * y); }
83 
84  // ------------------------------ Offset -----------------------------
85 
86  Vec2f OffsetX(KyFloat32 dx) const { return Vec2f(x + dx, y); }
87  Vec2f OffsetY(KyFloat32 dy) const { return Vec2f(x, y + dy); }
88  Vec2f Offset(KyFloat32 dx, KyFloat32 dy) const { return Vec2f(x + dx, y + dy); }
89 
90  // ------------------------------ Zero -----------------------------
91 
92  bool IsZero() const { return x == 0.0f && y == 0.0f; }
93  static Vec2f Zero() { return Vec2f(0.0f, 0.0f); }
94 
95  // ------------------------------ Unit -----------------------------
96 
97  static Vec2f UnitX() { return Vec2f(1.0f, 0.0f); }
98  static Vec2f UnitY() { return Vec2f(0.0f, 1.0f); }
99 
100  // ------------------------------ Data -----------------------------
101 
102  KyFloat32 x;
103  KyFloat32 y;
104 };
105 
106 inline void SwapEndianness(Endianness::Target e, Vec2f& self)
107 {
108  SwapEndianness(e, self.x);
109  SwapEndianness(e, self.y);
110 }
111 
112 template <class OSTREAM>
113 inline OSTREAM& operator<<(OSTREAM& os, const Vec2f& v)
114 {
115  return os << "{" << v.x << "," << v.y << "}";
116 }
117 
118 // ------------------------------ Global Functions -----------------------------
119 
120 inline Vec2f operator*(KyFloat32 s, const Vec2f& v) { return Vec2f(v.x * s, v.y * s); }
121 inline KyFloat32 DotProduct(const Vec2f& v1, const Vec2f& v2) { return v1.x * v2.x + v1.y * v2.y; }
122 inline KyFloat32 CrossProduct(const Vec2f& v1, const Vec2f& v2) { return v1.x * v2.y - v1.y * v2.x; }
123 inline KyFloat32 CrossProduct_z(const Vec2f& v1, const Vec2f& v2) { return v1.x * v2.y - v1.y * v2.x; }
124 
125 inline Vec2f Seg(const Vec2f& A, const Vec2f& B) { return B - A; }
126 
127 // ------------------------------ Distance and Direction ------------------------------
128 
130 inline KyFloat32 SquareDistance(const Vec2f& A, const Vec2f& B)
131 {
132  const KyFloat32 dx = B.x - A.x;
133  const KyFloat32 dy = B.y - A.y;
134  return dx * dx + dy * dy;
135 }
136 
138 inline KyFloat32 Distance(const Vec2f& A, const Vec2f& B) { return Sqrtf(SquareDistance(A, B)); }
139 
141 inline Vec2f GetNormalized(const Vec2f& v)
142 {
143  const KyFloat32 length = v.GetLength();
144  if (length != 0.0f) // use CanDivideBy()
145  return v / length;
146  return Vec2f::Zero();
147 }
148 
150 inline Vec2f Dir(const Vec2f& A, const Vec2f& B) { return (B - A).GetNormalized(); }
151 
152 inline bool IsEpsilonZero(const Vec2f& v) { return IsEpsilonZero(v.x) && IsEpsilonZero(v.y); }
153 inline bool IsEpsilonEqual(const Vec2f& v1, const Vec2f& v2) { return IsEpsilonEqual(v1.x, v2.x) && IsEpsilonEqual(v1.y, v2.y); }
154 inline bool IsEpsilonDifferent(const Vec2f& A, const Vec2f& B) { return !IsEpsilonEqual(A, B); }
155 
156 // ------------------------------ Angles and Rotation ------------------------------
157 
166 inline KyFloat32 GetPositiveAngleCCW(const Vec2f& v1, const Vec2f& v2)
167 {
168  const KyFloat32 sqlenV1 = v1.SqLength();
169  const KyFloat32 sqlenV2 = v2.SqLength();
170  const KyFloat32 sqlenProd = sqlenV1 * sqlenV2;
171 
172  if (sqlenProd != 0.0f)
173  {
174  const KyFloat32 lenProd = (sqlenProd == 1.0f) ? 1.0f : Sqrtf(sqlenProd);
175 
176  const KyFloat32 dp = DotProduct(v1, v2);
177  const KyFloat32 angle = Acosf(dp / lenProd);
178 
179  const KyFloat32 cp = CrossProduct(v1, v2);
180  return cp >= 0.0f ? angle : KY_2_PI - angle;
181  }
182  else
183  return 0.0f;
184 }
185 
194 inline KyFloat32 GetPositiveAngleCW(const Vec2f& v1, const Vec2f& v2)
195 {
196  return GetPositiveAngleCCW(v2, v1);
197 }
198 
200 inline KyFloat32 GetPositiveAngle(const Vec2f& v1, const Vec2f& v2, Winding::Enum winding)
201 {
202  switch (winding)
203  {
204  case Winding::CW: return GetPositiveAngleCW( v1, v2);
205  case Winding::CCW: return GetPositiveAngleCCW(v1, v2);
206  default: return GetPositiveAngleCCW(v1, v2);
207  }
208 }
209 
211 inline KyFloat32 GetSignedAngle(const Vec2f& v1, const Vec2f& v2, Winding::Enum winding)
212 {
213  switch (winding)
214  {
215  case Winding::CW: return -GetPositiveAngleCW( v1, v2);
216  case Winding::CCW: return GetPositiveAngleCCW(v1, v2);
217  default: return GetPositiveAngleCCW(v1, v2);
218  }
219 }
220 
222 inline void Rotate(Vec2f& v, KyFloat32 cosAngle, KyFloat32 sinAngle) { v.RotateCCW(cosAngle, sinAngle); }
223 
231 inline Vec2f BisectorCCW(const Vec2f& dir1, const Vec2f& dir2)
232 {
233  KyFloat32 cp = CrossProduct(dir1, dir2);
234  if (fabsf(cp) > 0.01f) // not collinear
235  return (dir2 - dir1).PerpCW().GetNormalized();
236  else // almost collinear
237  return cp > 0.0f ? (dir1 + dir2).GetNormalized() : -(dir1 + dir2).GetNormalized();
238 }
239 
246 inline Vec2f BisectorCCW(const Vec2f& A, const Vec2f& B, const Vec2f& C)
247 {
248  return BisectorCCW(Dir(B, C), Dir(B, A));
249 }
250 
252 inline bool Dir2dLessCCW(const Vec2f& dir_ref, const Vec2f& dir_a, const Vec2f& dir_b)
253 {
254  const KyFloat32 ra = CrossProduct(dir_ref, dir_a);
255  const KyFloat32 rb = CrossProduct(dir_ref, dir_b);
256  const KyFloat32 ab = CrossProduct(dir_a, dir_b);
257 
258  // rb=0 b=r // rb=0 b=-r ab=0 a=r // rb=0 b=-r ab=0 a=-r // rb=0 b=-r ab>0 // rb=0 b=-r ab<0 //
259  // // // // a // //
260  // +-b // b-+-r=a // a=b-+-r // b-+-r // b-+-r //
261  // false // true // false // true // a false //
262  if (rb == 0.0f)
263  {
264  if (DotProduct(dir_ref, dir_b) > 0.0f)
265  return false; // b=r
266  if (ab == 0.0f)
267  return DotProduct(dir_ref, dir_a) > 0.0f;
268  return ab > 0.0f;
269  }
270  // rb>0 ra<0 // rb>0 ra>=0 ab>0 // rb>0 ra>=0 ab<=0 //
271  // b // b a // a b //
272  // --+-r // --+-r // --+-r //
273  // a false // true // false //
274  if (rb > 0.0f)
275  {
276  if (ra < 0.0f)
277  return false;
278  return ab > 0.0f;
279  }
280  else
281  // rb<0 ra>=0 // rb<0 ra<0 ab>0 // rb<0 ra<0 ab<=0 //
282  // a // // //
283  // --+-r // --+-r // --+-r //
284  // b true // a b true // b a false //
285  {
286  if (ra >= 0.0f)
287  return true;
288  return ab > 0.0f;
289  }
290 }
291 
293 inline bool Dir2dLessCW(const Vec2f& dir_ref, const Vec2f& dir_a, const Vec2f& dir_b)
294 {
295  return Dir2dLessCCW(dir_ref, dir_b, dir_a);
296 }
297 
298 // ------------------------------ Global Functions Shorter Names -----------------------------
299 
300 inline KyFloat32 Dot(const Vec2f& v1, const Vec2f& v2) { return DotProduct(v1, v2); }
301 inline KyFloat32 Cross_z(const Vec2f& v1, const Vec2f& v2) { return CrossProduct_z(v1, v2); }
302 inline KyFloat32 Cross(const Vec2f& v1, const Vec2f& v2) { return CrossProduct(v1, v2); }
303 inline KyFloat32 SqDist(const Vec2f& A, const Vec2f& B) { return SquareDistance(A, B); }
304 inline KyFloat32 Dist(const Vec2f& A, const Vec2f& B) { return Distance(A, B); }
305 
306 
307 // ------------------------------ end -----------------------------
308 
309 inline KyFloat32 Vec2f::Normalize()
310 {
311  const KyFloat32 length = GetLength();
312  if (length != 0.0f) // use CanDivideBy()
313  operator/=(length);
314  else
315  Set(0.0f, 0.0f);
316  return length;
317 }
318 
319 inline KyFloat32 Vec2f::GetNormalized(Vec2f& normalized) const
320 {
321  // don't call Vec2f::Normalize() to avoid LHS
322  const KyFloat32 length = GetLength();
323  if (length != 0.0f) // use CanDivideBy()
324  {
325  const KyFloat32 inv_length = 1.0f / length;
326  normalized.Set(x * inv_length, y * inv_length);
327  return length;
328  }
329  else
330  {
331  normalized.Set(0.0f, 0.0f);
332  return 0.0f;
333  }
334 }
335 
336 inline Vec2f Vec2f::GetNormalized() const
337 {
338  const KyFloat32 length = GetLength();
339  if (length != 0.0f) // use CanDivideBy()
340  return *this / length;
341  return Vec2f::Zero();
342 }
343 
344 }
345 
KyFloat32 GetPositiveAngle(const Vec2f &v1, const Vec2f &v2, Winding::Enum winding)
Returns the positive angle in [0,2PI[ of the CounterClockwise or Clockwise rotation from v1 to v2...
Definition: vec2f.h:200
Vec2f()
Sets {0.0f, 0.0f}.
Definition: vec2f.h:25
bool operator<(const Vec2f &v) const
x is compared first, ex: {1, 5} < {2,="" 0}="" />
Definition: vec2f.h:43
KyFloat32 operator^(const Vec2f &v) const
CrossProduct(*this, v)
Definition: vec2f.h:60
Vec2f OffsetY(KyFloat32 dy) const
Returns {x, y + dy}.
Definition: vec2f.h:87
Vec2f(KyFloat32 *coords)
Sets {coords[0], coords[1]}.
Definition: vec2f.h:27
KyFloat32 Distance(const Vec2f &A, const Vec2f &B)
Returns the distance between A and B.
Definition: vec2f.h:138
Vec2f GetNormalized(const Vec2f &v)
Returns normalized v, returns {0.0f, 0.0f} if v is zero.
Definition: vec2f.h:141
static Vec2f UnitX()
Returns {1.0f, 0.0f}.
Definition: vec2f.h:97
bool Dir2dLessCW(const Vec2f &dir_ref, const Vec2f &dir_a, const Vec2f &dir_b)
Returns true when the CW angle (dir_ref, dir_a) is strictly less than CCW angle (dir_ref, dir_b).
Definition: vec2f.h:293
Vec2f OffsetX(KyFloat32 dx) const
Returns {x + dx, y}.
Definition: vec2f.h:86
KyFloat32 SquareDistance(const Vec2f &A, const Vec2f &B)
Returns the square of the distance between A and B.
Definition: vec2f.h:130
KyFloat32 GetPositiveAngleCCW(const Vec2f &v1, const Vec2f &v2)
Returns the positive angle in [0,2PI[ of the CounterClockwise rotation from v1 to v2...
Definition: vec2f.h:166
KyFloat32 GetSignedAngle(const Vec2f &v1, const Vec2f &v2, Winding::Enum winding)
Returns the signed (>0 for CCW <0 for="" cw)="" angle="" in="" ]-2pi,2pi[="" of="" the="" counterclockwise="" or="" clockwise="">
Definition: vec2f.h:211
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
Vec2f Dir(const Vec2f &A, const Vec2f &B)
Returns the normalized direction AB, returns zero if A == B.
Definition: vec2f.h:150
Target
Enumerates the possible endianness types relative to the current platform.
Definition: endianness.h:27
Vec2f PerpCCW() const
Rotates by 90 degrees counter-clockwise.
Definition: vec2f.h:79
Vec2f Offset(KyFloat32 dx, KyFloat32 dy) const
Returns {x + dx, y + dy}.
Definition: vec2f.h:88
2d vector using KyFloat32.
Definition: vec2f.h:18
bool Dir2dLessCCW(const Vec2f &dir_ref, const Vec2f &dir_a, const Vec2f &dir_b)
Returns true when the CCW angle (dir_ref, dir_a) is strictly less than CCW angle (dir_ref, dir_b).
Definition: vec2f.h:252
KyFloat32 GetPositiveAngleCW(const Vec2f &v1, const Vec2f &v2)
Returns the positive angle in [0,2PI[ of the Clockwise rotation from v1 to v2.
Definition: vec2f.h:194
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
Vec2f operator*(KyFloat32 s, const Vec2f &v)
scalar * vec operator
Definition: vec2f.h:120
KyFloat32 operator*(const Vec2f &v) const
DotProduct(*this, v)
Definition: vec2f.h:59
static Vec2f Zero()
Returns {0.0f, 0.0f}.
Definition: vec2f.h:93
std::int32_t KyInt32
int32_t
Definition: types.h:24
Vec2f BisectorCCW(const Vec2f &dir1, const Vec2f &dir2)
Definition: vec2f.h:231
Vec2f PerpCW() const
Rotates by 90 degrees clockwise.
Definition: vec2f.h:78
static const KyFloat32 KY_2_PI
Stores the value of 2*pi.
Definition: fastmath.h:143
KyFloat32 CrossProduct_z(const Vec2f &v1, const Vec2f &v2)
alias for CrossProduct, useful in some template functions
Definition: vec2f.h:123
static Vec2f UnitY()
Returns {0.0f, 1.0f}.
Definition: vec2f.h:98
void Rotate(Vec2f &v, KyFloat32 cosAngle, KyFloat32 sinAngle)
Rotate v by the provided cosAngle, sinAngle. Positive angles rotate CCW.
Definition: vec2f.h:222
void Clear()
Sets {0.0f, 0.0f}.
Definition: vec2f.h:32
float KyFloat32
float
Definition: types.h:32
void Set(const KyFloat32 *coords)
Sets {coords[0], coords[1]}.
Definition: vec2f.h:30