43#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_TRANSFORMATION_2D_INL
44#define LASS_GUARDIAN_OF_INCLUSION_PRIM_TRANSFORMATION_2D_INL
48#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
50# pragma warning(disable:4996)
66 matrix_(
impl::allocateArray<T>(matrixSize_)),
69 matrix_[ 0] = TNumTraits::one;
70 matrix_[ 1] = TNumTraits::zero;
71 matrix_[ 2] = TNumTraits::zero;
72 matrix_[ 3] = TNumTraits::zero;
73 matrix_[ 4] = TNumTraits::one;
74 matrix_[ 5] = TNumTraits::zero;
75 matrix_[ 6] = TNumTraits::zero;
76 matrix_[ 7] = TNumTraits::zero;
77 matrix_[ 8] = TNumTraits::one;
84 matrix_(
impl::allocateArray<T>(matrixSize_)),
87 matrix_[ 0] = baseX.x;
88 matrix_[ 1] = baseY.x;
89 matrix_[ 2] = origin.x;
90 matrix_[ 3] = baseX.y;
91 matrix_[ 4] = baseY.y;
92 matrix_[ 5] = origin.y;
93 matrix_[ 6] = TNumTraits::one;
94 matrix_[ 7] = TNumTraits::zero;
95 matrix_[ 8] = TNumTraits::zero;
105template <
typename InputIterator>
107 matrix_(
impl::allocateArray<T>(matrixSize_)),
110 LASS_ENFORCE(std::distance(first, last) == matrixSize_);
111 std::copy(first, last, matrix_.get());
126 if (inverseMatrix_.isEmpty())
128 TMatrix inverseMatrix(impl::allocateArray<T>(matrixSize_));
129 const TValue*
const mat = matrix_.get();
130 TValue*
const inv = inverseMatrix.get();
132 inv[0] = mat[4] * mat[8] - mat[5] * mat[7];
133 inv[1] = mat[7] * mat[2] - mat[8] * mat[1];
134 inv[2] = mat[1] * mat[5] - mat[2] * mat[4];
136 inv[3] = mat[6] * mat[5] - mat[8] * mat[3];
137 inv[4] = mat[0] * mat[8] - mat[2] * mat[6];
138 inv[5] = mat[3] * mat[2] - mat[5] * mat[0];
140 inv[6] = mat[3] * mat[7] - mat[4] * mat[6];
141 inv[7] = mat[6] * mat[1] - mat[7] * mat[0];
142 inv[8] = mat[0] * mat[4] - mat[1] * mat[3];
144 const TValue det = mat[0] *
inv[0] + mat[1] *
inv[3] + mat[2] *
inv[6];
145 if (det == TNumTraits::zero)
147 inverseMatrix.reset();
148 LASS_THROW_EX(util::SingularityError,
"transformation not invertible");
150 const TValue invDet =
num::inv(det);
151 for (
int i = 0; i < 9; ++i)
157 inverseMatrix_.swap(inverseMatrix);
161 LASS_ASSERT(inverseMatrix_ && matrix_);
162 return TSelf(inverseMatrix_, matrix_,
false);
170template <
typename T>
inline
171const typename Transformation2D<T>::TValue*
174 return matrix_.get();
180bool Transformation2D<T>::isIdentity()
const
182 const TValue*
const forward = matrix();
183 for (
size_t i = 0; i < 3; ++i)
185 for (
size_t j = 0; j < 3; ++j)
187 if (forward[i * 3 + j] != (i == j ? TNumTraits::one : TNumTraits::zero))
199bool Transformation2D<T>::isTranslation()
const
201 const TValue*
const forward = matrix();
202 for (
size_t i = 0; i < 3; ++i)
204 for (
size_t j = 0; j < 3; ++j)
206 if (j < 2 && forward[i * 3 + j] != (i == j ? TNumTraits::one : TNumTraits::zero))
218void Transformation2D<T>::swap(TSelf& other)
220 matrix_.swap(other.matrix_);
221 inverseMatrix_.swap(other.inverseMatrix_);
242 result.matrix_[2] = offset.x;
243 result.matrix_[5] = offset.y;
255 result.matrix_[0] = scale;
256 result.matrix_[4] = scale;
268 result.matrix_[0] = scale.x;
269 result.matrix_[4] = scale.y;
280 const T c = num::cos(radians);
281 const T s = num::sin(radians);
284 result.matrix_[0] = c;
285 result.matrix_[4] = c;
286 result.matrix_[1] = -s;
287 result.matrix_[3] = s;
299template <
typename T>
inline
302 inverseMatrix_(inverseMatrix)
325 const T*
const a = second.
matrix();
326 const T*
const b = first.
matrix();
328 for (
size_t i = 0; i < 9; i += 3)
330 for (
size_t j = 0; j < 3; ++j)
334 a[i + 1] * b[3 + j] +
349 const T*
const mat = transformation.
matrix();
351 mat[0] * subject.x + mat[1] * subject.y,
352 mat[3] * subject.x + mat[4] * subject.y);
363 const T*
const mat = transformation.
matrix();
364 const T weight =
num::inv(mat[6] * subject.x + mat[7] * subject.y + mat[8]);
366 weight * (mat[0] * subject.x + mat[1] * subject.y + mat[2]),
367 weight * (mat[3] * subject.x + mat[4] * subject.y + mat[5]));
381 const T*
const invMat = transformation.
inverse().matrix();
383 invMat[0] * subject.x + invMat[3] * subject.y,
384 invMat[1] * subject.x + invMat[4] * subject.y);
406 const T*
const invMat = transformation.
inverse().matrix();
408 const T c = subject.second;
409 return std::make_pair(
411 invMat[0] * n.x + invMat[3] * n.y + invMat[6] * c,
412 invMat[1] * n.x + invMat[4] * n.y + invMat[7] * c),
413 invMat[2] * n.x + invMat[5] * n.y + invMat[8] * c);
420template<
typename T,
typename Char,
typename Traits>
421std::basic_ostream<Char, Traits>& operator<<(std::basic_ostream<Char, Traits>& stream,
424 const T*
const mat = transformation.
matrix();
425 LASS_ENFORCE_STREAM(stream) <<
"(("
426 << mat[0] <<
", " << mat[1] <<
", " << mat[2] <<
"), ("
427 << mat[3] <<
", " << mat[4] <<
", " << mat[5] <<
"), ("
428 << mat[6] <<
", " << mat[7] <<
", " << mat[9] <<
"))";
439 const T*
const mat = transformation.matrix();
440 LASS_ENFORCE_STREAM(stream) <<
"<Transformation2D>"
441 << mat[0] <<
" " << mat[1] <<
" " << mat[2] <<
" "
442 << mat[3] <<
" " << mat[4] <<
" " << mat[5] <<
" "
443 << mat[6] <<
" " << mat[7] <<
" " << mat[9]
444 <<
"</Transformation2D>\n";
454#if LASS_COMPILER_TYPE == LASS_COMPILER_TYPE_MSVC
Output stream for writing a selection of geometric primitives to XML files.
T inv(const T &x)
return x ^ -1
T inv(const T &x)
return x ^ -1
implementation details of lass::prim
set of geometrical primitives
Library for Assembled Shared Sources.