Path: blob/master/thirdparty/embree/common/math/linearspace2.h
9912 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "vec2.h"67namespace embree8{9////////////////////////////////////////////////////////////////////////////////10/// 2D Linear Transform (2x2 Matrix)11////////////////////////////////////////////////////////////////////////////////1213template<typename T> struct LinearSpace214{15typedef T Vector;16typedef typename T::Scalar Scalar;1718/*! default matrix constructor */19__forceinline LinearSpace2 ( ) {}2021__forceinline LinearSpace2 ( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; }22__forceinline LinearSpace2& operator=( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; return *this; }2324template<typename L1> __forceinline LinearSpace2( const LinearSpace2<L1>& s ) : vx(s.vx), vy(s.vy) {}2526/*! matrix construction from column vectors */27__forceinline LinearSpace2(const Vector& vx, const Vector& vy)28: vx(vx), vy(vy) {}2930/*! matrix construction from row mayor data */31__forceinline LinearSpace2(const Scalar& m00, const Scalar& m01,32const Scalar& m10, const Scalar& m11)33: vx(m00,m10), vy(m01,m11) {}3435/*! compute the determinant of the matrix */36__forceinline const Scalar det() const { return vx.x*vy.y - vx.y*vy.x; }3738/*! compute adjoint matrix */39__forceinline const LinearSpace2 adjoint() const { return LinearSpace2(vy.y,-vy.x,-vx.y,vx.x); }4041/*! compute inverse matrix */42__forceinline const LinearSpace2 inverse() const { return adjoint()/det(); }4344/*! compute transposed matrix */45__forceinline const LinearSpace2 transposed() const { return LinearSpace2(vx.x,vx.y,vy.x,vy.y); }4647/*! returns first row of matrix */48__forceinline Vector row0() const { return Vector(vx.x,vy.x); }4950/*! returns second row of matrix */51__forceinline Vector row1() const { return Vector(vx.y,vy.y); }5253////////////////////////////////////////////////////////////////////////////////54/// Constants55////////////////////////////////////////////////////////////////////////////////5657__forceinline LinearSpace2( ZeroTy ) : vx(zero), vy(zero) {}58__forceinline LinearSpace2( OneTy ) : vx(one, zero), vy(zero, one) {}5960/*! return matrix for scaling */61static __forceinline LinearSpace2 scale(const Vector& s) {62return LinearSpace2(s.x, 0,630 , s.y);64}6566/*! return matrix for rotation */67static __forceinline LinearSpace2 rotate(const Scalar& r) {68Scalar s = sin(r), c = cos(r);69return LinearSpace2(c, -s,70s, c);71}7273/*! return closest orthogonal matrix (i.e. a general rotation including reflection) */74LinearSpace2 orthogonal() const75{76LinearSpace2 m = *this;7778// mirrored?79Scalar mirror(one);80if (m.det() < Scalar(zero)) {81m.vx = -m.vx;82mirror = -mirror;83}8485// rotation86for (int i = 0; i < 99; i++) {87const LinearSpace2 m_next = 0.5 * (m + m.transposed().inverse());88const LinearSpace2 d = m_next - m;89m = m_next;90// norm^2 of difference small enough?91if (max(dot(d.vx, d.vx), dot(d.vy, d.vy)) < 1e-8)92break;93}9495// rotation * mirror_x96return LinearSpace2(mirror*m.vx, m.vy);97}9899public:100101/*! the column vectors of the matrix */102Vector vx,vy;103};104105////////////////////////////////////////////////////////////////////////////////106// Unary Operators107////////////////////////////////////////////////////////////////////////////////108109template<typename T> __forceinline LinearSpace2<T> operator -( const LinearSpace2<T>& a ) { return LinearSpace2<T>(-a.vx,-a.vy); }110template<typename T> __forceinline LinearSpace2<T> operator +( const LinearSpace2<T>& a ) { return LinearSpace2<T>(+a.vx,+a.vy); }111template<typename T> __forceinline LinearSpace2<T> rcp ( const LinearSpace2<T>& a ) { return a.inverse(); }112113////////////////////////////////////////////////////////////////////////////////114// Binary Operators115////////////////////////////////////////////////////////////////////////////////116117template<typename T> __forceinline LinearSpace2<T> operator +( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return LinearSpace2<T>(a.vx+b.vx,a.vy+b.vy); }118template<typename T> __forceinline LinearSpace2<T> operator -( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return LinearSpace2<T>(a.vx-b.vx,a.vy-b.vy); }119120template<typename T> __forceinline LinearSpace2<T> operator*(const typename T::Scalar & a, const LinearSpace2<T>& b) { return LinearSpace2<T>(a*b.vx, a*b.vy); }121template<typename T> __forceinline T operator*(const LinearSpace2<T>& a, const T & b) { return b.x*a.vx + b.y*a.vy; }122template<typename T> __forceinline LinearSpace2<T> operator*(const LinearSpace2<T>& a, const LinearSpace2<T>& b) { return LinearSpace2<T>(a*b.vx, a*b.vy); }123124template<typename T> __forceinline LinearSpace2<T> operator/(const LinearSpace2<T>& a, const typename T::Scalar & b) { return LinearSpace2<T>(a.vx/b, a.vy/b); }125template<typename T> __forceinline LinearSpace2<T> operator/(const LinearSpace2<T>& a, const LinearSpace2<T>& b) { return a * rcp(b); }126127template<typename T> __forceinline LinearSpace2<T>& operator *=( LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a = a * b; }128template<typename T> __forceinline LinearSpace2<T>& operator /=( LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a = a / b; }129130////////////////////////////////////////////////////////////////////////////////131/// Comparison Operators132////////////////////////////////////////////////////////////////////////////////133134template<typename T> __forceinline bool operator ==( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a.vx == b.vx && a.vy == b.vy; }135template<typename T> __forceinline bool operator !=( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a.vx != b.vx || a.vy != b.vy; }136137////////////////////////////////////////////////////////////////////////////////138/// Output Operators139////////////////////////////////////////////////////////////////////////////////140141template<typename T> static embree_ostream operator<<(embree_ostream cout, const LinearSpace2<T>& m) {142return cout << "{ vx = " << m.vx << ", vy = " << m.vy << "}";143}144145/*! Shortcuts for common linear spaces. */146typedef LinearSpace2<Vec2f> LinearSpace2f;147typedef LinearSpace2<Vec2fa> LinearSpace2fa;148}149150151