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