2 Star 0 Fork 0

寧靜致遠/VectorComputation

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Quaternion.cpp 4.00 KB
一键复制 编辑 原始数据 按行查看 历史
张规化 提交于 2022-02-17 15:01 . format code
#ifndef __QUATERNION_CLASS_IMPL_DEFINE__
#define __QUATERNION_CLASS_IMPL_DEFINE__
#include "Quaternion.h"
Quaternion::Quaternion()
{
w = 0.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
Quaternion::Quaternion(double w, double x, double y, double z) :w(w), x(x), y(y), z(z)
{
}
// 转换为单位四元数
VOID Quaternion::ToIdentityQuaternion()
{
w = 1.0f;
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
// 绕任意轴旋转
VOID Quaternion::RotationAboutAnyAxis(VectorInformation& rotateAxis, double angle)
{
assert(fabs(rotateAxis.SquareVectorDescription() - 1.0f) < 0.01f);
double halfAngle = HALF_VALUE(angle);
// 计算sin半角
double sinHalfAngle = sin(halfAngle);
w = cos(halfAngle);
x = rotateAxis.GetX() * sinHalfAngle;
y = rotateAxis.GetY() * sinHalfAngle;
z = rotateAxis.GetZ() * sinHalfAngle;
}
double Quaternion::SquareQuaternion()
{
return sqrt(w * w + x * x + y * y + z * z);
}
double SafeAcos(double angle)
{
if (angle < -1.0f)
{
return PI;
}
else if (angle > 1.0F)
{
return 0.0f;
}
return acos(angle);
}
// 根据四元数计算旋转角
double Quaternion::GetRotationAngle()
{
double halfAngle = SafeAcos(w);
return halfAngle * 2.0f;
}
// 根据四元数计算旋转轴
VectorInformation Quaternion::GetRotationAxis()
{
// 计算sin半角
double sinHalfAngle = 1.0f - w * w;
double sqrtHalfAngle = sqrt(sinHalfAngle);
double nx = x * sqrtHalfAngle;
double ny = y * sqrtHalfAngle;
double nz = z * sqrtHalfAngle;
return VectorInformation(nx, ny, nz);
}
VOID Quaternion::normalize()
{
double sqrtQuat =this->SquareQuaternion();
if (sqrtQuat>0)
{
// 正常的四元数
w /= sqrtQuat;
x /= sqrtQuat;
y /= sqrtQuat;
z /= sqrtQuat;
}
else
{
// 非正常的四元数,断言+转换为单位四元数
assert(false);
ToIdentityQuaternion();
}
}
// 绕xyz轴旋转
VOID Quaternion::RotationAroundXYZAxis(ROTATE_TYPE rotateType, double angle)
{
double halfAngle = HALF_VALUE(angle);
// w固定为cos半角
w = cos(halfAngle);
switch (rotateType)
{
case ROTATE_TYPE::ROTATE_X: {
x = sin(halfAngle);
y = z = 0.0f;
break;
}
case ROTATE_TYPE::ROTATE_Y: {
y = sin(halfAngle);
x = z = 0.0f;
break;
}
case ROTATE_TYPE::ROTATE_Z: {
z = sin(halfAngle);
x = y = 0.0f;
break;
}
default:
assert(false);
break;
}
}
Quaternion operator*(Quaternion& q1, Quaternion& q2)
{
double w1 = q1.GetW();
double x1 = q1.GetX();
double y1 = q1.GetY();
double z1 = q1.GetZ();
double w2 = q2.GetW();
double x2 = q2.GetX();
double y2 = q2.GetY();
double z2 = q2.GetZ();
double newW = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2;
double newX = w1 * x2 + x1 * w2 + z1 * y2 - y1 * z2;
double newY = w1 * y2 + y1 * w2 + x1 * z2 - z1 * x2;
double newZ = w1 * z2 + z1 * w2 + y1 * x2 - x1 * y2;
return Quaternion(newW, newX, newY, newZ);
}
// 计算四元数的点乘
double QuaternionPointMultiplication(Quaternion& q1, Quaternion& q2)
{
double w1 = q1.GetW();
double x1 = q1.GetX();
double y1 = q1.GetY();
double z1 = q1.GetZ();
double w2 = q2.GetW();
double x2 = q2.GetX();
double y2 = q2.GetY();
double z2 = q2.GetZ();
return w1 * w2+ x1* x2+ y1* y2+ z1* z2;
}
// 计算四元数的共轭
Quaternion QuaternionConjugate(Quaternion& q)
{
return Quaternion(q.GetW(), -q.GetX(), -q.GetY(), -q.GetZ());
}
Quaternion PowerOfQuaternion(Quaternion& q, double exponent)
{
if (fabs(q.GetW()) > 0.999999f) {
return q;
}
double alpha1 = acos(q.GetW());
double alpha2 = exponent * alpha1;
double m = sin(alpha2) / sin(alpha1);
double NewW = cos(alpha2);
double NewX = q.GetX() * m;
double NewY = q.GetY() * m;
double NewZ = q.GetZ() * m;
return Quaternion(NewW, NewX, NewY, NewZ);
}
#endif // !__QUATERNION_CLASS_IMPL_DEFINE__
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/63327660/vector-computation.git
git@gitee.com:63327660/vector-computation.git
63327660
vector-computation
VectorComputation
master

搜索帮助