2016-03-29 03:03:54 +02:00
|
|
|
#ifndef SE_INCL_GEOMETRY_INL
|
|
|
|
#define SE_INCL_GEOMETRY_INL
|
|
|
|
#ifdef PRAGMA_ONCE
|
|
|
|
#pragma once
|
|
|
|
#endif
|
2016-03-11 14:57:17 +01:00
|
|
|
|
|
|
|
// mirror a position vector by a given plane
|
|
|
|
inline void ReflectPositionVectorByPlane(const FLOATplane3D &plPlane, FLOAT3D &vPoint)
|
|
|
|
{
|
|
|
|
vPoint-=((FLOAT3D &)plPlane)*(2*plPlane.PointDistance(vPoint));
|
|
|
|
}
|
|
|
|
// mirror a direction vector by a given plane
|
|
|
|
inline void ReflectDirectionVectorByPlane(const FLOATplane3D &plPlane, FLOAT3D &vDirection)
|
|
|
|
{
|
|
|
|
vDirection-=((FLOAT3D &)plPlane)*(2*(((FLOAT3D &)plPlane)%vDirection));
|
|
|
|
}
|
|
|
|
// mirror a rotation matrix by a given plane
|
|
|
|
inline void ReflectRotationMatrixByPlane_cols(const FLOATplane3D &plPlane, FLOATmatrix3D &m)
|
|
|
|
{ // reflect columns vectors
|
|
|
|
FLOAT3D vX(m(1,1),m(2,1),m(3,1));
|
|
|
|
FLOAT3D vY(m(1,2),m(2,2),m(3,2));
|
|
|
|
FLOAT3D vZ(m(1,3),m(2,3),m(3,3));
|
|
|
|
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vX);
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vY);
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vZ);
|
|
|
|
|
|
|
|
m(1,1) = vX(1); m(1,2) = vY(1); m(1,3) = vZ(1);
|
|
|
|
m(2,1) = vX(2); m(2,2) = vY(2); m(2,3) = vZ(2);
|
|
|
|
m(3,1) = vX(3); m(3,2) = vY(3); m(3,3) = vZ(3);
|
|
|
|
}
|
|
|
|
inline void ReflectRotationMatrixByPlane_rows(const FLOATplane3D &plPlane, FLOATmatrix3D &m)
|
|
|
|
{ // reflect row vectors
|
|
|
|
FLOAT3D vX(m(1,1),m(1,2),m(1,3));
|
|
|
|
FLOAT3D vY(m(2,1),m(2,2),m(2,3));
|
|
|
|
FLOAT3D vZ(m(3,1),m(3,2),m(3,3));
|
|
|
|
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vX);
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vY);
|
|
|
|
ReflectDirectionVectorByPlane(plPlane, vZ);
|
|
|
|
|
|
|
|
m(1,1) = vX(1); m(2,1) = vY(1); m(3,1) = vZ(1);
|
|
|
|
m(1,2) = vX(2); m(2,2) = vY(2); m(3,2) = vZ(2);
|
|
|
|
m(1,3) = vX(3); m(2,3) = vY(3); m(3,3) = vZ(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get component of a vector parallel to given reference vector
|
|
|
|
static inline void GetParallelComponent(
|
|
|
|
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vParallel)
|
|
|
|
{
|
|
|
|
vParallel = vReference*(vFull%vReference);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get component of a vector normal to given reference vector
|
|
|
|
static inline void GetNormalComponent(
|
|
|
|
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vNormal)
|
|
|
|
{
|
|
|
|
vNormal = vFull-vReference*(vFull%vReference);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get components of a vector parallel and normal to given reference vector
|
|
|
|
static inline void GetParallelAndNormalComponents(
|
|
|
|
const FLOAT3D &vFull, const FLOAT3D &vReference, FLOAT3D &vParallel, FLOAT3D &vNormal)
|
|
|
|
{
|
|
|
|
vParallel = vReference*(vFull%vReference);
|
|
|
|
vNormal = vFull-vParallel;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get measure of validity of a rotation matrix (should be around zero)
|
|
|
|
static inline FLOAT RotationMatrixValidity(const FLOATmatrix3D &m)
|
|
|
|
{
|
|
|
|
FLOATmatrix3D mSqr;
|
|
|
|
mSqr(1,1) = m(1,1)*m(1,1);
|
|
|
|
mSqr(1,2) = m(1,2)*m(1,2);
|
|
|
|
mSqr(1,3) = m(1,3)*m(1,3);
|
|
|
|
mSqr(2,1) = m(2,1)*m(2,1);
|
|
|
|
mSqr(2,2) = m(2,2)*m(2,2);
|
|
|
|
mSqr(2,3) = m(2,3)*m(2,3);
|
|
|
|
mSqr(3,1) = m(3,1)*m(3,1);
|
|
|
|
mSqr(3,2) = m(3,2)*m(3,2);
|
|
|
|
mSqr(3,3) = m(3,3)*m(3,3);
|
|
|
|
|
|
|
|
FLOAT3D vH;
|
|
|
|
vH(1) = Sqrt(mSqr(1,1)+mSqr(1,2)+mSqr(1,3))-1;
|
|
|
|
vH(2) = Sqrt(mSqr(2,1)+mSqr(2,2)+mSqr(2,3))-1;
|
|
|
|
vH(3) = Sqrt(mSqr(3,1)+mSqr(3,2)+mSqr(3,3))-1;
|
|
|
|
FLOAT3D vV;
|
|
|
|
vV(1) = Sqrt(mSqr(1,1)+mSqr(2,1)+mSqr(3,1))-1;
|
|
|
|
vV(2) = Sqrt(mSqr(1,2)+mSqr(2,2)+mSqr(3,2))-1;
|
|
|
|
vV(3) = Sqrt(mSqr(1,3)+mSqr(2,3)+mSqr(3,3))-1;
|
|
|
|
|
|
|
|
return Sqrt(
|
|
|
|
vH(1)*vH(1)+vH(2)*vH(2)+vH(3)*vH(3)+
|
|
|
|
vV(1)*vV(1)+vV(2)*vV(2)+vV(3)*vV(3));
|
|
|
|
}
|
|
|
|
|
|
|
|
// normalize rotation matrix to be special orthogonal
|
|
|
|
static inline void OrthonormalizeRotationMatrix( FLOATmatrix3D &m)
|
|
|
|
{
|
|
|
|
FLOAT3D vX(m(1,1),m(2,1),m(3,1));
|
|
|
|
FLOAT3D vY(m(1,2),m(2,2),m(3,2));
|
|
|
|
FLOAT3D vZ;
|
|
|
|
|
|
|
|
vX.Normalize();
|
|
|
|
vZ = vX*vY;
|
|
|
|
vZ.Normalize();
|
|
|
|
vY = vZ*vX;
|
|
|
|
vY.Normalize();
|
|
|
|
|
|
|
|
m(1,1) = vX(1); m(1,2) = vY(1); m(1,3) = vZ(1);
|
|
|
|
m(2,1) = vX(2); m(2,2) = vY(2); m(2,3) = vZ(2);
|
|
|
|
m(3,1) = vX(3); m(3,2) = vY(3); m(3,3) = vZ(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void GetMajorAxesForPlane(
|
|
|
|
const FLOATplane3D &plPlane, INDEX &iMajorAxis1, INDEX &iMajorAxis2)
|
|
|
|
{
|
|
|
|
// get maximum normal axis
|
|
|
|
INDEX iMaxNormalAxis = plPlane.GetMaxNormal();
|
|
|
|
// the major axes are the other two axes
|
|
|
|
switch (iMaxNormalAxis) {
|
|
|
|
case 1: iMajorAxis1 = 2; iMajorAxis2 = 3;
|
|
|
|
break;
|
|
|
|
case 2: iMajorAxis1 = 3; iMajorAxis2 = 1;
|
|
|
|
break;
|
|
|
|
case 3: iMajorAxis1 = 1; iMajorAxis2 = 2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ASSERT(FALSE);
|
|
|
|
iMajorAxis1 = 2;
|
|
|
|
iMajorAxis2 = 3;
|
|
|
|
}
|
|
|
|
ASSERT(Abs(plPlane(iMaxNormalAxis))>=Abs(plPlane(iMajorAxis1))
|
|
|
|
&&Abs(plPlane(iMaxNormalAxis))>=Abs(plPlane(iMajorAxis2)));
|
|
|
|
}
|
2016-03-29 03:03:54 +02:00
|
|
|
|
|
|
|
#endif /* include-once checker ... */
|
|
|
|
|