欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

旋转

程序员文章站 2022-03-26 16:08:57
...

3D数学中表示图形旋转有三种方式:

旋转矩阵,欧拉角,四元数

性质                                          矩阵                                     欧拉角                                                 四元数
在坐标系间转换                        能                                          不能                                                    不能
连续或增量旋转          能,但是转换速度慢                        不能                                           能,转换速度快
插值                                        基本不能                能,但可能遇到万向锁问题                     能,且能平滑插值
易用程度                                    难                                            易                                                         难
存储                                         9个数                                     3个数                                                   4个数
对给定方位表达方式是否唯一    是                    不是,对同一方位有无数种表达            不是,对同一方位有两种表达
可能导致非法                        矩阵蠕变               任意三个数都能构成合法的欧拉角    可能会出现误差积累,从而产生非法的四元数

欧拉角会导致 万象锁问题 一般调整xyz层级 可以尽量避免但是不能根本解决

世界坐标系到物体坐标系过程 ----世界坐标系平移到惯性坐标系 惯性坐标系经过旋转到物体坐标系

下面使用旋转矩阵的表示方法来实现惯性坐标系到物体坐标系 以及反过来的转换:

#pragma once
#include "Vector3.h"

class RotationMatrix
{
public:
	float m11, m12, m13;
	float m21, m22, m23;
	float m31, m32, m33;

	void identify(); //单位矩阵

	Vector3 intertialToObject(const Vector3 &v) const;

	Vector3 ObjectTointertial(const Vector3 &v) const;
};

#include "pch.h"
#include "RotationMatrix.h"
void RotationMatrix::identify()
{
	m11 = 1; m12 = 0; m13 = 0;
	m21 = 0; m22 = 1; m23 = 0;
	m31 = 0; m32 = 0; m33 = 1;
}

Vector3 RotationMatrix::intertialToObject(const Vector3 &v) const
{
	return Vector3(v.x*m11 + v.y *m21 + v.z*m31, v.x*m12 + v.y *m22 + v.z*m32, v.x*m13 + v.y*m23 + v.z *m33);
}

//需要乘以旋转矩阵的逆矩阵 保证旋转矩阵是正交矩阵 转置矩阵=逆矩阵
Vector3 RotationMatrix::ObjectTointertial(const Vector3 &v) const
{
	return Vector3(v.x*m11 + v.y*m12 + v.z*m13, v.x*m21 + v.y *m22 + v.z*m23, v.x*m31 + v.y* m32 + v.z *m33);
}
// 3DMath.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include "Vector3.h"
#include "Matrix4X3.h"
#include "MathUtil.h"
#include <math.h>
#include "RotationMatrix.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);
	r = rm.ObjectTointertial(r);
	print_v(r);
	system("pause");
	return 0;
}


项目代码地址
 

相关标签: 3D数学