旋转

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;
}


项目代码地址
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值