这篇文章主要是讲了矩阵的相乘、旋转、平移、缩放、绕轴翻转、求逆、求转置等运算。
矩阵一共写了两套,一个是给2D元素使用的,一套是给3D对象使用的,这里为了减少篇幅,只写4*4的矩阵的运算,原理和3*3矩阵一直,相比之下比3*3矩阵困难,理解了4*4的运算自然也就理解3*3的运算了。
矩阵相乘: 先说什么是行什么是列,横着的就是行,竖着的就是列。可以看一下图片1.1,别弄过了。不然一会计算一起全都弄饭了算起来就全错。 计算说的简单点就是每一行乘上每一列,然后把算出来的结果保存到一个新的矩阵对应的n行m列中。其实这个可以从结果出发反着看比较容易能看懂,比如说我要计算mat[0][0]这个mat的第0行第0列怎么算? 就是让
a[0][0]*b[0][0]+
a[0][1]*b[1][0]+
a[0][2]*b[2][0]+
a[0][3]*b[3][0] 得到的结果就是mat[0][0]想要的结果
程序1.1
Matrix3D Matrix3D::operator*(Matrix3D &mat)
{
Matrix3D temp;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
temp.m[i][j] =
m[i][0] * mat.m[0][j] +
m[i][1] * mat.m[1][j] +
m[i][2] * mat.m[2][j] +
m[i][3] * mat.m[3][j];
}
}
return temp;
}
图1.1
矩阵绕X轴旋转:直接套用图1.2 公式就可以:
图1.2
但是大家一定会有疑问,公式里不是这样的呀?为什么行列正好反过来了,这是因为OpenGL虽然用的是行矩阵,但是是列主序。相当于存空间信息的时候要以列主序的方式去存。
下文有具体解释什么是行主序,什么是列主序列,这里就不展开讲这个了。
https://www.jianshu.com/p/bfc8327eaad3https://www.jianshu.com/p/bfc8327eaad3
程序1.2
void Matrix3D::XRotate(float angle)
{
m[1][1] =cos(GL_PI/180*angle) ; m[1][2] =sin(GL_PI/180*angle) ;
m[2][1] =-sin(GL_PI/180*angle); m[2][2] =cos(GL_PI/180*angle) ;
}
矩阵绕Y轴旋转:同上直接套图1.3公式,空间信息存成列主序列:
图1.3
程序1.3
void Matrix3D::YRotate(float angle)
{
m[0][0] =cos(GL_PI/180*angle); m[0][2] =-sin(GL_PI/180*angle) ;
m[2][0] = sin(GL_PI / 180 * angle); m[2][2] =cos(GL_PI/180*angle);
}
矩阵绕Z轴旋转:同上直接套图1.4公式,空间信息存成列主序列:
图1.4
程序1.4
void Matrix3D::ZRotate(float angle)
{
m[0][0] = cos(GL_PI / 180 * angle); m[0][1] = sin(GL_PI / 180 * angle);
m[1][0] = -sin(GL_PI / 180 * angle);m[1][1] = cos(GL_PI / 180 * angle);
}
矩阵平移:直接往矩阵的设置三个空间信息就可以,这个没难度。
程序1.5
void Matrix3D::Translate(float x, float y, float z)
{
m[3][0] = x;
m[3][1] = y;
m[3][2] = z;
}
矩阵缩放:直接往矩阵的设置三个空间信息就可以,这个没难度。
程序1.6
void Matrix3D::Scale(float x, float y, float z)
{
m[0][0] *= x;
m[1][1] *= y;
m[2][2] *= z;
}
矩阵绕XYZ翻转:我们使用的方法是让x,y,z的旋转角度直接*-1 空间就翻转过来了。
程序1.7
void Matrix3D::FlipX()
{
m[1][1] *=-1;
}
void Matrix3D::FlipY()
{
m[0][0] *= -1;
}
void Matrix3D::FlipZ()
{
m[3][3] *= -1;
}
代码太多了,还有一些复杂的运算,到时候有时间了再把矩阵求逆和矩阵转置讲一下,还有把摄像机的俯仰角算成矩阵的讲一下。剩下的都是些简单的运算就自己研究下把。先把代码贴出来。
GLMath.h
#pragma once
#define PI 3.141596
class Vector2
{
private:
public:
int PointNum=0;
float x, y;
Vector2(float x, float y) { this->x = x;this->y = y; }
void setXy(float x, float y) { this->x = x; this->y = y; }
Vector2 &operator /= (float n)
{
this->x /= n;
this->y /= n;
return *this;
}
Vector2& operator *= (float n)
{
this->x *= n;
this->y *= n;
return *this;
}
Vector2& operator += (Vector2 &vec)
{
this->x += vec.x;
this->y += vec.y;
return *this;
}
Vector2& operator -= (Vector2 &vec)
{
this->x -= vec.x;
this->y -= vec.y;
return *this;
}
Vector2 operator* (float n)
{
Vector2 temp = *this;
temp.x *= n;
temp.y *= n;
return temp;
}
Vector2 operator/ (float n)
{
Vector2 temp = *this;
temp.x /= n;
temp.y /= n;
return temp;
}
Vector2 operator+ (Vector2 vec)
{
Vector2 temp = *this;
temp.x += vec.x;
temp.y += vec.y;
return temp;
}
Vector2 operator- (Vector2 vec)
{
Vector2 temp = *this;
temp.x -= vec.x;
temp.y -= vec.y;
return temp;
}
void normalize()
{
float len = sqrt(x*x + y*y);
x /= len;
y /= len;
}
Vector2 Normalize()
{
Vector2 temp = *this;
float len = sqrt(temp.x*temp.x + temp.y*temp.y);//单位化
temp.x /= len;
temp.y /= len;
return temp;
}
float length()
{
return sqrt(x*x + y*y);
}
float length2q()
{
return x*x + y*y;
}
float dot(Vector2 &vec)//点乘
{
return x*vec.x +y*vec.y;
}
Vector2 projection(Vector2&vec)//投影
{
Vector2 temp;
temp = vec.Normalize();
Vector2 temp1;
temp1 = temp*dot(temp);
return temp1;
}
Vector2 ortho()//正交
{
Vector2 temp=*this;
temp.x = y;
temp.y = -x;
return temp;
}
float Cross(Vector2 &vec)//叉乘
{
Vector2 a = *this;
return a.x * vec.x - a.y * vec.y;
}
Vector2::Vector2() { x = 0, y = 0; }
Vector2::~Vector2() {}
};
class Vector3D
{
public:
float x, y, z;
Vector3D(float x, float y, float z) {this->x = x; this->y = y;this->z = z;}
void setXYZ(float x, float y, float z){this->x = x; this->y = y; this->z = z;}
void normalize()
{
float len = sqrt(x*x + y*y+z*z);
x /= len;
y /= len;
z /= len;
}
Vector3D Normalize()
{
Vector3D temp=*this;
float len = sqrt(x*x + y*y + z*z);
temp.x /= len;
temp.y /= len;
temp.z /= len;
return temp;
}
float length()
{
return sqrt(x*x + y*y+z*z);
}
float length2q()
{
return x*x + y*y + z*z;
}
float dot(Vector3D &vec)//点乘
{
return x*vec.x +y*vec.y +z*vec.z;
}
Vector3D &operator /= (float n)
{
this->x /= n;
this->y /= n;
this->z /= n;
return *this;
}
Vector3D& operator *= (float n)
{
this->x *= n;
this->y *= n;
this->z *= n;
return *this;
}
Vector3D& operator += (Vector3D &vec)
{
this->x += vec.x;
this->y += vec.y;
this->z += vec.z;
return *this;
}
Vector3D& operator -= (Vector3D &vec)
{
this->x -= vec.x;
this->y -= vec.y;
this->z -= vec.z;
return *this;
}
Vector3D operator* (float n)
{
Vector3D temp = *this;
temp.x *= n;
temp.y *= n;
temp.z *= n;
return temp;
}
Vector3D operator/ (float n)
{
Vector3D temp = *this;
temp.x /= n;
temp.y /= n;
temp.z /= n;
return temp;
}
Vector3D operator+ (Vector3D vec)
{
Vector3D temp = *this;
temp.x += vec.x;
temp.y += vec.y;
temp.z += vec.z;
return temp;
}
Vector3D operator+(float n)
{
Vector3D temp = *this;
temp.x += n;
temp.y += n;
temp.z += n;
return temp;
}
Vector3D operator-()
{
Vector3D vec ;
Vector3D temp = *this;
vec.x =-temp.x;
vec.y=-temp.y;
vec.z = -temp.z;
return vec;
}
Vector3D operator- (Vector3D vec)
{
Vector3D temp = *this;
temp.x -= vec.x;
temp.y -= vec.y;
temp.z -= vec.z;
return temp;
}
bool operator == (Vector3D &vec)
{
if (this->x == vec.x&&this->y == vec.y&&this->z==vec.z)
return true;
else
return false;
}
bool operator >= (Vector3D &vec)
{
if (this->x >=vec.x&&this->y>=vec.y&&this->z>=vec.z)
return true;
else
return false;
}
bool operator x y zx y z >=vec.z)
return true;
else
return false;
}
int operator || (Vector3D &vec) //判断距离差的是正还是负
{
if (vec.x > 0 && vec.z > 0)
return 1;
else if(vec.x < 0 && vec.z < 0)
return -1;
else
return 0;
}
Vector3D projection(Vector3D&vec)//投影
{
Vector3D temp;
temp = vec.Normalize();
Vector3D temp1;
temp1 = temp*dot(temp);
return temp1;
}
Vector3D cross(Vector3D &v)
{
Vector3D temp;
temp.x = y * v.z - z * v.y;
temp.y = z * v.x - x * v.z;
temp.z = x * v.y - y * v.x;
return temp;
}
Vector3D::Vector3D() {}
Vector3D::~Vector3D() {}
};
Vector3D operator*(Vector3D vc1, Vector3D vc2);
struct Vector4D
{
public:
float x, y, z, w;
Vector4D(float x, float y, float z, float w)
{
this->x = x;this->y = y;
this->z = z;this->w = w;
}
void setXYZW(float x, float y, float z, float w)
{
this->x = x;this->y = y;
this->z = z;this->w = w;
}
Vector4D() {}
~Vector4D() {}
};
class Matrix3
{
public:
union {
struct {
float _11, _21, _31,_41; //_11,_12,_13,_14 |
float _12, _22, _32,_42; //_21,_22,_23,_24 |转置后的矩阵
float _13, _23, _33,_43; //_31,_32,_33,_34 |
float _14, _24, _34,_44; //_41,_42,_43,_44 |
}; //openGL用的是行矩阵,但是是列的算法
float mat[16];
float m[4][4];
};
Matrix3()
{
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
if (i == j)
m[i][j] = 1;
else
m[i][j] = 0;
}
Matrix3 operator*(Matrix3& mat);//矩阵*矩阵
Matrix3 &operator*=(const Matrix3 &mat); //矩阵与矩阵
Vector2 operator*(const Vector2 &v); //矩阵与向量
Matrix3 &Rotate(float angle); //绕Z轴旋转
Matrix3 &Translate(float x, float y,float z); //平移
Matrix3 &Translate(float x, float y);
Matrix3 &Scale(float x, float y); //比例
Matrix3 &FlipX(); //x轴翻转
Matrix3 &FlipY(); //y轴翻转
void Identity()//矩阵单位化
{
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
}
~Matrix3();
};
Matrix3 operator*(const Matrix3 &mat1, const Matrix3 &mat2); //矩阵与矩阵
Vector2 operator*(const Vector2 &v, const Matrix3 &mat); //矩阵与向量
Matrix3 &Rotate(Matrix3 &mat, float angle); //绕Z轴旋转
Matrix3 &Translate(Matrix3 &mat, float x, float y,float z); //平移
Matrix3 &Translate(Matrix3 &mat, float x, float y);
Matrix3 &Scale(Matrix3 &mat, float x, float y); //比例
Matrix3 &FlipX(Matrix3 &mat); //x轴翻转
Matrix3 &FlipY(Matrix3 &mat); //y轴翻转
void Vec2TransformCoord(Vector2 &newVec, Vector2 &cornerPoint, Matrix3 &world_matrix);
//************3D*******************
class Matrix3D
{
public:
union {
struct {
float _11, _21, _31, _41; //_11,_12,_13,_14 |
float _12, _22, _32, _42; //_21,_22,_23,_24 |转置后的矩阵
float _13, _23, _33, _43; //_31,_32,_33,_34 |
float _14, _24, _34, _44; //_41,_42,_43,_44 |
}; //openGL用的是行矩阵,但是是列的算法
float mat[16];
float m[4][4];
};
Matrix3D()
{
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
}
Matrix3D operator*(Matrix3D &mat);//矩阵*矩阵
Matrix3D &operator*=(Matrix3D &mat); //矩阵与矩阵
Vector3D operator*(Vector3D &v); //矩阵与向量
Matrix3D MatrixInverse(Matrix3D &m); //逆矩阵
void XRotate(float angle); //绕X轴旋转
void YRotate(float angle); //绕Y轴旋转
void ZRotate(float angle); //绕Z轴旋转
void Translate(float x, float y, float z);//平移
void Scale(float x, float y, float z); //比例
void FlipX(); //x轴翻转
void FlipY(); //y轴翻转
void FlipZ(); //z翻转
void Identity()//矩阵单位化
{
m[0][0] = 1; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
m[1][0] = 0; m[1][1] = 1; m[1][2] = 0; m[1][3] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 1; m[2][3] = 0;
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
}
~Matrix3D(){};
};
Matrix3D MatrixRotationAxis(Vector3D &axis, float angle);
Matrix3D MatrixRotationAxisRad(Vector3D &axis, float radian);
Vector3D Vec3TransformCoord(Matrix3D &m, Vector3D &v);
Vector2 Vec3TransformCoord(Matrix3D &m, Vector2 &v);
Vector3D Vec3TransformNormal(Matrix3D &m, Vector3D &v);
Matrix3D YRotate(float angle); //绕Y轴旋转(全局函数)
Matrix3D MatrixTranspose(Matrix3D &m); //转置矩阵
Matrix3D MatrixInverse(Matrix3D &m); //逆矩阵
Matrix3D FromToRotation(Vector3D from, Vector3D to);
Matrix3D &MatrixRotationYawPitchRoll(float Yaw, float Pitch, float Roll);
Matrix3D &MatrixRotationY(float angle);
struct sColor
{
public:
union {
struct {
float r, g, b, a;
};
float color[4];//r,g,b,a的分量
};
sColor()//默认颜色
{
color[0] = 1.0f;
color[1] = 1.0f;
color[2] = 1.0f;
color[3] = 1.0f;
}
sColor(float r, float g, float b, float a)//外部初始化颜色
{
color[0] = r;
color[1] = g;
color[2] = b;
color[3] = a;
}
float getR() { return color[0]; }
float getG() { return color[1]; }
float getB() { return color[2]; }
float getA() { return color[3]; }
void operator=(DWORD col)
{
color[0] = (col >> 16 & 0xff)*0.00392156862;
color[1] = (col >> 8 & 0xff)*0.00392156862;
color[2] = (col & 0xff)*0.00392156862;
color[3] = (col >> 24)*0.00392156862;
}
void operator+=(float z)
{
r +=z; g +=z; b +=z;
}
bool operator==(float z)
{
if (r == z&&g == z&&b == z)
return true;
return false;
}
bool operator>=(float z)
{
if (r>=z&&g>=z&&b>=z)
return true;
return false;
}
bool operator
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?