3D数学 矩阵和线性变换之正交投影

2023-12-20 09:18

本文主要是介绍3D数学 矩阵和线性变换之正交投影,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

矩阵和线性变换之正交投影

1. 具有正交投影效果的矩阵是怎样的?

这里给出一个正交投影在法向量(而且同时又是单位向量)为(x,y,z)平面上的投影矩阵,数学证明暂时不说,详见《3d数学基础 图形与游戏开发》。
投影矩阵

2. 投影矩阵编程示例
void Matrix3X3::setOrthProject(Vector3 &vec)
{assert(fabs(vec*vec) - 1 < 0.0001);m11 = 1 - vec.x*vec.x;m12 = m21 = -vec.x * vec.y;m13 = m31 = -vec.x * vec.z;m22 = 1 - vec.y * vec.y;m23 = m32 = -vec.y * vec.z;m33 = 1 -  vec.z * vec.z;}
3. 投影矩阵编程完整示例代码
//MathUtil.h#pragma once#include <math.h>enum E_Axis{Axis_x,Axis_y,Axis_z};
const float Pi = 3.14159;
//Vector3.h#pragma onceclass Vector3{
public:Vector3();Vector3(float X,float Y,float Z);//变为零向量void Zero();//求负向量Vector3 operator-() const;//求向量大小(长度或模)float Length() const;//标准化该向量void Normal();//向量的加法Vector3 operator+(Vector3 &rhs) const;Vector3& operator+=(Vector3 &rhs);//向量的减法Vector3 operator-(Vector3 &rhs) const;Vector3& operator-=(Vector3 &rhs);//向量乘标量Vector3 operator*(float scalar);//向量乘等于标量Vector3& operator*=(float scalar);//向量除以等于标量Vector3& operator/=(float scalar);//向量除以标量Vector3 operator/(float scalar);//距离公式float Distance(Vector3 &vec) const;//向量点乘float operator*(Vector3 &rhs) const;//向量叉积Vector3 CrossProduct(Vector3& vec) const;public:float x,y,z;};//标量乘向量
Vector3 operator*(float scalar, Vector3& vec);
//Vector3.cpp#include "Vector3.h"
#include <cmath>Vector3::Vector3():x(0.0),y(0.0),z(0.0)
{}Vector3::Vector3(float X,float Y,float Z):x(X),y(Y),z(Z)
{}void Vector3::Zero()
{x = y = z = 0;
}Vector3 Vector3::operator-() const
{return Vector3(-x,-y,-z);
}float Vector3::Length() const
{return sqrt(x*x+y*y+z*z);
}Vector3 Vector3::operator*(float scalar)
{return Vector3(this->x * scalar, this->y * scalar, this->z * scalar);
}Vector3& Vector3::operator*=(float scalar)
{return *this = *this * scalar;
}Vector3& Vector3::operator/=(float scalar)
{return *this = *this / scalar;
}Vector3 operator*(float scalar, Vector3& vec)
{return vec*scalar;
}Vector3 Vector3::operator/(float scalar)
{float temp = 1/ scalar;return *this * temp;
}void Vector3::Normal()
{//计算机计算乘法的速度比除法快float temp = 1 / Length();x *= temp;y *= temp;z *= temp;
}Vector3 Vector3::operator+(Vector3& rhs) const
{return Vector3(x+rhs.x,y+rhs.y,z+rhs.z);
}Vector3& Vector3::operator+=(Vector3& rhs)
{*this = *this + rhs;return *this;
}Vector3 Vector3::operator-(Vector3& rhs) const
{return Vector3(x-rhs.x,y-rhs.y,z-rhs.z);
}Vector3& Vector3::operator-=(Vector3& rhs)
{*this = *this - rhs;return *this;
}float Vector3::Distance(Vector3& vec) const
{return (*this - vec).Length();
}float Vector3::operator*(Vector3& rhs) const
{return this->x * rhs.x + this->y * rhs.y + this->z * rhs.z;
}Vector3 Vector3::CrossProduct(Vector3& vec) const
{return Vector3(this->y * vec.z - this->z * vec.y,this->z * vec.x - this->x * vec.z,this->x * vec.y - this->y * vec.x);
}
//Matrix3X3.h#pragma once
#include "MathUtil.h"
#include "Vector3.h"class Matrix3X3
{
public://矩阵相乘Matrix3X3 operator*(Matrix3X3& rhs);//矩阵乘等矩阵Matrix3X3& operator*=(Matrix3X3& rhs);void setRotate(E_Axis axis,float theta);void setScale(Vector3 &vec);void setOrthProject(Vector3 &vec);
public:float m11,m12,m13;float m21,m22,m23;float m31,m32,m33;
};//向量乘以矩阵
Vector3 operator*(Vector3& vec,Matrix3X3& mat);
//向量乘等矩阵
Vector3& operator*=(Vector3& vec,Matrix3X3& mat);
//Matrix3X3.cpp#include "Matrix3X3.h"
#include <assert.h>Matrix3X3 Matrix3X3::operator*(Matrix3X3& rhs)
{Matrix3X3 tempMat;tempMat.m11 = this->m11 * rhs.m11 + this->m12 * rhs.m21 + this->m13 * rhs.m31;tempMat.m12 = this->m11 * rhs.m12 + this->m12 * rhs.m22 + this->m13 * rhs.m32;tempMat.m13 = this->m11 * rhs.m13 + this->m12 * rhs.m23 + this->m13 * rhs.m33;tempMat.m21 = this->m21 * rhs.m11 + this->m22 * rhs.m21 + this->m23 * rhs.m31;tempMat.m22 = this->m21 * rhs.m12 + this->m22 * rhs.m22 + this->m23 * rhs.m32;tempMat.m23 = this->m21 * rhs.m13 + this->m22 * rhs.m23 + this->m23 * rhs.m33;tempMat.m31 = this->m31 * rhs.m11 + this->m32 * rhs.m21 + this->m33 * rhs.m31;tempMat.m32 = this->m31 * rhs.m12 + this->m32 * rhs.m22 + this->m33 * rhs.m32;tempMat.m33 = this->m31 * rhs.m13 + this->m32 * rhs.m23 + this->m33 * rhs.m33;return tempMat;
}Matrix3X3& Matrix3X3::operator*=(Matrix3X3& rhs)
{*this = *this * rhs;return *this;
}Vector3 operator*(Vector3& vec,Matrix3X3& mat)
{Vector3 tempVec;tempVec.x = vec.x * mat.m11 + vec.y * mat.m21 + vec.z * mat.m31;tempVec.y = vec.x * mat.m12 + vec.y * mat.m22 + vec.z * mat.m32;tempVec.z = vec.x * mat.m13 + vec.y * mat.m23 + vec.z * mat.m33;return tempVec;
}Vector3& operator*=(Vector3& vec,Matrix3X3& mat)
{vec = vec * mat;return vec;
}void Matrix3X3::setRotate(E_Axis axis,float theta)
{float sinValue,cosValue;sinValue = sin(theta);cosValue = cos(theta);switch(axis){case Axis_x:{m11 = 1;    m12 = 0;            m13 = 0;m21 = 0;    m22 = cosValue;     m23 = sinValue;m31 = 0;    m32 = -sinValue;    m33 = cosValue;break;}case Axis_y:{m11 = cosValue; m12 = 0;    m13 = -sinValue;m21 = 0;        m22 = 1;    m23 = 0;m31 = sinValue; m32 = 0;    m33 = cosValue;break;}case Axis_z:{m11 = cosValue;     m12 = sinValue; m13 = 0;m21 = -sinValue;    m22 = cosValue; m23 = 0;m31 = 0;            m32 = 0;        m33 = 1;break;}default:assert(false);}}void Matrix3X3::setScale(Vector3& vec)
{m11 = vec.x;    m12 = 0;        m13 = 0;m21 = 0;        m22 = vec.y;    m23 = 0;m31 = 0;        m32 = 0;        m33 = vec.z;
}void Matrix3X3::setOrthProject(Vector3 &vec)
{assert(fabs(vec*vec) - 1 < 0.0001);m11 = 1 - vec.x*vec.x;m12 = m21 = -vec.x * vec.y;m13 = m31 = -vec.x * vec.z;m22 = 1 - vec.y * vec.y;m23 = m32 = -vec.y * vec.z;m33 = 1 -  vec.z * vec.z;}
//main.cpp#include <iostream>
#include "Vector3.h"
#include "Matrix3X3.h"using namespace std;float ToZero(float num)
{return (abs(num) < 0.0001 ? 0 : num);
}void print_v(Vector3 v)
{cout << "[ " << ToZero(v.x) << ", " << ToZero(v.y) << ", " << ToZero(v.z) << " ]" << endl;cout << endl;
}void print_m(Matrix3X3 m)
{cout << m.m11 << "\t" << m.m12 << "\t" << m.m13 << endl;cout << m.m21 << "\t" << m.m22 << "\t" << m.m23 << endl;cout << m.m31 << "\t" << m.m32 << "\t" << m.m33 << endl;cout << endl;
}int main()
{Vector3 a(10,20,30),b,n(0,0,1);Matrix3X3 M;M.setOrthProject(n);print_m(M);print_v(a);b = a * M;print_v(b);system("pause");return 0;
}
4. 代码运行结果

