gwnavruntime/math/vec2i.h Source File

vec2i.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 
13 
14 namespace Kaim
15 {
16 
18 class Vec2i
19 {
20  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
21 
22 public:
23  // ------------------------------ Functions -----------------------------
24 
25  Vec2i() : x(0), y(0) {}
26  Vec2i(KyInt32 _x, KyInt32 _y) : x(_x), y(_y) {}
27  explicit Vec2i(KyInt32* coords) { Set(coords); }
28 
29  void Set(KyInt32 _x, KyInt32 _y) { x = _x; y = _y; }
30  void Set(KyInt32* coords) { x = coords[0]; y = coords[1]; }
31 
32  void Clear() { x = 0; y = 0; }
33 
34  // ------------------------------ Operators -----------------------------
35 
36  KyInt32& operator[](KyInt32 idx) { return (&x)[idx]; }
37  KyInt32 operator[](KyInt32 idx) const { return (&x)[idx]; }
38 
39  bool operator==(const Vec2i& v) const { return x == v.x && y == v.y; }
40  bool operator!=(const Vec2i& v) const { return !operator==(v); }
41 
42  bool operator<(const Vec2i& v) const { return (x != v.x) ? x < v.x : y < v.y; }
43  bool operator<=(const Vec2i& v) const { return (x != v.x) ? x < v.x : y <= v.y; }
44  bool operator>(const Vec2i& v) const { return (x != v.x) ? x > v.x : y > v.y; }
45  bool operator>=(const Vec2i& v) const { return (x != v.x) ? x < v.x : y >= v.y; }
46 
47  Vec2i& operator*=(KyInt32 s) { x *= s; y *= s; return *this; }
48  Vec2i& operator/=(KyInt32 d) { x /= d; y /= d; return *this; }
49  Vec2i& operator+=(const Vec2i& v) { x += v.x; y += v.y; return *this; }
50  Vec2i& operator-=(const Vec2i& v) { x -= v.x; y -= v.y; return *this; }
51 
52  Vec2i operator*(KyInt32 s) const { return Vec2i(x * s , y * s ); }
53  Vec2i operator/(KyInt32 d) const { return Vec2i(x / d , y / d ); }
54  Vec2i operator+(const Vec2i& v) const { return Vec2i(x + v.x, y + v.y); }
55  Vec2i operator-(const Vec2i& v) const { return Vec2i(x - v.x, y - v.y); }
56  Vec2i operator-() const { return Vec2i(-x , -y ); }
57 
58  // ------------------------------ SquareLength -----------------------------
59 
60  KyInt64 SqLength() const { return KyInt64(x) * KyInt64(x) + KyInt64(y) * KyInt64(y); }
61  KyInt64 SqLength_15bits() const { return x * x + y * y; }
62  bool IsZero() const { return x == 0 && y == 0; }
63 
64  // -------------------------- Offset --------------------------------
65 
66  Vec2i OffsetX(KyInt32 dx) const { return Vec2i(x + dx, y); }
67  Vec2i OffsetY(KyInt32 dy) const { return Vec2i(x, y + dy); }
68  Vec2i Offset(KyInt32 dx, KyInt32 dy) const { return Vec2i(x + dx, y + dy); }
69 
70  // ------------------------------ Rotation -----------------------------
71 
72  Vec2i PerpCCW() const { return Vec2i(y, -x); }
73  Vec2i PerpCW() const { return Vec2i(-y, x); }
74 
75  // ------------------------------ Side -----------------------------
76 
78  KyInt64 Orient2d(const Vec2i& A, const Vec2i& B) const { return KyInt64(A.x - x) * KyInt64(B.y - y) - KyInt64(B.x - x) * KyInt64(A.y - y); } // > 0 if (MA,MB) is CCW
79  bool IsOnLeftSide(const Vec2i& A, const Vec2i& B) const { return Orient2d(A, B) >= 0; }
80  bool IsStrictlyOnLeftSide(const Vec2i& A, const Vec2i& B) const { return Orient2d(A, B) > 0; }
81 
82  // ------------------------------ IsInside -----------------------------
83 
84  bool IsInsideTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const;
85  bool IsInsideNotColinearTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const;
86  bool IsStrictlyInsideTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const;
87 
88  // ------------------------------ Zero, Unit -----------------------------
89 
90  static Vec2i Zero() { return Vec2i(0, 0); }
91  static Vec2i UnitX() { return Vec2i(1, 0); }
92  static Vec2i UnitY() { return Vec2i(0, 1); }
93 
94  // ------------------------------ Neighbors -----------------------------
95 
96  Vec2i NeighborEast() const { return Vec2i(x + 1, y ); }
97  Vec2i NeighborWest() const { return Vec2i(x - 1, y ); }
98  Vec2i NeighborNorth() const { return Vec2i(x , y + 1); }
99  Vec2i NeighborSouth() const { return Vec2i(x , y - 1); }
100 
101  void NeighborEast(Vec2i& neighbor) const { neighbor.Set(x + 1, y ); }
102  void NeighborWest(Vec2i& neighbor) const { neighbor.Set(x - 1, y ); }
103  void NeighborNorth(Vec2i& neighbor) const { neighbor.Set(x , y + 1); }
104  void NeighborSouth(Vec2i& neighbor) const { neighbor.Set(x , y - 1); }
105 
106  Vec2i Neighbor(CardinalDir dir) const
107  {
108  const KyInt8 dx[4] = { 1, 0, -1, 0 };
109  const KyInt8 dy[4] = { 0, 1, 0, -1 };
110  return Vec2i(x + dx[dir], y + dy[dir]);
111  }
112 
113  void Neighbor(CardinalDir dir, Vec2i& neighbor) const
114  {
115  const KyInt8 dx[4] = {1, 0, -1, 0};
116  const KyInt8 dy[4] = {0, 1, 0, -1};
117  neighbor.Set(x + dx[dir], y + dy[dir]);
118  }
119 
120  Vec2i NeighborNorthEast() const { return Vec2i(x + 1, y + 1); }
121  Vec2i NeighborNorthWest() const { return Vec2i(x - 1, y + 1); }
122  Vec2i NeighborSouthEast() const { return Vec2i(x + 1, y - 1); }
123  Vec2i NeighborSouthWest() const { return Vec2i(x - 1, y - 1); }
124 
125  // ------------------------------ Data -----------------------------
126 
127  KyInt32 x;
128  KyInt32 y;
129 };
130 
131 inline void SwapEndianness(Kaim::Endianness::Target e, Vec2i& self)
132 {
133  SwapEndianness(e, self.x);
134  SwapEndianness(e, self.y);
135 }
136 
137 inline Vec2i Seg(const Vec2i& A, const Vec2i& B) { return B - A; }
138 
139 inline KyInt64 SquareDistance(const Vec2i& A, const Vec2i& B) { return Seg(A, B).SqLength(); }
140 
141 inline KyInt32 DotProduct_15bits(const Vec2i& v1, const Vec2i& v2) { return v1.x * v2.x + v1.y * v2.y; }
142 inline KyInt32 CrossProduct_15bits(const Vec2i& v1, const Vec2i& v2) { return v1.x * v2.y - v1.y * v2.x; }
143 
144 inline KyInt64 DotProduct(const Vec2i& v1, const Vec2i& v2) { return KyInt64(v1.x) * KyInt64(v2.x) + KyInt64(v1.y) * KyInt64(v2.y); }
145 inline KyInt64 CrossProduct(const Vec2i& v1, const Vec2i& v2) { return KyInt64(v1.x) * KyInt64(v2.y) - KyInt64(v1.y) * KyInt64(v2.x); }
146 
147 inline bool AreAligned(const Vec2i& A, const Vec2i& B, const Vec2i& C) { return CrossProduct(B - A, C - A) == 0; }
148 
150 inline KyInt32 Side(const Vec2i& P, const Vec2i& A, const Vec2i& B) { return (KyInt32)Lsign(CrossProduct(B - A, P - A)); } // ABxAP
151 
152 inline bool Vec2i::IsInsideTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const
153 {
154  if (AreAligned(A, B, C) == 0) // flat triangle
155  {
156  if (A.x == B.x && A.x == C.x) // vertical
157  {
158  if (y < A.y && y < B.y && y < C.y) { return false; } // M.y < ABC.y
159  if (y > A.y && y > B.y && y > C.y) { return false; } // M.y > ABC.y
160  return true; // M is on ABC
161  }
162  else // not vertical
163  {
164  if (x < A.x && x < B.x && x < C.x) { return false; } // M.x < ABC.x
165  if (x > A.x && x > B.x && x > C.x) { return false; } // M.x > ABC.x
166  return true; // M is on ABC
167  }
168  }
169 
170  return IsInsideNotColinearTriangle(A, B, C);
171 }
172 
173 
174 inline bool Vec2i::IsInsideNotColinearTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const
175 {
176  return IsOnLeftSide(A, B) && IsOnLeftSide(B, C) && IsOnLeftSide(C, A);
177 }
178 
179 
180 inline bool Vec2i::IsStrictlyInsideTriangle(const Vec2i& A, const Vec2i& B, const Vec2i& C) const
181 {
182  return IsStrictlyOnLeftSide(A, B) && IsStrictlyOnLeftSide(B, C) && IsStrictlyOnLeftSide(C, A);
183 }
184 
185 template <class OSTREAM>
186 inline OSTREAM& operator<<(OSTREAM& os, const Kaim::Vec2i& v)
187 {
188  os << "{" << v.x << "," << v.y << "}";
189  return os;
190 }
191 
192 }
193 
194 
195 
196 
void Set(KyInt32 *coords)
Sets x=coords[0], y=coords[1].
Definition: vec2i.h:30
bool operator<(const Vec2i &v) const
x is compared first. ex: {1, 5} < {2,="" 0}.="" />
Definition: vec2i.h:42
KyInt64 Lsign(KyInt64 x)
return -1 if x<0, 0="" if="" x="=0," 1="" if="" x="">0
Definition: fastmath.h:43
void Set(KyInt32 _x, KyInt32 _y)
Sets x=_x and y=_y.
Definition: vec2i.h:29
KyUInt32 CardinalDir
Defines a type that refers to one of the cardinal points on the compass:
Definition: cardinaldir.h:15
KyFloat32 SquareDistance(const Vec2f &A, const Vec2f &B)
Returns the square of the distance between A and B.
Definition: vec2f.h:130
Vec2i OffsetY(KyInt32 dy) const
Returns {x, y + dy}.
Definition: vec2i.h:67
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
Vec2i Offset(KyInt32 dx, KyInt32 dy) const
Returns {x + dx, y + dy}.
Definition: vec2i.h:68
Target
Enumerates the possible endianness types relative to the current platform.
Definition: endianness.h:27
std::int64_t KyInt64
int64_t
Definition: types.h:25
Vec2i(KyInt32 *coords)
Constructs x=coords[0], y=coords[1].
Definition: vec2i.h:27
KyInt32 Side(const Vec2i &P, const Vec2i &A, const Vec2i &B)
P relative to AB: left=1, on=0, right=-1.
Definition: vec2i.h:150
2d vector using KyInt32
Definition: vec2i.h:18
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
std::int32_t KyInt32
int32_t
Definition: types.h:24
void Clear()
Sets x = 0 and y = 0.
Definition: vec2i.h:32
KyInt64 Orient2d(const Vec2i &A, const Vec2i &B) const
CrossProduct(MA, MB) where M=*this.
Definition: vec2i.h:78
std::int8_t KyInt8
int8_t
Definition: types.h:22
Vec2i(KyInt32 _x, KyInt32 _y)
Constructs x=_x, y=_y.
Definition: vec2i.h:26
Vec2i()
Constructs x=0.0f, y=0.0f.
Definition: vec2i.h:25
Vec2i OffsetX(KyInt32 dx) const
Returns {x + dx, y}.
Definition: vec2i.h:66