空间坐标变换可看作坐标点乘以一个齐次矩阵,其中,齐次矩阵可表示为:
其中:
①区域的3×3矩阵产生三维图形的比例、对称、旋转、错切等基本变换;
②区域产生图形的透视变换;
③区域产生沿X、Y、Z三个轴的平移变换;
④区域产生图形的总比例变换。
平移变换
平移变换可表示为:
[
x
y
z
1
]
[
1
0
0
0
0
1
0
0
0
0
1
0
l
m
n
1
]
=
[
x
+
l
y
+
m
z
+
n
1
]
\begin{gathered} \quad \begin{bmatrix} x & y & z & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ l & m & n & 1 \end{bmatrix} = \begin{bmatrix} x+l & y+m & z+n & 1 \end{bmatrix} \end{gathered}
[xyz1]
100l010m001n0001
=[x+ly+mz+n1]
绕X轴旋转
空间立体绕X轴旋转某个角度,实体上个点的X坐标不变,只有Y、Z坐标改变,可表示为:
[
x
y
z
1
]
[
1
0
0
0
0
c
o
s
(
θ
)
s
i
n
(
θ
)
0
0
−
s
i
n
(
θ
)
c
o
s
(
θ
)
0
0
0
0
1
]
=
[
x
y
×
c
o
s
(
θ
)
−
z
×
s
i
n
(
θ
)
y
×
s
i
n
(
θ
)
+
z
×
c
o
s
(
θ
)
1
]
\begin{gathered} \quad \begin{bmatrix} x & y & z & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos(\theta) & sin(\theta) & 0 \\ 0 & -sin(\theta) & cos(\theta) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} x & y \times cos(\theta) - z \times sin(\theta) & y \times sin(\theta) + z \times cos(\theta) & 1 \end{bmatrix} \end{gathered}
[xyz1]
10000cos(θ)−sin(θ)00sin(θ)cos(θ)00001
=[xy×cos(θ)−z×sin(θ)y×sin(θ)+z×cos(θ)1]
绕Y轴旋转
空间立体绕Y轴旋转某个角度,实体上个点的Y坐标不变,只有X、Z坐标改变,可表示为:
[
x
y
z
1
]
[
c
o
s
(
θ
)
0
−
s
i
n
(
θ
)
0
0
1
0
0
s
i
n
(
θ
)
0
c
o
s
(
θ
)
0
0
0
0
1
]
=
[
x
×
c
o
s
(
θ
)
+
z
×
s
i
n
(
θ
)
y
−
x
×
s
i
n
(
θ
)
+
z
×
c
o
s
(
θ
)
1
]
\begin{gathered} \quad \begin{bmatrix} x & y & z & 1 \end{bmatrix} \begin{bmatrix} cos(\theta) & 0 & -sin(\theta) & 0 \\ 0 & 1 & 0 & 0 \\ sin(\theta) & 0 & cos(\theta) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} x \times cos(\theta) + z \times sin(\theta) & y & -x \times sin(\theta) + z \times cos(\theta) & 1 \end{bmatrix} \end{gathered}
[xyz1]
cos(θ)0sin(θ)00100−sin(θ)0cos(θ)00001
=[x×cos(θ)+z×sin(θ)y−x×sin(θ)+z×cos(θ)1]
绕Z轴旋转
空间立体绕Z轴旋转某个角度,实体上个点的Z坐标不变,只有X、Y坐标改变,可表示为:
[
x
y
z
1
]
[
c
o
s
(
θ
)
s
i
n
(
θ
)
0
0
−
s
i
n
(
θ
)
c
o
s
(
θ
)
0
0
0
0
1
0
0
0
0
1
]
=
[
x
×
c
o
s
(
θ
)
−
y
×
s
i
n
(
θ
)
x
×
s
i
n
(
θ
)
+
y
×
c
o
s
(
θ
)
z
1
]
\begin{gathered} \quad \begin{bmatrix} x & y & z & 1 \end{bmatrix} \begin{bmatrix} cos(\theta) & sin(\theta) & 0 & 0 \\ -sin(\theta) & cos(\theta) & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} = \begin{bmatrix} x \times cos(\theta) - y \times sin(\theta) & x \times sin(\theta) + y \times cos(\theta) & z & 1 \end{bmatrix} \end{gathered}
[xyz1]
cos(θ)−sin(θ)00sin(θ)cos(θ)0000100001
=[x×cos(θ)−y×sin(θ)x×sin(θ)+y×cos(θ)z1]
python代码
绕X轴旋转
def rotate_X(x, y, z, alpha):
alpha = alpha * (np.pi / 180)
x_r = x
y_r = np.cos(alpha) * y - np.sin(alpha) * z
z_r = np.sin(alpha) * y + np.cos(alpha) * z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
绕Y轴旋转
def rotate_Y(x, y, z, beta):
beta = beta * (np.pi / 180)
x_r = np.cos(beta) * x + np.sin(beta) * z
y_r = y
z_r = -np.sin(beta) * x + np.cos(beta) * z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
绕Z轴旋转
def rotate_Z(x, y, z, gamma):
gamma = gamma * (np.pi / 180)
x_r = np.cos(gamma) * x - np.sin(gamma) * y
y_r = np.sin(gamma) * x + np.cos(gamma) * y
z_r = z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
为了更直观的显示,使用matplotlib将旋转前后的点显示出来
def plot_3D(x, y, z, x1, y1, z1):
a, b, c = [0, x, x1], \
[0, y, y1], \
[0, z, z1]
d, e, f, g, h, i = [0], [0], [0], [0], [0], [0]
d.append(x)
e.append(y)
f.append(z)
g.append(x1)
h.append(y1)
i.append(z1)
dd, ee, ff = [x, 0, 0, x, x, x], \
[y, y, 0, 0, y, y], \
[z, z, z, z, z, 0]
dd1, ee1, ff1 = [0, x, x, 0, 0, 0], \
[0, 0, y, y, 0, 0], \
[0, 0, 0, 0, 0, z]
dd2, ee2, ff2 = [x, x], \
[0, 0], \
[0, z]
dd3, ee3, ff3 = [0, 0], \
[y, y], \
[0, z]
gg, hh, ii = [x1, 0, 0, x1, x1, x1], \
[y1, y1, 0, 0, y1, y1], \
[z1, z1, z1, z1, z1, 0]
gg1, hh1, ii1 = [0, x1, x1, 0, 0, 0], \
[0, 0, y1, y1, 0, 0], \
[0, 0, 0, 0, 0, z1]
gg2, hh2, ii2 = [x1, x1], \
[0, 0], \
[0, z1]
gg3, hh3, ii3 = [0, 0], \
[y1, y1], \
[0, z1]
ax = plt.axes(projection='3d') # 创建一个三维的绘图工程
ax.scatter3D(a, b, c, c='r') # 绘制数据点 c: 'r'红色,'y'黄色,等颜色
ax.text(x, y, z, (x, y, z), c='r') # 显示点坐标
ax.text(x1, y1, z1, (x1, y1, z1), c='r')
ax.plot3D(d, e, f, c='b')
ax.plot3D(dd, ee, ff, c='b', linestyle='--')
ax.plot3D(dd1, ee1, ff1, c='b', linestyle='--')
ax.plot3D(dd2, ee2, ff2, c='b', linestyle='--')
ax.plot3D(dd3, ee3, ff3, c='b', linestyle='--')
ax.plot3D(g, h, i, c='y')
ax.plot3D(gg, hh, ii, c='y', linestyle='--')
ax.plot3D(gg1, hh1, ii1, c='y', linestyle='--')
ax.plot3D(gg2, hh2, ii2, c='y', linestyle='--')
ax.plot3D(gg3, hh3, ii3, c='y', linestyle='--')
ax.set_xlabel('X') # 设置x坐标轴
ax.set_ylabel('Y') # 设置y坐标轴
ax.set_zlabel('Z') # 设置z坐标轴
ax.grid(False) # 关闭网格
plt.show()
现设初始点为P0(0,0,6),P0先绕X轴旋转6°,再绕Y轴旋转45°得到P2
完整代码:文章来源:https://www.toymoban.com/news/detail-645235.html
import numpy as np
import matplotlib.pyplot as plt
# 1、绕Z周旋转gamma角
def rotate_Z(x, y, z, gamma):
gamma = gamma * (np.pi / 180)
x_r = np.cos(gamma) * x - np.sin(gamma) * y
y_r = np.sin(gamma) * x + np.cos(gamma) * y
z_r = z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
# 2、绕Y轴旋转beta角
def rotate_Y(x, y, z, beta):
beta = beta * (np.pi / 180)
x_r = np.cos(beta) * x + np.sin(beta) * z
y_r = y
z_r = -np.sin(beta) * x + np.cos(beta) * z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
# 3、绕X轴旋转alpha角
def rotate_X(x, y, z, alpha):
alpha = alpha * (np.pi / 180)
x_r = x
y_r = np.cos(alpha) * y - np.sin(alpha) * z
z_r = np.sin(alpha) * y + np.cos(alpha) * z
return round(x_r, 4), round(y_r, 4), round(z_r, 4)
def plot_3D(x, y, z, x1, y1, z1):
a, b, c = [0, x, x1], \
[0, y, y1], \
[0, z, z1]
d, e, f, g, h, i = [0], [0], [0], [0], [0], [0]
d.append(x)
e.append(y)
f.append(z)
g.append(x1)
h.append(y1)
i.append(z1)
dd, ee, ff = [x, 0, 0, x, x, x], \
[y, y, 0, 0, y, y], \
[z, z, z, z, z, 0]
dd1, ee1, ff1 = [0, x, x, 0, 0, 0], \
[0, 0, y, y, 0, 0], \
[0, 0, 0, 0, 0, z]
dd2, ee2, ff2 = [x, x], \
[0, 0], \
[0, z]
dd3, ee3, ff3 = [0, 0], \
[y, y], \
[0, z]
gg, hh, ii = [x1, 0, 0, x1, x1, x1], \
[y1, y1, 0, 0, y1, y1], \
[z1, z1, z1, z1, z1, 0]
gg1, hh1, ii1 = [0, x1, x1, 0, 0, 0], \
[0, 0, y1, y1, 0, 0], \
[0, 0, 0, 0, 0, z1]
gg2, hh2, ii2 = [x1, x1], \
[0, 0], \
[0, z1]
gg3, hh3, ii3 = [0, 0], \
[y1, y1], \
[0, z1]
ax = plt.axes(projection='3d') # 创建一个三维的绘图工程
ax.scatter3D(a, b, c, c='r') # 绘制数据点 c: 'r'红色,'y'黄色,等颜色
ax.text(x, y, z, (x, y, z), c='r') # 显示点坐标
ax.text(x1, y1, z1, (x1, y1, z1), c='r')
ax.plot3D(d, e, f, c='b')
ax.plot3D(dd, ee, ff, c='b', linestyle='--')
ax.plot3D(dd1, ee1, ff1, c='b', linestyle='--')
ax.plot3D(dd2, ee2, ff2, c='b', linestyle='--')
ax.plot3D(dd3, ee3, ff3, c='b', linestyle='--')
ax.plot3D(g, h, i, c='y')
ax.plot3D(gg, hh, ii, c='y', linestyle='--')
ax.plot3D(gg1, hh1, ii1, c='y', linestyle='--')
ax.plot3D(gg2, hh2, ii2, c='y', linestyle='--')
ax.plot3D(gg3, hh3, ii3, c='y', linestyle='--')
ax.set_xlabel('X') # 设置x坐标轴
ax.set_ylabel('Y') # 设置y坐标轴
ax.set_zlabel('Z') # 设置z坐标轴
ax.grid(False) # 关闭网格
plt.show()
if __name__ == '__main__':
x, y, z = 0, 0, 6
x1, y1, z1 = rotate_X(x, y, z, 6)
x2, y2, z2 = rotate_Y(x1, y1, z1, 45)
print(x2, y2, z2)
plot_3D(x, y, z, x2, y2, z2)
C++代码:文章来源地址https://www.toymoban.com/news/detail-645235.html
#include<iostream>
#include <iomanip>
#include<math.h>
#define PAI acos(-1)
using namespace std;
void rotate_Z(double x, double y, double z, double theta);
void rotate_Y(double x, double y, double z, double theta);
void rotate_X(double x, double y, double z, double theta);
int main()
{
double x = 0;
double y = 0;
double z = 6;
rotate_Z(x,y,z,45);
return 0;
}
void rotate_Z(double x, double y, double z, double theta)
{
double theta_r = theta * (PAI/180);
double x_r = cos(theta_r) * x - sin(theta_r) * y;
double y_r = sin(theta_r) * x + sin(theta_r) * y;
double z_r = z;
cout.setf(ios::fixed);
cout << "X:" << setprecision(4) << x_r << endl;
cout << "Y:" << setprecision(4) << y_r << endl;
cout << "Z:" << setprecision(4) << z_r << endl;
}
void rotate_Y(double x, double y, double z, double theta)
{
double theta_r = theta * (PAI/180);
double x_r = cos(theta_r) * x + sin(theta_r) * z;
double y_r = y;
double z_r = -sin(theta_r) * x + cos(theta_r) * z;
cout.setf(ios::fixed);
cout << "X:" << setprecision(4) << x_r << endl;
cout << "Y:" << setprecision(4) << y_r << endl;
cout << "Z:" << setprecision(4) << z_r << endl;
}
void rotate_X(double x, double y, double z, double theta)
{
double theta_r = theta * (PAI/180);
double x_r = x;
double y_r = cos(theta_r) * y - sin(theta_r) * z;
double z_r = sin(theta_r) * y + cos(theta_r) * z;
cout.setf(ios::fixed);
cout << "X:" << setprecision(4) << x_r << endl;
cout << "Y:" << setprecision(4) << y_r << endl;
cout << "Z:" << setprecision(4) << z_r << endl;
}
到了这里,关于空间坐标变换(Python&C++实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!