1 -0 -0
-0 1 -0
-0 -0 0

[ 10, 20, 30 ]

[ 10, 20, 0 ]

这篇关于3D数学 矩阵和线性变换之正交投影的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/515513

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

uva 10025 The ? 1 ? 2 ? ... ? n = k problem(数学)

题意是    ?  1  ?  2  ?  ...  ?  n = k 式子中给k,? 处可以填 + 也可以填 - ,问最小满足条件的n。 e.g k = 12  - 1 + 2 + 3 + 4 + 5 + 6 - 7 = 12 with n = 7。 先给证明,令 S(n) = 1 + 2 + 3 + 4 + 5 + .... + n 暴搜n,搜出当 S(n) >=

uva 11044 Searching for Nessy(小学数学)

题意是给出一个n*m的格子,求出里面有多少个不重合的九宫格。 (rows / 3) * (columns / 3) K.o 代码: #include <stdio.h>int main(){int ncase;scanf("%d", &ncase);while (ncase--){int rows, columns;scanf("%d%d", &rows, &col

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

hdu 4565 推倒公式+矩阵快速幂

题意 求下式的值: Sn=⌈ (a+b√)n⌉%m S_n = \lceil\ (a + \sqrt{b}) ^ n \rceil\% m 其中: 0<a,m<215 0< a, m < 2^{15} 0<b,n<231 0 < b, n < 2^{31} (a−1)2<b<a2 (a-1)^2< b < a^2 解析 令: An=(a+b√)n A_n = (a +

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

hdu 6198 dfs枚举找规律+矩阵乘法

number number number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description We define a sequence  F : ⋅   F0=0,F1=1 ; ⋅   Fn=Fn

MiniGPT-3D, 首个高效的3D点云大语言模型,仅需一张RTX3090显卡,训练一天时间,已开源

项目主页:https://tangyuan96.github.io/minigpt_3d_project_page/ 代码:https://github.com/TangYuan96/MiniGPT-3D 论文:https://arxiv.org/pdf/2405.01413 MiniGPT-3D在多个任务上取得了SoTA,被ACM MM2024接收,只拥有47.8M的可训练参数,在一张RTX

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室