旋转-欧拉角
程序员文章站
2022-03-26 16:09:21
...
矩阵表示旋转赋值操作比较麻烦,使用欧拉角代替矩阵表示顶点旋转
1.欧拉角转变矩阵
2.矩阵转欧拉角
3.万向死锁避免以及角度限制
#pragma once
#include "RotationMatrix.h"
#include "Matrix4X3.h"
class EulerAngles
{
public :
float heading;
float pitch;
float bank;
EulerAngles(){}
EulerAngles(float h,float p,float b):heading(h),pitch(p),bank(b){}
void FromObjectToWorldMatrix(const Matrix4X3 &m);
void FromWorldToObjectMatrix(const Matrix4X3 &m);
void FromRotationMatrix(const RotationMatrix &r);
void canonize(); // 三个角度限制 一定程度避免万向死锁问题
};
#include "pch.h"
#include "MathUtil.h"
#include "EulerAngles.h"
void EulerAngles::FromObjectToWorldMatrix(const Matrix4X3 &m)
{
//pitch正负九十度发生万向死锁
float sp = -m.m32;
if (fabs(sp) > 0.999999f) //检测万像死锁
{
pitch = PiOver2 * sp;
bank = 0.0f;
heading = atan2(-m.m23, m.m11);
}
else
{
heading = atan2(m.m31, m.m33);
pitch = asin(sp);
bank = atan2(m.m12, m.m22);
}
}
void EulerAngles::FromWorldToObjectMatrix(const Matrix4X3 &m)
{
//pitch正负九十度发生万向死锁
float sp = -m.m23;
if (fabs(sp) > 0.999999f) //检测万像死锁
{
pitch = PiOver2 * sp;
bank = 0.0f;
heading = atan2(-m.m31, m.m11);
}
else
{
heading = atan2(m.m13, m.m33);
pitch = asin(sp);
bank = atan2(m.m21, m.m22);
}
}
void EulerAngles::FromRotationMatrix(const RotationMatrix &m)
{
//pitch正负九十度发生万向死锁
float sp = -m.m23;
if (fabs(sp) > 0.999999f) //检测万像死锁
{
pitch = PiOver2 * sp;
bank = 0.0f;
heading = atan2(-m.m31, m.m11);
}
else
{
heading = atan2(m.m13, m.m33);
pitch = asin(sp);
bank = atan2(m.m21, m.m22);
}
}
void EulerAngles::canonize()
{
pitch = wrapPi(pitch);
if (pitch < -k1Over2Pi)
{
pitch = -PI - pitch;
heading += PI;
bank += PI;
}
else if (pitch > PiOver2)
{
pitch = PI - pitch;
heading += PI;
bank += PI;
}
if (fabs(pitch) > PiOver2 - 1e-4)
{
heading += bank;
bank = 0.0f;
}
else
{
bank = wrapPi(bank);
}
heading = wrapPi(heading);
}
#include "pch.h"
#include "MathUtil.h"
#include <math.h>
float wrapPi(float theta)
{
theta = theta + PI;
theta -= floor(theta*k1Over2Pi)*Pi2;
theta -= PI;
return theta;
}
// 3DMath.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include "Vector3.h"
#include "Matrix4X3.h"
#include "MathUtil.h"
#include <math.h>
#include "RotationMatrix.h"
#include "EulerAngles.h"
using namespace std;
float to_zero(float n)
{
if (abs(n) < 0.0001)
{
return 0;
}
return n;
}
void print_v(Vector3 &v)
{
cout << "[" << to_zero(v.x) << "," << to_zero(v.y) << "," << to_zero(v.z) << "]" << endl;
}
void print_m(Matrix4X3 &m)
{
cout << to_zero(m.m11) << "\t" << to_zero(m.m12) << "\t" << to_zero(m.m13) << endl;
cout << to_zero(m.m21) << "\t" << to_zero(m.m22) << "\t" << to_zero(m.m23) << endl;
cout << to_zero(m.m31) << "\t" << to_zero(m.m32) << "\t" << to_zero(m.m33) << endl;
}
int main()
{
cout << "Hello Rotation Matrix !\n";
RotationMatrix rm;
rm.m11 = 0.866f; rm.m12 = 0; rm.m13 =-0.5f;
rm.m21 = 0.0f; rm.m22 = 1.0f; rm.m23 = 0.0f;
rm.m31 = 0.5f; rm.m32 = 0.0f; rm.m33 = 0.866f;
Vector3 v(10, 20, 30);
Vector3 r;
r = rm.intertialToObject(v);
print_v(r);
RotationMatrix erm;
EulerAngles ea(30*PI/180,0,0);
erm.Setup(ea);
Vector3 er;
er = erm.intertialToObject(v);
print_v(er);
system("pause");
return 0;
}
上一篇: 3D数学 学习笔记(4) 几何图元