Mat2x2::Mat2x2( const Vec2 &c1, const Vec2 &c2 ) { m[0][0] = c1.X(); m[1][0] = c1.Y(); m[0][1] = c2.X(); m[1][1] = c2.Y(); }

// Return solution x of the system Ax = b. Vec2 Solve( const Mat2x2 &A, const Vec2 &b ) { float MachEps = MachineEpsilon(); Vec2 x; double d = det( A ); double n = Norm1( A ); if( n <= MachEps || Abs(d) <= MachEps * n ) return Vec2::Zero; x.X() = A(1,1) * b.X() - A(0,1) * b.Y(); x.Y() = -A(1,0) * b.X() + A(0,0) * b.Y(); return x / d; }

float Normalize( Vec2 &A ) { float d = Len( A ); if( d != 0.0 ) { A.X() /= d; A.Y() /= d; } return d; }

Vector ToVector( const Vec2 &V ) { return Vector( V.X(), V.Y() ); }

Vec2<S> operator / (Vec2<S> const &lhs, S a) { return Vec2<S>{lhs.X() / a, lhs.Y() / a}; }

Vec2<S> operator * (Vec2<S> const &lhs, S a) { return Vec2<S>{lhs.X() * a, lhs.Y() * a}; }

Vec2<S> operator - (Vec2<S> const &lhs, S a) { return Vec2<S>{lhs.X() - a, lhs.Y() - a}; }

Vec2<S> operator + (Vec2<S> const &lhs, S a) { return Vec2<S>{lhs.X() + a, lhs.Y() + a}; }

Vec2<S> operator / (Vec2<S> const &lhs, Vec2<S> const &rhs) { return Vec2<S>{lhs.X() / rhs.X(), lhs.Y() / rhs.Y()}; }

bool Room::InBounds(Vec2 position) { return !(position.X() < 0 || position.Y() < 0 || position.X() > dimensions.X() || position.Y() > dimensions.Y()); }

Vec2 Max( const Vec2 &A, const Vec2 &B ) { return Vec2( Max( A.X(), B.X() ), Max( A.Y(), B.Y() ) ); }

Vec2 Min( const Vec2 &A, const Vec2 &B ) { return Vec2( Min( A.X(), B.X() ), Min( A.Y(), B.Y() ) ); }