24#ifndef JAU_AFFINETRANSFORM_HPP_
25#define JAU_AFFINETRANSFORM_HPP_
56 return static_cast<int>(rhs);
75 return !( lhs == rhs );
78 return bit == ( mask & bit );
105 constexpr static const char* determinantIsZero =
"Zero Determinante";
110 constexpr static const float ZERO = (float)1E-10;
114 : m00(1.0f), m10(0.0f),
115 m01(0.0f), m11(1.0f),
116 m02(0.0f), m12(0.0f),
120 constexpr AffineTransform(
const float m00_,
const float m10_,
const float m01_,
const float m11_,
const float m02_,
const float m12_) noexcept
121 : m00(m00_), m10(m10_),
122 m01(m01_), m11(m11_),
123 m02(m02_), m12(m12_),
132 : m00(mat2xN[0]), m10(mat2xN[1]),
133 m01(mat2xN[2]), m11(mat2xN[3]),
134 m02(0.0f), m12(0.0f),
174 if (m00 * m01 + m10 * m11 != 0.0f) {
187 if (m00 * m11 - m01 * m10 < 0.0f) {
191 const float dx = m00 * m00 + m10 * m10;
192 const float dy = m01 * m01 + m11 * m11;
209 float scaleX() const noexcept {
return m00; }
211 float scaleY() const noexcept {
return m11; }
213 float shearX() const noexcept {
return m01; }
215 float shearY() const noexcept {
return m10; }
238 float determinant() const noexcept {
return m00 * m11 - m01 * m10; }
240 AffineTransform&
set(
const float m00_,
const float m10_,
const float m01_,
const float m11_,
const float m02_,
const float m12_)
noexcept {
254 m10 = m01 = m02 = m12 = 0.0f;
274 m10 = m01 = m02 = m12 = 0.0f;
297 float sin = std::sin(angle);
298 float cos = std::cos(angle);
301 sin = sin > 0.0f ? 1.0f : -1.0f;
304 cos = cos > 0.0f ? 1.0f : -1.0f;
316 m02 = px * (1.0f - m00) + py * m10;
317 m12 = py * (1.0f - m00) - px * m10;
323 return concat(tmp.setToTranslation(mx, my));
327 return concat(tmp.setToScale(scx, scy));
331 return concat(tmp.setToShear(shx, shy));
335 return concat(tmp.setToRotation(angle));
339 return concat(tmp.setToRotation(angle, px, py));
351 tR.m00 * tL.m00 + tR.m10 * tL.m01,
352 tR.m00 * tL.m10 + tR.m10 * tL.m11,
353 tR.m01 * tL.m00 + tR.m11 * tL.m01,
354 tR.m01 * tL.m10 + tR.m11 * tL.m11,
355 tR.m02 * tL.m00 + tR.m12 * tL.m01 + tL.m02,
356 tR.m02 * tL.m10 + tR.m12 * tL.m11 + tL.m12);
373 set( tR.m00 * m00 + tR.m10 * m01,
374 tR.m00 * m10 + tR.m10 * m11,
375 tR.m01 * m00 + tR.m11 * m01,
376 tR.m01 * m10 + tR.m11 * m11,
377 tR.m02 * m00 + tR.m12 * m01 + m02,
378 tR.m02 * m10 + tR.m12 * m11 + m12);
396 set( m00 * tL.m00 + m10 * tL.m01,
397 m00 * tL.m10 + m10 * tL.m11,
398 m01 * tL.m00 + m11 * tL.m01,
399 m01 * tL.m10 + m11 * tL.m11,
400 m02 * tL.m00 + m12 * tL.m01 + tL.m02,
401 m02 * tL.m10 + m12 * tL.m11 + tL.m12);
415 (m01 * m12 - m11 * m02) / det,
416 (m10 * m02 - m00 * m12) / det
427 const Vec3f& lo = src.low();
428 const Vec3f& hi = src.high();
429 dst.setSize(lo.
x * m00 + lo.
y * m01 + m02, lo.
x * m10 + lo.
y * m11 + m12, lo.
z,
430 hi.
x * m00 + hi.
y * m01 + m02, hi.
x * m10 + hi.
y * m11 + m12, hi.
z);
461 float*
transform(
const float src[],
float dst[])
const noexcept {
462 const float x = src[0];
463 const float y = src[1];
464 dst[0] = x * m00 + y * m01 + m02;
465 dst[1] = x * m10 + y * m11 + m12;
469 void transform(
const float src[],
float dst[],
size_t length)
const noexcept {
470 const float* src_end = src + length * 2;
471 if (src <= dst && dst < src_end ) {
473 size_t srcOff = length * 2 - 2;
474 size_t dstOff = length * 2 - 2;
475 while (length-- > 0) {
476 const float x = src[srcOff + 0];
477 const float y = src[srcOff + 1];
478 dst[dstOff + 0] = x * m00 + y * m01 + m02;
479 dst[dstOff + 1] = x * m10 + y * m11 + m12;
486 while (length-- > 0) {
487 const float x = src[srcOff++];
488 const float y = src[srcOff++];
489 dst[dstOff++] = x * m00 + y * m01 + m02;
490 dst[dstOff++] = x * m10 + y * m11 + m12;
501 const float x = src.
x;
502 const float y = src.y;
503 dst.x = x * m00 + y * m01 + m02;
504 dst.y = x * m10 + y * m11 + m12;
513 const float x = src.
x;
514 const float y = src.y;
515 return Vec2f( x * m00 + y * m01 + m02,
516 x * m10 + y * m11 + m12 );
525 const float x = src.
x;
526 const float y = src.y;
527 dst.x = x * m00 + y * m01 + m02;
528 dst.y = x * m10 + y * m11 + m12;
534 Vec3f transformVec3f(
const Vec3f& src)
const noexcept {
535 const float x = src.
x;
536 const float y = src.y;
537 return Vec3f( x * m00 + y * m01 + m02,
538 x * m10 + y * m11 + m12,
550 return transformVec3f(src);
579 void deltaTransform(
const float src[],
float dst[],
size_t length)
const noexcept {
582 while (length-- > 0) {
583 const float x = src[srcOff++];
584 const float y = src[srcOff++];
585 dst[dstOff++] = x * m00 + y * m01;
586 dst[dstOff++] = x * m10 + y * m11;
614 while (length-- > 0) {
615 const float x = src[srcOff++] - m02;
616 const float y = src[srcOff++] - m12;
617 dst[dstOff++] = (x * m11 - y * m01) / det;
618 dst[dstOff++] = (y * m00 - x * m10) / det;
627 constexpr bool equals(
const AffineTransform& o,
const float epsilon=std::numeric_limits<float>::epsilon()) const noexcept {
Class template jau::function is a general-purpose static-polymorphic function wrapper.
Axis Aligned Bounding Box.
std::string to_string(const alphabet &v) noexcept
std::enable_if< std::is_floating_point_v< T >, bool >::type constexpr is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
std::enable_if< std::is_floating_point_v< T >, bool >::type constexpr equals(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
uint_fast32_t nsize_t
Natural 'size_t' alternative using uint_fast32_t as its natural sized type.
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
static constexpr bool is_set(const AffineTransformType mask, const AffineTransformType bit) noexcept
static constexpr AffineTransformType operator&(const AffineTransformType lhs, const AffineTransformType rhs) noexcept
static constexpr AffineTransformType operator|(const AffineTransformType lhs, const AffineTransformType rhs) noexcept
static constexpr bool operator==(const AffineTransformType lhs, const AffineTransformType rhs) noexcept
static constexpr int number(const AffineTransformType rhs) noexcept
static constexpr bool operator!=(const AffineTransformType lhs, const AffineTransformType rhs) noexcept
static constexpr AffineTransformType & operator|=(AffineTransformType &lhs, const AffineTransformType rhs) noexcept
static constexpr AffineTransformType operator^(const AffineTransformType lhs, const AffineTransformType rhs) noexcept
@ UNKNOWN
The AffineTransformType::TYPE_UNKNOWN is an initial type_t value.