You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
676 lines
15 KiB
C++
676 lines
15 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// ## ######
|
|
// ###### ### Based on:
|
|
// ## ###############
|
|
// ########## # # # Shark 3D Engine (www.shark3d.com)
|
|
// ########
|
|
// ######### # # # Copyright (c) 1996-2001 Spinor GmbH.
|
|
// ## ##########
|
|
// ##
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// G A M E.O.N.E - LOW LEVEL LIB V1.0
|
|
// Copyright (C) 2001 LEVEL ONE ENTERTAINMENT,
|
|
// Licensed under the terms of LGPL.
|
|
//:---------------------------------------------------------------------------
|
|
//:Description
|
|
//
|
|
// LOW LEVEL 3D VEC2 UTIL HEADERFILE
|
|
//
|
|
//:---------------------------------------------------------------------------
|
|
|
|
#ifndef _LL3D_VEC2_H
|
|
#define _LL3D_VEC2_H
|
|
|
|
|
|
#include "ll3d_math.h"
|
|
|
|
namespace ll3d {
|
|
|
|
|
|
template<typename T> struct CVec2;
|
|
template<typename T> struct CMat2x2;
|
|
|
|
|
|
typedef CVec2<float> CVec2f;
|
|
typedef const CVec2f CVec2f_c;
|
|
typedef CVec2f &CVec2f_r;
|
|
typedef const CVec2f &CVec2f_cr;
|
|
typedef CVec2<double> CVec2d;
|
|
typedef const CVec2d CVec2d_c;
|
|
typedef CVec2d &CVec2d_r;
|
|
typedef const CVec2d &CVec2d_cr;
|
|
|
|
typedef CMat2x2<float> CMat2x2f;
|
|
typedef const CMat2x2f CMat2x2f_c;
|
|
typedef CMat2x2f &CMat2x2f_r;
|
|
typedef const CMat2x2f &CMat2x2f_cr;
|
|
typedef CMat2x2<double> CMat2x2d;
|
|
typedef const CMat2x2d CMat2x2d_c;
|
|
typedef CMat2x2d &CMat2x2d_r;
|
|
typedef const CMat2x2d &CMat2x2d_cr;
|
|
|
|
/*
|
|
* 2D Vector
|
|
*/
|
|
|
|
template<typename T>
|
|
struct CVec2
|
|
{
|
|
T m_u, m_v;
|
|
|
|
CVec2<T>();
|
|
|
|
// Set each component to the same value.
|
|
// Also allows to use 0 as null vector
|
|
CVec2<T>(T s);
|
|
|
|
CVec2<T>(T u, T v);
|
|
CVec2<T>(const CVec2<T> &v);
|
|
CVec2<T> &operator=(const CVec2<T> &v);
|
|
CVec2<T> &operator+() const;
|
|
CVec2<T> &operator-() const;
|
|
CVec2<T> &operator+=(const CVec2<T> &v);
|
|
CVec2<T> &operator-=(const CVec2<T> &v);
|
|
CVec2<T> &operator*=(T s);
|
|
CVec2<T> &operator/=(T s);
|
|
|
|
T GetSqLen() const;
|
|
T GetLen() const;
|
|
|
|
CVec2<T> GetNormalized() const;
|
|
CVec2<T> GetNormalized(T Len) const;
|
|
CVec2<T> GetDual() const;// Contract with the Levicita tensor.
|
|
bool IsFinite() const;// Are both components finite?
|
|
CVec2<T> GetAbsComp() const;// Return for each component the absolute value.
|
|
T GetMinComp() const;// Return the smallest component.
|
|
T GetMaxComp() const;// Return the largest component.
|
|
T GetSumAbsComp() const;// Return the sum of the absolute value of all components.
|
|
T GetMaxAbsComp() const;// Return the maximum of the absolute value of all components.
|
|
|
|
CVec2<T> &SetCompToMin(const CVec2<T> &v);
|
|
CVec2<T> &SetCompToMax(const CVec2<T> &v);
|
|
|
|
CVec2<T> operator+(const CVec2<T> &v) const;
|
|
CVec2<T> operator-(const CVec2<T> &v) const;
|
|
CVec2<T> operator*(T s) const;
|
|
CVec2<T> operator/(T s) const;
|
|
T operator*(const CVec2<T> &v) const;
|
|
T operator^(const CVec2<T> &v) const;// Area spanned by two vectors.
|
|
|
|
// Linear interpolation between two vectors.
|
|
// Returns (*this) + (v - (*this)) * Frac.
|
|
CVec2<T> InterpLinear(const CVec2<T> &v, T Frac) const;
|
|
|
|
CVec2<T> operator*(const CMat2x2<T> &m) const;
|
|
bool operator==(const CVec2<T> &v) const;
|
|
bool operator!=(const CVec2<T> &v) const;
|
|
int CompareComp(const CVec2<T> &v) const;
|
|
};
|
|
|
|
|
|
/*
|
|
* 2D Matrix
|
|
*/
|
|
|
|
template<typename T>
|
|
struct CMat2x2
|
|
{
|
|
T m_uu, m_uv;
|
|
T m_vu, m_vv;
|
|
|
|
CMat2x2<T>();
|
|
|
|
// Multiple of unitary matrix.
|
|
// Also allows to use 0 as null matrix and 1 as unity matrix.
|
|
CMat2x2<T>(T s);
|
|
|
|
CMat2x2<T>(T uu, T uv, T vu, T vv);
|
|
CMat2x2<T>(const CMat2x2<T> &m);
|
|
CMat2x2<T> &operator=(const CMat2x2<T> &m);
|
|
CMat2x2<T> operator+() const;
|
|
CMat2x2<T> operator-() const;
|
|
CMat2x2<T> &operator+=(const CMat2x2<T> &m);
|
|
CMat2x2<T> &operator-=(const CMat2x2<T> &m);
|
|
CMat2x2<T> &operator*=(const CMat2x2<T> &m);
|
|
CMat2x2<T> &operator*=(T s);
|
|
CMat2x2<T> &operator/=(T s);
|
|
|
|
CMat2x2<T> GetTransposed() const;
|
|
CMat2x2<T> GetInv() const;
|
|
T GetSqLen() const;
|
|
T GetLen() const;
|
|
T GetDet() const;
|
|
T GetTrace() const;
|
|
|
|
bool IsFinite() const;// Are all components finite?
|
|
|
|
|
|
CVec2<T> GetRowU() const { return CVec2<T>(m_uu, m_uv); }// Return m_uu, m_uv as vector.
|
|
CVec2<T> GetRowV() const { return CVec2<T>(m_vu, m_vv); }// Return m_vu, m_vv as vector.
|
|
CVec2<T> GetColU() const { return CVec2<T>(m_uu, m_vu); }// Return m_uu, m_vu as vector.
|
|
CVec2<T> GetColV() const { return CVec2<T>(m_uv, m_vv); }// Return m_uv, m_vv as vector.
|
|
|
|
|
|
CMat2x2<T> GetCompAbs() const;// Return componentwis absolute value.
|
|
|
|
CMat2x2<T> GetScaledRows(const CVec2<T> &v) const;
|
|
CMat2x2<T> GetScaledCols(const CVec2<T> &v) const;
|
|
|
|
static CMat2x2<T> ByTensorProd(
|
|
const CVec2<T> &v1, const CVec2<T> &v2);
|
|
|
|
static CMat2x2<T> ByDual(T Scal);
|
|
static CMat2x2<T> ByDiag(const CVec2<T> &v); // Diagonal matrix
|
|
static CMat2x2<T> ByRows(
|
|
const CVec2<T> &u, const CVec2<T> &v);
|
|
|
|
static CMat2x2<T> ByCols(
|
|
const CVec2<T> &u, const CVec2<T> &v);
|
|
|
|
static CMat2x2<T> ByAngleUnit(T Angle);
|
|
static CMat2x2<T> ByAngleLen(T Angle, T Len);
|
|
CMat2x2<T> operator+(const CMat2x2<T> &m) const;
|
|
CMat2x2<T> operator-(const CMat2x2<T> &m) const;
|
|
CMat2x2<T> operator*(T s) const;
|
|
CMat2x2<T> operator/(T s) const;
|
|
CMat2x2<T> operator*(const CMat2x2<T> &m) const;
|
|
CVec2<T> operator*(const CVec2<T> &v) const;
|
|
bool operator==(const CMat2x2<T> &m) const;
|
|
bool operator!=(const CMat2x2<T> &m) const;
|
|
};
|
|
|
|
/*
|
|
* Implementation
|
|
*/
|
|
|
|
template<typename T>
|
|
inline CVec2<T>::CVec2()
|
|
{
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T>::CVec2(T s)
|
|
{
|
|
m_u = m_v = s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T>::CVec2(T u, T v)
|
|
{
|
|
m_u = u;
|
|
m_v = v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T>::CVec2(const CVec2<T> &v)
|
|
{
|
|
m_u = v.m_u;
|
|
m_v = v.m_v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator=(const CVec2<T> &v)
|
|
{
|
|
m_u = v.m_u,
|
|
m_v = v.m_v;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator+() const
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator-() const
|
|
{
|
|
return CVec2<T>(- m_u, - m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator+=(const CVec2<T> &v)
|
|
{
|
|
return *this = *this + v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator-=(const CVec2<T> &v)
|
|
{
|
|
return *this = *this - v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator*=(T s)
|
|
{
|
|
return *this = *this * s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> &CVec2<T>::operator/=(T s)
|
|
{
|
|
return *this = *this / s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline T CVec2<T>::GetSqLen() const
|
|
{
|
|
return m_u * m_u + m_v * m_v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline T CVec2<T>::GetLen() const
|
|
{
|
|
return Sqrt(m_u * m_u + m_v * m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CVec2<T>::GetNormalized() const
|
|
{
|
|
T f = 1 / Sqrt(m_u * m_u + m_v * m_v);
|
|
return CVec2<T>(f * m_u, f * m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CVec2<T>::GetNormalized(T Len) const
|
|
{
|
|
T f = Len / Sqrt(m_u * m_u + m_v * m_v);
|
|
return CVec2<T>(f * m_u, f * m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> CVec2<T>::GetDual() const
|
|
{
|
|
return CVec2<T>(- m_v, m_u);
|
|
}
|
|
|
|
template<typename T>
|
|
bool CVec2<T>::IsFinite() const
|
|
{
|
|
return IsFinite(m_u) && IsFinite(m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CVec2<T>::GetAbsComp() const
|
|
{
|
|
return CVec2<T>(Abs(m_u), Abs(m_v));
|
|
}
|
|
|
|
template<typename T>
|
|
T CVec2<T>::GetMinComp() const
|
|
{
|
|
return Min(m_u, m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
T CVec2<T>::GetMaxComp() const
|
|
{
|
|
return Max(m_u, m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
T CVec2<T>::GetSumAbsComp() const
|
|
{
|
|
return Abs(m_u) + Abs(m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
T CVec2<T>::GetMaxAbsComp() const
|
|
{
|
|
return Max(Abs(m_u), Abs(m_v));
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> &CVec2<T>::SetCompToMin(const CVec2<T> &v)
|
|
{
|
|
if(v.m_u < m_u) m_u = v.m_u;
|
|
if(v.m_v < m_v) m_v = v.m_v;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> &CVec2<T>::SetCompToMax(const CVec2<T> &v)
|
|
{
|
|
if(v.m_u > m_u) m_u = v.m_u;
|
|
if(v.m_v > m_v) m_v = v.m_v;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> CVec2<T>::operator+(const CVec2<T> &v) const
|
|
{
|
|
return CVec2<T>(m_u + v.m_u, m_v + v.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> CVec2<T>::operator-(const CVec2<T> &v) const
|
|
{
|
|
return CVec2<T>(m_u - v.m_u, m_v - v.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> CVec2<T>::operator*(T s) const
|
|
{
|
|
return CVec2<T>(m_u * s, m_v * s);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CVec2<T> CVec2<T>::operator/(T s) const
|
|
{
|
|
return CVec2<T>(m_u / s, m_v / s);
|
|
}
|
|
|
|
template<typename T>
|
|
inline T CVec2<T>::operator*(const CVec2<T> &v) const
|
|
{
|
|
return m_u * v.m_u + m_v * v.m_v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline T CVec2<T>::operator^(const CVec2<T> &v) const
|
|
{
|
|
return m_u * v.m_v - m_v * v.m_u;
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CVec2<T>::InterpLinear(const CVec2<T> &v, T Frac) const
|
|
{
|
|
return *this + (v - *this) * Frac;
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CVec2<T>::operator*(const CMat2x2<T> &m) const
|
|
{
|
|
return CVec2<T>(
|
|
m_u * m.m_uu + m_v * m.m_vu,
|
|
m_u * m.m_uv + m_v * m.m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool CVec2<T>::operator==(const CVec2<T> &v) const
|
|
{
|
|
return m_u == v.m_u && m_v == v.m_v;
|
|
}
|
|
|
|
template<typename T>
|
|
inline bool CVec2<T>::operator!=(const CVec2<T> &v) const
|
|
{
|
|
return m_u != v.m_u || m_v != v.m_v;
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
int CVec2<T>::CompareComp(const CVec2<T> &v) const
|
|
{
|
|
if(m_u < v.m_u)
|
|
return -1;
|
|
else if(m_u > v.m_u)
|
|
return 1;
|
|
else if(m_v < v.m_v)
|
|
return -1;
|
|
else if(m_v > v.m_v)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Implementation CMat2x2
|
|
*/
|
|
template<typename T>
|
|
inline CMat2x2<T>::CMat2x2()
|
|
{
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T>::CMat2x2(T s)
|
|
{
|
|
m_uu = s; m_uv = 0;
|
|
m_vu = 0; m_vv = s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T>::CMat2x2(T uu, T uv,
|
|
T vu, T vv)
|
|
{
|
|
m_uu = uu; m_uv = uv;
|
|
m_vu = vu; m_vv = vv;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T>::CMat2x2(const CMat2x2<T> &m)
|
|
{
|
|
m_uu = m.m_uu; m_uv = m.m_uv;
|
|
m_vu = m.m_vu; m_vv = m.m_vv;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator=(const CMat2x2<T> &m)
|
|
{
|
|
m_uu = m.m_uu; m_uv = m.m_uv;
|
|
m_vu = m.m_vu; m_vv = m.m_vv;
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator+() const
|
|
{
|
|
return *this;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator-() const
|
|
{
|
|
return CMat2x2<T>(- m_uu, - m_uv, - m_vu, - m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator+=(const CMat2x2<T> &m)
|
|
{
|
|
return *this = *this + m;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator-=(const CMat2x2<T> &m)
|
|
{
|
|
return *this = *this - m;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator*=(const CMat2x2<T> &m)
|
|
{
|
|
return *this = *this * m;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator*=(T s)
|
|
{
|
|
return *this = *this * s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> &CMat2x2<T>::operator/=(T s)
|
|
{
|
|
return *this = *this / s;
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::GetTransposed() const
|
|
{
|
|
return CMat2x2<T>(m_uu, m_vu, m_uv, m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::GetInv() const
|
|
{
|
|
T f = 1.0f / (m_uu * m_vv - m_uv * m_vu);
|
|
return CMat2x2<T>(f * m_vv, - f * m_vu, - f * m_uv, f * m_uu);
|
|
}
|
|
|
|
template<typename T>
|
|
T CMat2x2<T>::GetSqLen() const
|
|
{
|
|
return (m_uu * m_uu + m_uv * m_uv) + (m_vu * m_vu + m_vv * m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
T CMat2x2<T>::GetLen() const
|
|
{
|
|
return Sqrt(GetSqLen());
|
|
}
|
|
|
|
template<typename T>
|
|
T CMat2x2<T>::GetDet() const
|
|
{
|
|
return m_uu * m_vv - m_uv * m_vu;
|
|
}
|
|
|
|
template<typename T>
|
|
inline T CMat2x2<T>::GetTrace() const
|
|
{
|
|
return m_uu + m_vv;
|
|
}
|
|
|
|
template<typename T>
|
|
bool CMat2x2<T>::IsFinite() const
|
|
{
|
|
return IsFinite(m_uu) && IsFinite(m_uv)
|
|
&& IsFinite(m_vu) && IsFinite(m_vv);
|
|
};
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::GetCompAbs() const
|
|
{
|
|
return CMat2x2<T>(
|
|
Abs(m_uu), Abs(m_uv),
|
|
Abs(m_vu), Abs(m_vv));
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::GetScaledRows(const CVec2<T> &v)
|
|
const
|
|
{
|
|
return CMat2x2<T>(
|
|
v.m_u * m_uu, v.m_u * m_uv,
|
|
v.m_v * m_vu, v.m_v * m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::GetScaledCols(const CVec2<T> &v) const
|
|
{
|
|
return CMat2x2<T>(
|
|
v.m_u * m_uu, v.m_v * m_uv,
|
|
v.m_u * m_vu, v.m_v * m_vv);
|
|
}
|
|
|
|
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::ByTensorProd(
|
|
const CVec2<T> &v1, const CVec2<T> &v2)
|
|
{
|
|
return CMat2x2<T>(
|
|
v1.m_u * v2.m_u, v1.m_u * v2.m_v,
|
|
v1.m_v * v2.m_u, v1.m_v * v2.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> ByDual(T Scal)
|
|
{
|
|
return CMat2x2<T>(0, Scal, - Scal, 0);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::ByDiag(const CVec2<T> &v)
|
|
{
|
|
return CMat2x2<T>(v.m_u, 0.0f, 0.0f, v.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::ByRows(
|
|
const CVec2<T> &u, const CVec2<T> &v)
|
|
{
|
|
return CMat2x2<T>(u.m_u, u.m_v, v.m_u, v.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::ByCols(
|
|
const CVec2<T> &u, const CVec2<T> &v)
|
|
{
|
|
return CMat2x2<T>(u.m_u, v.m_u, u.m_v, v.m_v);
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::ByAngleUnit(T Angle)
|
|
{
|
|
T ls = Sin(Angle);
|
|
T lc = Cos(Angle);
|
|
return CMat2x2<T>(lc, -ls, ls, lc);
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::ByAngleLen(T Angle, T Len)
|
|
{
|
|
T ls = Len * Sin(Angle);
|
|
T lc = Len * Cos(Angle);
|
|
return CMat2x2<T>(lc, -ls, ls, lc);
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator+(const CMat2x2<T> &m) const
|
|
{
|
|
return CMat2x2<T>(
|
|
m_uu + m.m_uu, m_uv + m.m_uv,
|
|
m_vu + m.m_vu, m_vv + m.m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator-(const CMat2x2<T> &m) const
|
|
{
|
|
return CMat2x2<T>(
|
|
m_uu - m.m_uu, m_uv - m.m_uv,
|
|
m_vu - m.m_vu, m_vv - m.m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator*(T s) const
|
|
{
|
|
return CMat2x2<T>(
|
|
m_uu * s, m_uv * s,
|
|
m_vu * s, m_vv * s);
|
|
}
|
|
|
|
template<typename T>
|
|
inline CMat2x2<T> CMat2x2<T>::operator/(T s) const
|
|
{
|
|
return CMat2x2<T>(
|
|
m_uu / s, m_uv / s,
|
|
m_vu / s, m_vv / s);
|
|
}
|
|
|
|
template<typename T>
|
|
CMat2x2<T> CMat2x2<T>::operator*(const CMat2x2<T> &m) const
|
|
{
|
|
return CMat2x2<T>(
|
|
m_uu * m.m_uu + m_uv * m.m_vu,
|
|
m_uu * m.m_uv + m_uv * m.m_vv,
|
|
m_vu * m.m_uu + m_vv * m.m_vu,
|
|
m_vu * m.m_uv + m_vv * m.m_vv);
|
|
}
|
|
|
|
template<typename T>
|
|
CVec2<T> CMat2x2<T>::operator*(const CVec2<T> &v) const
|
|
{
|
|
return CVec2<T>(
|
|
m_uu * v.m_u + m_uv * v.m_v,
|
|
m_vu * v.m_u + m_vv * v.m_v);
|
|
}
|
|
|
|
|
|
}//namespace ll2d
|
|
#endif //_LL3D_VEC2_H
|