1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: math_Vector2.h
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 18015 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NN_MATH_VECTOR2_H_
17 #define NN_MATH_VECTOR2_H_
18
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21
22 #pragma push
23 #pragma Otime
24
25 namespace nn {
26 namespace math {
27
28 struct VEC2;
29 struct MTX23;
30
31 NN_MATH_INLINE bool VEC2IsZero(const VEC2* p);
32
33 NN_MATH_INLINE VEC2* VEC2Lerp(VEC2* pOut, const VEC2* p1, const VEC2* p2, f32 t);
34 NN_MATH_INLINE f32 VEC2Dot(const VEC2* p1, const VEC2* p2);
35 NN_MATH_INLINE VEC2* VEC2Maximize(VEC2* pOut, const VEC2* p1, const VEC2* p2);
36 NN_MATH_INLINE VEC2* VEC2Minimize(VEC2* pOut, const VEC2* p1, const VEC2* p2);
37 NN_MATH_INLINE VEC2* VEC2Normalize(VEC2* pOut, const VEC2* p);
38 NN_MATH_INLINE VEC2* VEC2SafeNormalize(VEC2* pOut, const VEC2* p, const VEC2& alt);
39 NN_MATH_INLINE f32 VEC2DistSq(const VEC2* p1, const VEC2* p2);
40 NN_MATH_INLINE VEC2* VEC2Transform(VEC2* pOut, const MTX23* pM, const VEC2* pV);
41
42 /* =======================================================================
43 クラスの定義
44 ======================================================================== */
45 struct VEC2_
46 {
47 f32 x;
48 f32 y;
49 };
50
51 /*!------------------------------------------------------------------------
52 @brief 2次のベクトルクラスです。
53 ------------------------------------------------------------------------ */
54 struct VEC2 : public VEC2_
55 {
56 public:
57 static const int DIMENSION = 2; //!< 次元数です。
58
59 //!< @brief ゼロベクトルです。
ZeroVEC260 static const VEC2& Zero()
61 {
62 static const VEC2 zero(0.0f, 0.0f);
63
64 return zero;
65 }
66
67 typedef VEC2 self_type; //!< 自分の型です
68 typedef f32 value_type; //!< 要素の型です。
69 public:
70
71 //----------------------------------------
72 //! @name 作成
73 //@{
74
75 //! @brief コンストラクタです。
VEC2VEC276 VEC2() {}
77 //! @brief コンストラクタです。
VEC2VEC278 VEC2(const f32* p) { x = p[0]; y = p[1]; }
79 //! @brief コピーコンストラクタです。
VEC2VEC280 VEC2(const VEC2_& v) { x = v.x; y = v.y; }
81 //! @brief コンストラクタです。
VEC2VEC282 VEC2(f32 fx, f32 fy) { x = fx; y = fy; }
83
84 //@}
85
86 //----------------------------------------
87 //! @name 変換
88 //@{
89 //! @brief f32 型へのキャストです。
90 operator f32*() { return &x; }
91
92 //! @brief f32 型へのキャストです。
93 operator const f32*() const { return &x; }
94 //@}
95
96 //----------------------------------------
97 //! @name 演算
98 //@{
99 self_type& operator += (const self_type& rhs) { x += rhs.x; y += rhs.y; return *this; }
100 self_type& operator -= (const self_type& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
101 self_type& operator *= (const self_type& rhs) { x *= rhs.x; y *= rhs.y; return *this; }
102 self_type& operator *= (f32 f) { x *= f; y *= f; return *this; }
103 self_type& operator /= (f32 f) { f32 r = 1.f / f; x *= r; y *= r; return *this; }
104
105 self_type operator + () const { return *this; }
106 self_type operator - () const { return self_type(-x, -y); }
107
108 self_type operator + (const self_type& rhs) const { return self_type(x + rhs.x, y + rhs.y); }
109 self_type operator - (const self_type& rhs) const { return self_type(x - rhs.x, y - rhs.y); }
110 self_type operator * (f32 f) const { return self_type(f * x, f * y); }
111 self_type operator / (f32 f) const { f32 r = 1.f / f; return self_type(r * x, r * y); }
112
113 //! @brief 2つのベクトル間の線形補間を計算し設定します。
114 //!
115 //! @param[in] lhs 線形補間の始点となるベクトルです。
116 //! @param[in] rhs 線形補間の終点となるベクトルです。
117 //! @param[in] t 線形補間のパラメータ。0.0 であれば lhs が 1.0 であれば rhs が結果となります。
118 //!
LerpVEC2119 self_type& Lerp(const VEC2& lhs, const VEC2& rhs, f32 t)
120 {
121 return *VEC2Lerp(this, &lhs, &rhs, t);
122 }
123
124 //! @brief 指定したベクトルとの内積を計算します。
125 //!
126 //! @param[in] vec 内積を行うベクトルです。
127 //!
DotVEC2128 f32 Dot(const VEC2& vec) const
129 {
130 return VEC2Dot(this, &vec);
131 }
132
133 //! @brief ベクトルの長さの2乗を計算します。
LenSqVEC2134 f32 LenSq() const { return x * x + y * y; }
135
136 //! @brief ベクトルの長さの2乗を計算します。
LengthSquareVEC2137 f32 LengthSquare() const { return x * x + y * y; }
138
139 //! @brief ベクトルの長さを計算します。
LengthVEC2140 f32 Length() const { return FSqrt(this->x * this->x + this->y * this->y); }
141
142 //! @brief ベクトルを正規化します。
NormalizeVEC2143 self_type& Normalize()
144 {
145 return *VEC2Normalize(this, this);
146 }
147
148 //! @brief ベクトルを正規化します。
149 //! 正規化に失敗した場合は指定されたベクトルを設定します。
150 //!
151 //! @param[in] alt 正規化に失敗した場合に設定するベクトルです。
SafeNormalizeVEC2152 self_type& SafeNormalize(const VEC2& alt)
153 {
154 return *VEC2SafeNormalize(this, this, alt);
155 }
156
157 //! @brief 指定したベクトルとの距離の二乗を計算します。
158 //!
159 //! @param[in] vec 距離を計算するベクトルです。
DistanceSquareVEC2160 f32 DistanceSquare(const VEC2& vec)
161 {
162 return VEC2DistSq(this, &vec);
163 }
164
165 //! @brief 2つのベクトルのそれぞれの成分の最大値から構成されるベクトルを作成し設定します。
166 //!
167 //! @brief lhs 最大値を計算する左辺ベクトルです。
168 //! @brief rhs 最大値を計算する右辺ベクトルです。
MaximizeVEC2169 self_type& Maximize(const VEC2& lhs, const VEC2& rhs)
170 {
171 return *VEC2Maximize(this, &lhs, &rhs);
172 }
173
174 //! @brief 2つのベクトルのそれぞれの成分の最小値から構成されるベクトルを作成し設定します。
175 //!
176 //! @brief lhs 最小値を計算する左辺ベクトルです。
177 //! @brief rhs 最小値を計算する右辺ベクトルです。
MinimizeVEC2178 self_type& Minimize(const VEC2& lhs, const VEC2& rhs)
179 {
180 return *VEC2Minimize(this, &lhs, &rhs);
181 }
182
183 //@}
184
185 //----------------------------------------
186 //! @name 設定
187 //@{
188
189 //! @brief 値を個別に設定します。
SetVEC2190 void Set(f32 fx, f32 fy) { x = fx; y = fy; }
191
192 //@}
193
194 //----------------------------------------
195 //! @name 比較
196 //@{
197
198 //! @brief 同値であれば true を返します。
199 bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y; }
200
201 //! @brief 同値であれば true を返します。
202 bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y; }
203
204 //! @brief ゼロベクトルであれば true を返します。
IsZeroVEC2205 bool IsZero() const { return VEC2IsZero(this); }
206 //@}
207
208 //! @brief 状態を出力します。
209 void Report(bool bNewline = true, const char* name = NULL) const;
210 };
211
212 typedef struct VEC2 Vector2;
213
214 /* ------------------------------------------------------------------------
215 VEC2用の関数
216 ------------------------------------------------------------------------ */
217
218 /*!
219 @name ベクトル
220 @{
221 */
222
223 /*!--------------------------------------------------------------------------*
224 @brief ベクトルの和を計算します。
225
226 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
227 @param[in] p1 左辺値へのポインタ
228 @param[in] p2 右辺値へのポインタ
229
230 @return pOut を返します。
231 *---------------------------------------------------------------------------*/
232 inline VEC2*
VEC2Add(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)233 VEC2Add(VEC2* pOut, const VEC2* p1, const VEC2* p2)
234 {
235 NN_NULL_ASSERT( pOut );
236 NN_NULL_ASSERT( p1 );
237 NN_NULL_ASSERT( p2 );
238
239 pOut->x = p1->x + p2->x; pOut->y = p1->y + p2->y;
240 return pOut;
241 }
242
243 /*!--------------------------------------------------------------------------*
244 @brief ベクトルの差を計算します。
245
246 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
247 @param[in] p1 左辺値へのポインタ
248 @param[in] p2 右辺値へのポインタ
249
250 @return pOut を返します。
251 *---------------------------------------------------------------------------*/
252 inline VEC2*
VEC2Sub(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)253 VEC2Sub(VEC2* pOut, const VEC2* p1, const VEC2* p2)
254 {
255 NN_NULL_ASSERT( pOut );
256 NN_NULL_ASSERT( p1 );
257 NN_NULL_ASSERT( p2 );
258
259 pOut->x = p1->x - p2->x; pOut->y = p1->y - p2->y;
260 return pOut;
261 }
262
263 /*!--------------------------------------------------------------------------*
264 @brief ベクトルの積を計算します。
265
266 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
267 @param[in] p1 左辺値へのポインタ
268 @param[in] p2 右辺値へのポインタ
269
270 @return pOut を返します。
271 *---------------------------------------------------------------------------*/
272 inline VEC2*
VEC2Mult(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)273 VEC2Mult(VEC2* pOut, const VEC2* p1, const VEC2* p2)
274 {
275 pOut->x = p1->x * p2->x;
276 pOut->y = p1->y * p2->y;
277 return pOut;
278 }
279
280 /*!--------------------------------------------------------------------------*
281 @brief ベクトルのスカラー倍を計算します。
282
283 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
284 @param[in] p 左辺値へのポインタ
285 @param[in] scale 掛ける数
286
287 @return pOut を返します。
288 *---------------------------------------------------------------------------*/
289 inline VEC2*
VEC2Scale(VEC2 * pOut,const VEC2 * p,f32 scale)290 VEC2Scale(VEC2* pOut, const VEC2* p, f32 scale)
291 {
292 NN_NULL_ASSERT( pOut );
293 NN_NULL_ASSERT( p );
294
295 pOut->x = p->x * scale; pOut->y = p->y * scale;
296 return pOut;
297 }
298
299
300 /*!--------------------------------------------------------------------------*
301 @brief ベクトル間の線形補間を計算します。
302
303 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
304 @param[in] p1 線形補間の始点となるベクトルへのポインタ
305 @param[in] p2 線形補間の終点となるベクトルへのポインタ
306 @param[in] t 線形補間のパラメータ。0.0 であれば p1 が 1.0 であれば p2 が結果となります。
307
308 @return pOut を返します。
309 *---------------------------------------------------------------------------*/
310 inline VEC2*
VEC2Lerp(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2,f32 t)311 VEC2Lerp(VEC2* pOut, const VEC2* p1, const VEC2* p2, f32 t)
312 {
313 // (1-t)*p1 + t*p2
314 pOut->x = p1->x + t * (p2->x - p1->x);
315 pOut->y = p1->y + t * (p2->y - p1->y);
316 return pOut;
317 }
318
319
320 /*!--------------------------------------------------------------------------*
321 @brief ベクトルの内積を計算します。
322
323 @param[in] p1 左辺値へのポインタ
324 @param[in] p2 右辺値へのポインタ
325
326 @return p1 と p2 の内積を返します。
327 *---------------------------------------------------------------------------*/
328 inline f32
VEC2Dot(const VEC2 * p1,const VEC2 * p2)329 VEC2Dot(const VEC2* p1, const VEC2* p2)
330 {
331 NN_NULL_ASSERT( p1 );
332 NN_NULL_ASSERT( p2 );
333
334 return p1->x * p2->x + p1->y * p2->y;
335 }
336
337 /*!--------------------------------------------------------------------------*
338 @brief ベクトルの長さの2乗を計算します。
339
340 @param[in] p 対象のベクトルへのポインタ。
341
342 @return p の長さの2乗を返します。
343 *---------------------------------------------------------------------------*/
344 inline f32
VEC2LenSq(const VEC2 * p)345 VEC2LenSq(const VEC2* p)
346 {
347 NN_NULL_ASSERT( p );
348 return p->x * p->x + p->y * p->y;
349 }
350
351 /*!--------------------------------------------------------------------------*
352 @brief ベクトルの長さを計算します。
353
354 @param[in] p 対象のベクトルへのポインタ。
355
356 @return p の長さを返します。
357 *---------------------------------------------------------------------------*/
358 inline f32
VEC2Len(const VEC2 * p)359 VEC2Len(const VEC2* p) { return FSqrt(p->x * p->x + p->y * p->y); }
360
361 /*!--------------------------------------------------------------------------*
362 @brief 2つのベクトル間の距離の2乗を計算します。
363
364 @param[in] p1 左辺値へのポインタ
365 @param[in] p2 右辺値へのポインタ
366
367 @return p1 と p2 の距離の2乗を返します。
368 *---------------------------------------------------------------------------*/
369 inline f32
VEC2DistSq(const VEC2 * p1,const VEC2 * p2)370 VEC2DistSq(const VEC2* p1, const VEC2* p2) { VEC2 tmp; return VEC2LenSq(VEC2Sub(&tmp, p1, p2)); }
371
372 inline VEC2
373 operator * (f32 f, const VEC2& rhs) { return VEC2(f * rhs.x, f * rhs.y); }
374
375 /*!
376 @}
377 */
378
379 } // namespace math
380 } // namespace nn
381
382 #if defined(NN_MATH_AS_INLINE)
383 #include <nn/math/inline/math_Vector2.ipp>
384 #endif
385
386 namespace nn {
387 namespace math {
388
389 //-- const 引数を参照にしたオーバーロード
VEC2IsZero(const VEC2 & v)390 inline bool VEC2IsZero(const VEC2& v){ return VEC2IsZero( &v ); }
VEC2Add(VEC2 * pOut,const VEC2 & p1,const VEC2 & p2)391 inline VEC2* VEC2Add(VEC2* pOut, const VEC2& p1, const VEC2& p2) { return VEC2Add(pOut, &p1, &p2); }
VEC2Sub(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)392 inline VEC2* VEC2Sub(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Sub(pOut, &v1, &v2); }
VEC2Mult(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)393 inline VEC2* VEC2Mult(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Mult(pOut, &v1, &v2); }
VEC2Scale(VEC2 * pOut,const VEC2 & v,f32 scale)394 inline VEC2* VEC2Scale(VEC2* pOut, const VEC2& v, f32 scale) { return VEC2Scale(pOut, &v, scale); }
VEC2Lerp(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2,f32 t)395 inline VEC2* VEC2Lerp(VEC2* pOut, const VEC2& v1, const VEC2& v2, f32 t) { return VEC2Lerp(pOut, &v1, &v2, t); }
VEC2Dot(const VEC2 & v1,const VEC2 & v2)396 inline f32 VEC2Dot(const VEC2& v1, const VEC2& v2) { return VEC2Dot(&v1, &v2); }
VEC2LenSq(const VEC2 & v)397 inline f32 VEC2LenSq(const VEC2& v) { return VEC2LenSq( &v ); }
VEC2Len(const VEC2 & v)398 inline f32 VEC2Len(const VEC2& v) { return VEC2Len( &v ); }
VEC2DistSq(const VEC2 & v1,const VEC2 & v2)399 inline f32 VEC2DistSq(const VEC2& v1, const VEC2& v2) { return VEC2DistSq( &v1, &v2 ); }
400
VEC2Maximize(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)401 inline VEC2* VEC2Maximize(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Maximize( pOut, &v1, &v2 ); }
VEC2Minimize(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)402 inline VEC2* VEC2Minimize(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Minimize( pOut, &v1, &v2 ); }
VEC2Normalize(VEC2 * pOut,const VEC2 & v)403 inline VEC2* VEC2Normalize(VEC2* pOut, const VEC2& v) { return VEC2Normalize( pOut, &v ); }
VEC2SafeNormalize(VEC2 * pOut,const VEC2 & v,const VEC2 & alt)404 inline VEC2* VEC2SafeNormalize(VEC2* pOut, const VEC2& v, const VEC2& alt) { return VEC2SafeNormalize( pOut, &v, alt ); }
VEC2Transform(VEC2 * pOut,const MTX23 & m,const VEC2 & v)405 inline VEC2* VEC2Transform(VEC2* pOut, const MTX23& m, const VEC2& v) { return VEC2Transform( pOut, &m, &v ); }
406
407 } // namespace math
408 } // namespace nn
409
410 #pragma pop
411
412 #endif
413