📄 rotation.hpp
字号:
//===========================================================================//
// File: rotation.hh //
// Contents: Interface specification for rotation classes //
//---------------------------------------------------------------------------//
// Copyright (C) Microsoft Corporation. All rights reserved. //
//===========================================================================//
#pragma once
#include "Stuff.hpp"
#include "Angle.hpp"
#include "Vector3D.hpp"
namespace Stuff {
class UnitQuaternion;
class YawPitchRoll;
class EulerAngles;
}
#if !defined(Spew)
void
Spew(
const char* group,
const Stuff::EulerAngles &angle
);
void
Spew(
const char* group,
const Stuff::YawPitchRoll &angle
);
void
Spew(
const char* group,
const Stuff::UnitQuaternion &angle
);
#endif
namespace Stuff {
class UnitQuaternion;
class Origin3D;
class YawPitchRoll;
class UnitVector3D;
class LinearMatrix4D;
//##########################################################################
//######################### EulerAngles #############################
//##########################################################################
class EulerAngles
{
public:
Radian
pitch,
yaw,
roll;
static const EulerAngles
Identity;
//
// Constructors
//
EulerAngles()
{}
EulerAngles(
const Radian &p,
const Radian &y,
const Radian &r
)
{pitch = p; yaw = y; roll = r;}
EulerAngles(const EulerAngles &a)
{pitch = a.pitch; yaw = a.yaw; roll = a.roll;}
explicit EulerAngles(const YawPitchRoll &angles)
{*this = angles;}
explicit EulerAngles(const UnitQuaternion &quaternion)
{*this = quaternion;}
explicit EulerAngles(const LinearMatrix4D &matrix)
{*this = matrix;}
explicit EulerAngles(const Origin3D &origin)
{*this = origin;}
//
// Assignment operators
//
EulerAngles&
operator=(const EulerAngles &angles)
{
Check_Pointer(this); Check_Object(&angles);
pitch = angles.pitch; yaw = angles.yaw; roll = angles.roll;
return *this;
}
EulerAngles&
operator=(const YawPitchRoll &angles);
EulerAngles&
operator=(const UnitQuaternion &quaternion);
EulerAngles&
operator=(const LinearMatrix4D &matrix);
EulerAngles&
operator=(const Origin3D &p);
//
// "Close-enough" comparators
//
friend bool
Small_Enough(
const EulerAngles &a,
Scalar e=SMALL
);
bool
operator!() const
{return Small_Enough(*this);}
friend bool
Close_Enough(
const EulerAngles &a1,
const EulerAngles &a2,
Scalar e=SMALL
);
bool
operator==(const EulerAngles& a) const
{return Close_Enough(*this,a,SMALL);}
bool
operator!=(const EulerAngles& a) const
{return !Close_Enough(*this,a,SMALL);}
//
// Axis index operators
//
static int GetMemberCount(void)
{
return 3;
}
const Radian&
operator[](size_t index) const
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= Z_Axis);
return (&pitch)[index];
}
Radian&
operator[](size_t index)
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= Z_Axis);
return (&pitch)[index];
}
//
// Template support
//
EulerAngles&
Lerp(
const EulerAngles& v1,
const EulerAngles& v2,
Scalar t
);
//
// Support functions
//
EulerAngles&
Normalize();
#if !defined(Spew)
friend void
::Spew(
const char* group,
const EulerAngles &angle
);
#endif
//
// Test functions
//
void
TestInstance() const
{}
static bool
TestClass();
};
//##########################################################################
//######################### YawPitchRoll ############################
//##########################################################################
class YawPitchRoll
{
public:
Radian
yaw,
pitch,
roll;
static const YawPitchRoll
Identity;
//
// Constructors
//
YawPitchRoll()
{}
YawPitchRoll(
const Radian &y,
const Radian &p,
const Radian &r
)
{pitch = p; yaw = y; roll = r;}
YawPitchRoll(const YawPitchRoll &angles)
{pitch = angles.pitch; yaw = angles.yaw; roll = angles.roll;}
explicit YawPitchRoll(const EulerAngles &angles)
{*this = angles;}
explicit YawPitchRoll(const UnitQuaternion &quaternion)
{*this = quaternion;}
explicit YawPitchRoll(const LinearMatrix4D &matrix)
{*this = matrix;}
explicit YawPitchRoll(const Origin3D &origin)
{*this = origin;}
//
// Assignment operators
//
YawPitchRoll&
operator=(const YawPitchRoll &angles)
{
Check_Pointer(this); Check_Object(&angles);
pitch = angles.pitch; yaw = angles.yaw; roll = angles.roll;
return *this;
}
YawPitchRoll&
operator=(const EulerAngles &angles);
YawPitchRoll&
operator=(const UnitQuaternion &quaternion);
YawPitchRoll&
operator=(const LinearMatrix4D &matrix);
YawPitchRoll&
operator=(const Origin3D &p);
static int GetMemberCount(void)
{
return 3;
}
const Radian&
operator[](size_t index) const
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= Z_Axis);
return (&yaw)[index];
}
Radian&
operator[](size_t index)
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= Z_Axis);
return (&yaw)[index];
}
//
// "Close-enough" comparators
//
friend bool
Small_Enough(
const YawPitchRoll &a,
Scalar e=SMALL
);
bool
operator!() const
{return Small_Enough(*this);}
friend bool
Close_Enough(
const YawPitchRoll &a1,
const YawPitchRoll &a2,
Scalar e=SMALL
);
bool
operator==(const YawPitchRoll& a) const
{return Close_Enough(*this,a);}
bool
operator!=(const YawPitchRoll& a) const
{return !Close_Enough(*this,a);}
//
// Template support
//
YawPitchRoll&
Lerp(
const YawPitchRoll& v1,
const YawPitchRoll& v2,
Scalar t
);
//
// Support functions
//
YawPitchRoll&
Normalize();
#if !defined(Spew)
friend void
::Spew(
const char* group,
const YawPitchRoll& angle
);
#endif
YawPitchRoll&
AlignWithVector(const Vector3D &v);
//
// Test functions
//
void
TestInstance() const
{}
};
//##########################################################################
//######################### UnitQuaternion ###############################
//##########################################################################
class UnitQuaternion
{
public:
static const UnitQuaternion
Identity;
static void
InitializeClass();
static void
TerminateClass();
DECLARE_TIMER(static, SlerpTime);
static DWORD
SlerpCount;
Scalar
x,
y,
z,
w;
//
// Constructors
//
UnitQuaternion()
{}
UnitQuaternion(
Scalar x,
Scalar y,
Scalar z,
Scalar w
)
{
Check_Pointer(this);
this->x = x; this->y = y; this->z = z; this->w = w;
Check_Object(this);
}
//
// Assignment operators
//
UnitQuaternion&
operator=(const UnitQuaternion &q)
{
Check_Pointer(this); Check_Object(&q);
x = q.x; y = q.y; z = q.z; w = q.w; return *this;
}
UnitQuaternion&
operator=(const EulerAngles &angles);
UnitQuaternion&
operator=(const YawPitchRoll &angles);
UnitQuaternion&
operator=(const LinearMatrix4D &matrix);
UnitQuaternion&
operator=(const Origin3D &p);
UnitQuaternion&
operator=(const Vector3D &v);
//
// "Close-enough" comparators
//
friend bool
Small_Enough(
const UnitQuaternion &q,
Scalar e=SMALL
)
{Check_Object(&q); return Close_Enough(q.w,1.0f,e);}
bool
operator!() const
{return Small_Enough(*this,SMALL);}
friend bool
Close_Enough(
const UnitQuaternion &a1,
const UnitQuaternion &a2,
Scalar e=SMALL
);
bool
operator==(const UnitQuaternion& a) const
{return Close_Enough(*this,a,SMALL);}
bool
operator!=(const UnitQuaternion& a) const
{return !Close_Enough(*this,a,SMALL);}
//
// Axis index operators
//
const Scalar&
operator[](size_t index) const
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= W_Axis);
return (&x)[index];
}
Scalar&
operator[](size_t index)
{
Check_Pointer(this);
Verify(static_cast<unsigned>(index) <= W_Axis);
return (&x)[index];
}
Scalar
GetAngle();
void
GetAxis(UnitVector3D *axis);
//
// Multiplication operators
//
UnitQuaternion&
Multiply(
const UnitQuaternion &q1,
const UnitQuaternion &q2
);
UnitQuaternion&
Multiply(
const UnitQuaternion &q,
Scalar scale
);
UnitQuaternion&
MultiplyScaled(
const UnitQuaternion &q1,
const UnitQuaternion &q2,
Scalar t
);
//
// Transform functions
//
UnitQuaternion&
Multiply(
const UnitQuaternion &q,
const LinearMatrix4D &m
);
UnitQuaternion&
operator*=(const LinearMatrix4D &m);
//
// Template support
//
#if 0
UnitQuaternion&
Lerp(
const UnitQuaternion& v1,
const UnitQuaternion& v2,
Scalar t
);
#endif
UnitQuaternion&
Lerp(
const UnitQuaternion& p,
const UnitQuaternion& q,
Scalar t
);
UnitQuaternion&
FastLerp(
const UnitQuaternion& p,
const UnitQuaternion& q,
Scalar t
);
UnitQuaternion&
Lerp(
const EulerAngles& v1,
const EulerAngles& v2,
Scalar t
);
//
// Miscellaneous functions
//
UnitQuaternion&
Normalize();
UnitQuaternion&
FastNormalize();
UnitQuaternion&
Subtract(
const UnitQuaternion &end,
const UnitQuaternion &start
);
UnitQuaternion&
Subtract(
const UnitVector3D &end,
const UnitVector3D &start
);
UnitQuaternion&
Subtract(
const Vector3D &end,
const Vector3D &start
);
#if 0
UnitQuaternion&
Combine(
const EulerAngles& v1,
Scalar t1,
const EulerAngles& v2,
Scalar t2
);
#endif
// JSE -------------------------------------------------------
// ---- UnitQuaternion Slerping and Splining routines
// ---- USE AT OWN RISK!!!!
// ---- This code is as of yet untested!!!
//------------------------------------------------------------
UnitQuaternion
Squad(
const UnitQuaternion& p, // start quaternion
const UnitQuaternion& a, // start tangent quaternion
const UnitQuaternion& b, // end tangent quaternion
const UnitQuaternion& q, // end quaternion
Scalar t
);
UnitQuaternion
SquadRev(
Scalar angle, // angle of rotation
const Point3D& axis, // the axis of rotation
const UnitQuaternion& p, // start quaternion
const UnitQuaternion& a, // start tangent quaternion
const UnitQuaternion& b, // end tangent quaternion
const UnitQuaternion& q, // end quaternion
Scalar t // parameter, in range [0.0,1.0]
);
UnitQuaternion&
MakeClosest(const UnitQuaternion& qto);
Scalar
Dot(
const UnitQuaternion& p,
const UnitQuaternion& q
);
void
Negate()
{
x = -x;
y = -y;
z = -z;
w = -w;
}
UnitQuaternion&
Inverse(
const UnitQuaternion& q
);
UnitQuaternion&
Exp(
const UnitQuaternion& q
);
UnitQuaternion&
Divide(
const UnitQuaternion& p,
const UnitQuaternion& q
);
UnitQuaternion&
LnDif(
const UnitQuaternion& p,
const UnitQuaternion& q
);
UnitQuaternion&
LogN(
const UnitQuaternion& q
);
UnitQuaternion
CompA(
const UnitQuaternion& qprev,
const UnitQuaternion& q,
const UnitQuaternion& qnext
);
UnitQuaternion&
Orthog(
const UnitQuaternion& p,
const Point3D& axis
);
// END JSE ---------------------------------------
//------------------------------------------------
//
// Support functions
//
#if !defined(Spew)
friend void
::Spew(
const char* group,
const UnitQuaternion &quat
);
#endif
void
TestInstance() const;
static bool
TestClass();
};
}
namespace MemoryStreamIO {
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::EulerAngles *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::EulerAngles *input
)
{return stream->WriteBytes(input, sizeof(*input));}
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::YawPitchRoll *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::YawPitchRoll *input
)
{return stream->WriteBytes(input, sizeof(*input));}
inline Stuff::MemoryStream&
Read(
Stuff::MemoryStream* stream,
Stuff::UnitQuaternion *output
)
{return stream->ReadBytes(output, sizeof(*output));}
inline Stuff::MemoryStream&
Write(
Stuff::MemoryStream* stream,
const Stuff::UnitQuaternion *input
)
{return stream->WriteBytes(input, sizeof(*input));}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -