00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #if !defined(_XRB_MATRIX2_HPP_)
00012 #define _XRB_MATRIX2_HPP_
00013
00014 #include "xrb.hpp"
00015
00016 #include "xrb_simpletransform2.hpp"
00017 #include "xrb_util.hpp"
00018 #include "xrb_vector.hpp"
00019 #include "xrb_math.hpp"
00020
00021 namespace Xrb
00022 {
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 template <typename T>
00034 class Matrix2
00035 {
00036 public:
00037
00038 static Matrix2<T> const ms_identity;
00039
00040 enum Component
00041 {
00042 A = 0,
00043 B,
00044 X,
00045 C,
00046 D,
00047 Y,
00048
00049 COMPONENT_COUNT
00050 };
00051
00052 T m[COMPONENT_COUNT];
00053
00054
00055
00056
00057
00058 inline Matrix2 () { }
00059 inline Matrix2 (
00060 T a, T b, T x,
00061 T c, T d, T y)
00062 {
00063 m[A] = a;
00064 m[B] = b;
00065 m[X] = x;
00066 m[C] = c;
00067 m[D] = d;
00068 m[Y] = y;
00069 }
00070 inline Matrix2 (T const *const components)
00071 {
00072 ASSERT1(components != NULL);
00073 #if defined(XRB_MATRIX2_USES_MEMCPY)
00074 memcpy(m, components, sizeof(T) * COMPONENT_COUNT);
00075 #else
00076 for (Uint32 i = 0; i < COMPONENT_COUNT; ++i)
00077 m[i] = components[i];
00078 #endif
00079 }
00080 inline Matrix2 (Matrix2<T> const &source)
00081 {
00082 #if defined(XRB_MATRIX2_USES_MEMCPY)
00083 memcpy(m, source.m, sizeof(T) * COMPONENT_COUNT);
00084 #else
00085 for (Uint32 i = 0; i < COMPONENT_COUNT; ++i)
00086 m[i] = source.m[i];
00087 #endif
00088 }
00089 inline Matrix2 (SimpleTransform2<T> const &source)
00090 {
00091 m[A] = source[SimpleTransform2<T>::R];
00092 m[B] = static_cast<T>(0);
00093 m[X] = source[SimpleTransform2<T>::X];
00094
00095 m[C] = static_cast<T>(0);
00096 m[D] = source[SimpleTransform2<T>::S];
00097 m[Y] = source[SimpleTransform2<T>::Y];
00098 }
00099 inline ~Matrix2 () { }
00100
00101
00102
00103
00104
00105 inline T const &operator [] (Component const component) const
00106 {
00107 ASSERT3(A == 0);
00108 ASSERT1(component < COMPONENT_COUNT);
00109 return m[component];
00110 }
00111 inline T &operator [] (Component const component)
00112 {
00113 ASSERT3(A == 0);
00114 ASSERT1(component < COMPONENT_COUNT);
00115 return m[component];
00116 }
00117
00118 inline void operator *= (Matrix2<T> const &operand)
00119 {
00120 T b, x, c;
00121 b = operand.m[A]*m[B] + operand.m[B]*m[D];
00122 x = operand.m[A]*m[X] + operand.m[B]*m[Y] + operand.m[X];
00123 c = operand.m[C]*m[A] + operand.m[D]*m[C];
00124 m[A] = operand.m[A]*m[A] + operand.m[B]*m[C];
00125 m[D] = operand.m[C]*m[B] + operand.m[D]*m[D];
00126 m[Y] = operand.m[C]*m[X] + operand.m[D]*m[Y] + operand.m[Y];
00127 m[B] = b;
00128 m[X] = x;
00129 m[C] = c;
00130 }
00131
00132 inline void operator *= (SimpleTransform2<T> const &operand)
00133 {
00134 m[A] *= operand[SimpleTransform2<T>::R];
00135 m[B] *= operand[SimpleTransform2<T>::R];
00136 m[X] = m[X]*operand[SimpleTransform2<T>::R] + operand[SimpleTransform2<T>::X];
00137 m[C] *= operand[SimpleTransform2<T>::S];
00138 m[D] *= operand[SimpleTransform2<T>::S];
00139 m[Y] = m[Y]*operand[SimpleTransform2<T>::S] + operand[SimpleTransform2<T>::Y];
00140 }
00141 inline void operator = (Matrix2<T> const &operand)
00142 {
00143 #if defined(XRB_MATRIX2_USES_MEMCPY)
00144 memcpy(m, operand.m, sizeof(T) * COMPONENT_COUNT);
00145 #else
00146 for (Uint32 i = 0; i < COMPONENT_COUNT; ++i)
00147 m[i] = operand.m[i];
00148 #endif
00149 }
00150 inline void operator = (SimpleTransform2<T> const &operand)
00151 {
00152 m[A] = operand[SimpleTransform2<T>::R];
00153 m[B] = static_cast<T>(0);
00154 m[X] = operand[SimpleTransform2<T>::X];
00155
00156 m[C] = static_cast<T>(0);
00157 m[D] = operand[SimpleTransform2<T>::S];
00158 m[Y] = operand[SimpleTransform2<T>::Y];
00159 }
00160
00161
00162
00163
00164
00165 inline T Determinant () const
00166 {
00167 return m[A] * m[D] - m[B] * m[C];
00168 }
00169 inline Matrix2<T> Inverse () const
00170 {
00171 Matrix2<T> retval;
00172 T determinant = m[A] * m[D] - m[B] * m[C];
00173 T negative_determinant = -determinant;
00174 if (determinant != negative_determinant)
00175 {
00176 retval.m[A] = m[D] / determinant;
00177 retval.m[B] = m[B] / negative_determinant;
00178 retval.m[X] = (m[B]*m[Y] - m[X]*m[D]) / determinant;
00179 retval.m[C] = m[C] / negative_determinant;
00180 retval.m[D] = m[A] / determinant;
00181 retval.m[Y] = (m[X]*m[C] - m[A]*m[Y]) / determinant;
00182 }
00183 else
00184 {
00185 #if defined(XRB_MATRIX2_USES_MEMCPY)
00186 memcpy(retval.m, ms_identity.m, sizeof(T) * COMPONENT_COUNT);
00187 #else
00188 for (Uint32 i = 0; i < COMPONENT_COUNT; ++i)
00189 retval.m[i] = ms_identity.m[i];
00190 #endif
00191 }
00192 return retval;
00193 }
00194
00195
00196
00197
00198
00199 inline void Invert ()
00200 {
00201 T determinant = m[A]*m[D] - m[B]*m[C];
00202 T negative_determinant = -determinant;
00203 if (determinant != negative_determinant)
00204 {
00205 T a, x, c;
00206 a = m[D] / determinant;
00207 x = (m[B]*m[Y] - m[X]*m[D]) / determinant;
00208 c = m[C] / negative_determinant;
00209 m[B] /= negative_determinant;
00210 m[D] = m[A] / determinant;
00211 m[Y] = (m[X]*m[C] - m[A]*m[Y]) / determinant;
00212 m[A] = a;
00213 m[X] = x;
00214 m[C] = c;
00215 }
00216 else
00217 {
00218 #if defined(XRB_MATRIX2_USES_MEMCPY)
00219 memcpy(m, ms_identity.m, sizeof(T) * COMPONENT_COUNT);
00220 #else
00221 for (Uint32 i = 0; i < COMPONENT_COUNT; ++i)
00222 m[i] = ms_identity.m[i];
00223 #endif
00224 }
00225 }
00226
00227 inline void Rotate (T const angle)
00228 {
00229 Rotate(Math::Cos(angle), Math::Sin(angle));
00230 }
00231 inline void Rotate (T const cos_value, T const sin_value)
00232 {
00233 T a, b, x;
00234 a = m[A]*cos_value - m[C]*sin_value;
00235 b = m[B]*cos_value - m[D]*sin_value;
00236 x = m[X]*cos_value - m[Y]*sin_value;
00237 m[C] = m[A]*sin_value + m[C]*cos_value;
00238 m[D] = m[B]*sin_value + m[D]*cos_value;
00239 m[Y] = m[X]*sin_value + m[Y]*cos_value;
00240 m[A] = a;
00241 m[B] = b;
00242 m[X] = x;
00243 }
00244 inline void Scale (Vector<T, 2> const &scale_factors)
00245 {
00246 m[A] *= scale_factors[Dim::X];
00247 m[B] *= scale_factors[Dim::X];
00248 m[X] *= scale_factors[Dim::X];
00249 m[C] *= scale_factors[Dim::Y];
00250 m[D] *= scale_factors[Dim::Y];
00251 m[Y] *= scale_factors[Dim::Y];
00252 }
00253 inline void Scale (T const r, T const s)
00254 {
00255 m[A] *= r;
00256 m[B] *= r;
00257 m[X] *= r;
00258 m[C] *= s;
00259 m[D] *= s;
00260 m[Y] *= s;
00261 }
00262 inline void Scale (T const scale_factor)
00263 {
00264 m[A] *= scale_factor;
00265 m[B] *= scale_factor;
00266 m[X] *= scale_factor;
00267 m[C] *= scale_factor;
00268 m[D] *= scale_factor;
00269 m[Y] *= scale_factor;
00270 }
00271 inline void Translate (Vector<T, 2> const &translation)
00272 {
00273 m[X] += translation[Dim::X];
00274 m[Y] += translation[Dim::Y];
00275 }
00276 inline void Translate (T const x, T const y)
00277 {
00278 m[X] += x;
00279 m[Y] += y;
00280 }
00281
00282 inline void SetComponents (
00283 T const a, T const b, T const x,
00284 T const c, T const d, T const y)
00285 {
00286 m[A] = a;
00287 m[B] = b;
00288 m[X] = x;
00289 m[C] = c;
00290 m[D] = d;
00291 m[Y] = y;
00292 }
00293
00294
00295
00296
00297
00298 void Fprint (
00299 FILE *const fptr,
00300 char const *const component_printf_format) const
00301 {
00302 ASSERT1(fptr != NULL);
00303 ASSERT1(component_printf_format != NULL);
00304
00305 fprintf(fptr, "Matrix2:\n\t[");
00306 fprintf(fptr, component_printf_format, m[A]);
00307 fprintf(fptr, ", ");
00308 fprintf(fptr, component_printf_format, m[B]);
00309 fprintf(fptr, ", ");
00310 fprintf(fptr, component_printf_format, m[X]);
00311 fprintf(fptr, "]\n\t[");
00312 fprintf(fptr, component_printf_format, m[C]);
00313 fprintf(fptr, ", ");
00314 fprintf(fptr, component_printf_format, m[D]);
00315 fprintf(fptr, ", ");
00316 fprintf(fptr, component_printf_format, m[Y]);
00317 fprintf(fptr, "]\n");
00318 }
00319 };
00320
00326 template <typename T>
00327 Matrix2<T> const Matrix2<T>::ms_identity(
00328 static_cast<T>(1), static_cast<T>(0), static_cast<T>(0),
00329 static_cast<T>(0), static_cast<T>(1), static_cast<T>(0));
00330
00331
00332
00333
00334
00335
00336 template <typename T>
00337 inline Matrix2<T> operator * (
00338 Matrix2<T> const &left_operand,
00339 Matrix2<T> const &right_operand)
00340 {
00341 Matrix2<T> retval(right_operand);
00342 retval *= left_operand;
00343 return retval;
00344 }
00345
00346
00347 template <typename T>
00348 inline Matrix2<T> operator * (
00349 SimpleTransform2<T> const &left_operand,
00350 Matrix2<T> const &right_operand)
00351 {
00352 Matrix2<T> retval(right_operand);
00353 retval *= left_operand;
00354 return retval;
00355 }
00356
00357
00358 template <typename T>
00359 inline Matrix2<T> operator * (
00360 Matrix2<T> const &left_operand,
00361 SimpleTransform2<T> const &right_operand)
00362 {
00363 Matrix2<T> retval;
00364 retval[Matrix2<T>::A] =
00365 left_operand[Matrix2<T>::A] * right_operand[SimpleTransform2<T>::R];
00366 retval[Matrix2<T>::B] =
00367 left_operand[Matrix2<T>::B] * right_operand[SimpleTransform2<T>::S];
00368 retval[Matrix2<T>::X] =
00369 left_operand[Matrix2<T>::A] * right_operand[SimpleTransform2<T>::X] +
00370 left_operand[Matrix2<T>::B] * right_operand[SimpleTransform2<T>::Y] +
00371 left_operand[Matrix2<T>::X];
00372 retval[Matrix2<T>::C] =
00373 left_operand[Matrix2<T>::C] * right_operand[SimpleTransform2<T>::R];
00374 retval[Matrix2<T>::D] =
00375 left_operand[Matrix2<T>::D] * right_operand[SimpleTransform2<T>::S];
00376 retval[Matrix2<T>::Y] =
00377 left_operand[Matrix2<T>::C] * right_operand[SimpleTransform2<T>::X] +
00378 left_operand[Matrix2<T>::D] * right_operand[SimpleTransform2<T>::Y] +
00379 left_operand[Matrix2<T>::Y];
00380 return retval;
00381 }
00382
00383
00384 template <typename T>
00385 inline void operator *= (
00386 Vector<T, 2> &assignee,
00387 Matrix2<T> const &operand)
00388 {
00389 T temp =
00390 operand[Matrix2<T>::A] * assignee[Dim::X] +
00391 operand[Matrix2<T>::B] * assignee[Dim::Y] +
00392 operand[Matrix2<T>::X];
00393 assignee[Dim::Y] =
00394 operand[Matrix2<T>::C] * assignee[Dim::X] +
00395 operand[Matrix2<T>::D] * assignee[Dim::Y] +
00396 operand[Matrix2<T>::Y];
00397 assignee[Dim::X] = temp;
00398 }
00399
00400
00401 template <typename T>
00402 inline Vector<T, 2> operator * (
00403 Matrix2<T> const &left_operand,
00404 Vector<T, 2> const &right_operand)
00405 {
00406 Vector<T, 2> retval(right_operand);
00407 retval *= left_operand;
00408 return retval;
00409 }
00410
00411
00412
00413
00414
00415
00416
00420 typedef Matrix2<Float> FloatMatrix2;
00421
00428 void Fprint (FILE *fptr, FloatMatrix2 const &matrix);
00429
00430 }
00431
00432 #endif // !defined(_XRB_MATRIX2_HPP_)
00433