diff --git a/perspective/perspective.md b/perspective/perspective.md
new file mode 100644
index 0000000..789c40b
--- /dev/null
+++ b/perspective/perspective.md
@@ -0,0 +1,138 @@
+# 透视投影
+
+# 总体思路:
+ 1.先透视变换 $P_{透视}$
+ 2.再投影 $P_{投影}$
+ 3.最终的变换矩阵 $T = P_{透视}P_{投影}$
+ 4.定点序列 $V_{new}=V_{origin}T $
+# 1. 透视
+
+## 1.1 一点透视
+
+### 步骤:
+
+ (1) 进行平移变换,将三维形体平移到适当位 置l、m、n;
+
+ (2)进行透视变换;
+
+ (3)进行投影变换,向xoy平面作正投影变换,将结果变换到xoy平面上。
+
+ 变换矩阵:
+
+
+$P_{透视}=\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&1&0\\L&M&N&1\end{bmatrix}$
+
+
+## 1.2 两点透视
+
+### 步骤:
+
+ (1)先将三维形体平移到适当位置,使视点有一定 高度,且使形体的主要表面不会积聚成线;
+
+ (2)将形体绕y轴旋转一个φ⻆(φ<90 ̊),方向满足 右手定则;
+
+ (3)进行透视变换;
+
+ (4)最后向xoy面作正投影,即得二点透视图。
+
+ 变换矩阵:
+
+
+$P_{透视}=\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&1&0\\L&M&N&1\end{bmatrix}\begin{bmatrix} cos(φ)&0&sin(φ)&0\\0&1&0&0\\-sin(φ)&0&cos(φ)&0\\0&0&0&1\end{bmatrix}$
+
+
+## 1.3 三点透视
+
+### 步骤:
+
+ (1)首先将三维形体平移到适当位置;;
+
+ (2)将形体进行透视变换;
+
+ (3)然后使形体先绕y轴旋转φ⻆;
+
+ (4)再绕x轴旋转θ⻆;
+
+ (5)将变形且旋转后的形体向xoy面作正投影。
+
+ 变换矩阵:
+
+
+$P_{透视}=\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&1&0\\L&M&N&1\end{bmatrix}\begin{bmatrix} cosφ&0&sinφ&0\\0&1&0&0\\-sinφ&0&cosφ&0\\0&0&0&1\end{bmatrix}\begin{bmatrix} 1&0&0&0\\0&cosθ&sinθ&0\\0&-sinθ&cosθ&0\\0&0&0&1\end{bmatrix}$
+
+
+# 2 投影
+
+
+
+
+
+ 首先考虑这样一种最简单的情况,假设投影中心为坐标为 $(0, 0, -d)$ ,空间中任意一点$P(x,y,z)$,投影到$xOy$平面一点$P^’(x^’,y^’,0)$,由相似三角形易证:
+
+
+$x^’= \frac{d}{d+z}*x$
+
+$y^’= \frac{d}{d+z}*y$
+
+
+ 易得,$P^’$的齐次坐标位为
+
+
+
+ $[\frac{d}{d+z}*x,\frac{d}{d+z}*y,0,1]$
+
+
+ 即
+
+
+
+$[x,y,0,\frac{1+z}d]$
+
+ 因此,投投影矩阵为
+
+
+
+$P_{投影}=\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&0& \frac{1}{d} \\ 0&0&0&1 \\ \end{bmatrix}$
+
+ 推广:空间任意一点作为投影中心,投影到xOy平面
+
+
+
+$P_{投影}=\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&1&0 \\ -x_0&-y_0&0&1 \\ \end{bmatrix}\begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&0& \frac{1}{d} \\ 0&0&0&1 \\ \end{bmatrix} \begin{bmatrix} 1&0&0&0\\0&1&0&0\\0&0&1&0 \\ x_0&y_0&0&1\\ \end{bmatrix}= \begin{bmatrix} 1&0&0&0\\0&1&0&0\\\frac{x}{d}& \frac{y}{d}&0& \frac{1}{d} \\ 0&0&0&1\\ \end{bmatrix}$
+
+
+# 3 实例
+ 假设初始顶点序列表示一个顶点在原点,边长为2的正方体,视点在(4,4,-2),投影平面在$xOy$。
+ 用蓝色图形表示原图形;红色图形表示透视移动后的图形;黑色图形表示投影结果;绿色平面是投影平面;粉色虚线表示进行透视所进行的变换对应关系;黄色虚线表示投影进行的变换关系。
+## 3.1 一点透视
+ 假设移动距离L=6,M=5,N=1
+
+
+
+一点透视三维示意图
+
+
+一点透视投影结果
+
+
+## 3.2 二点透视
+ 假设移动距离L=6,M=5,N=1,φ=40$^。$
+
+
+
+一二点透视三维示意图
+
+
+二点透视投影结果
+
+
+## 3.3 三点透视
+ 假设移动距离L=1,M=-3,N=4,φ=45$^。$,θ=30$^。$
+
+
+
+三点透视三维示意图
+
+
+三点透视投影结果
+
\ No newline at end of file
diff --git a/projection.py b/perspective/perspective.py
similarity index 54%
rename from projection.py
rename to perspective/perspective.py
index e70f6dd..075c427 100644
--- a/projection.py
+++ b/perspective/perspective.py
@@ -19,19 +19,38 @@ def projection_trans(view_point,points):
new_points=np.matmul(points,mtx)
return new_points
-def one_point_projection(L,M,N,view_point,point):
- '''一点'''
+def one_point_perspective(L,M,N,view_point,point):
+ '''一点透视:移动L,M,N'''
+ mtx_mv=np.array([[1,0,0,0],
+ [0,1,0,0],
+ [0,0,1,0],
+ [L,M,N,1]],dtype=np.float32)
+ new_point=np.matmul(point,mtx_mv)
+
+ return new_point
+
+def two_point_perspective(L,M,N,a,view_point,point):
+ '''二点透视'''
+ #先移动L,M,N
mtx_mv=np.array([[1,0,0,0],
[0,1,0,0],
[0,0,1,0],
[L,M,N,1]],dtype=np.float32)
point=np.matmul(point,mtx_mv)
- # print(point)
- new_point=projection_trans(view_point,point)
- return new_point,point
-def two_point_projection(L,M,N,a,view_point,point):
- '''二点'''
+ #绕y轴旋转 a 度(a<90deg)
+ a=a/180*np.pi
+ mtx_roty=np.array([[np.cos(a),0,np.sin(a),0],
+ [0,1,0,0],
+ [-1*np.sin(a),0,np.cos(a),0],
+ [0,0,0,1]],dtype=np.float32)
+ new_point=np.matmul(point,mtx_roty)
+
+ return new_point
+
+
+def three_point_perspective(L,M,N,a,b,view_point,point):
+ '''三点透视'''
#先移动L,M,N
mtx_mv=np.array([[1,0,0,0],
[0,1,0,0],
@@ -47,71 +66,18 @@ def two_point_projection(L,M,N,a,view_point,point):
[0,0,0,1]],dtype=np.float32)
point=np.matmul(point,mtx_roty)
- # print(point)
- new_point=projection_trans(view_point,point)
- return new_point,point
-
-
-def three_point_projection(L,M,N,a,b,view_point,point):
- '''三点'''
- #先移动L,M,N
- mtx_mv=np.array([[1,0,0,0],
- [0,1,0,0],
- [0,0,1,0],
- [L,M,N,1]],dtype=np.float32)
- point=np.matmul(point,mtx_mv)
- print("aaa")
- print(point)
- #绕y轴旋转 a 度(a<90deg)
- a=a/180*np.pi
- mtx_roty=np.array([[np.cos(a),0,np.sin(a),0],
- [0,1,0,0],
- [-1*np.sin(a),0,np.cos(a),0],
- [0,0,0,1]],dtype=np.float32)
- point=np.matmul(point,mtx_roty)
- print("bbb")
- print(point)
#绕x轴旋转 b 度(b<90deg)
b=b/180*np.pi
mtx_rotx=np.array([[1,0,0,0],
[0,np.cos(b),np.sin(b),0],
[0,-1*np.sin(b),np.cos(b),0],
[0,0,0,1]],dtype=np.float32)
- point=np.matmul(point,mtx_rotx)
- print("ccc")
- print(point)
- # print(point)
- new_point=projection_trans(view_point,point)
- return new_point,point
+ new_point=np.matmul(point,mtx_rotx)
+
+ return new_point
-view_point = np.array([0,0,-1,1],dtype=np.float32)
-points= np.array([[0,0,0,1],
- [1,0,0,1],
- [1,1,0,1],
- [0,1,0,1],
- [0,0,0,1],
- [0,0,1,1],
- [1,0,1,1],
- [1,1,1,1],
- [0,1,1,1],
- [0,0,1,1],
- [0,0,0,1],
- [1,0,0,1],
- [1,0,1,1],
- [1,1,1,1],
- [1,1,0,1],
- [0,1,0,1],
- [0,1,1,1]],dtype=np.float32)
-
-
-#new_points=one_point_projection(0,0,0,view_point,points)
-new_points,ori_points=three_point_projection(2,3,1,50,30,view_point,points)
-
-new_points=homo2cart(new_points)
-
-
-def draw(view_point,ori_points,new_points):
+def draw(view_point,ori_points,mv_points,new_points):
plt.scatter(new_points[:,0],new_points[:,1],c="black")
plt.plot(new_points[:,0],new_points[:,1],c="black")
ax=Axes3D(plt.figure())
@@ -123,23 +89,63 @@ def draw(view_point,ori_points,new_points):
ax.plot_surface(X,Y,Z=X*0,color='g',alpha=0.3)
- ax.scatter(ori_points[:,0],ori_points[:,1],ori_points[:,2])
+ #原来的点阵
+ ax.scatter(ori_points[:,0],ori_points[:,1],ori_points[:,2],c="brown")
+ ax.plot(ori_points[:,0],ori_points[:,1],ori_points[:,2],c="brown")
+ #透视移动后
+ ax.scatter(mv_points[:,0],mv_points[:,1],mv_points[:,2])
ax.scatter(view_point[0],view_point[1],view_point[2],c='r')
- ax.plot(ori_points[:,0],ori_points[:,1],ori_points[:,2])
- ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1,1, 0.5, 1]))
-
+ ax.plot(mv_points[:,0],mv_points[:,1],mv_points[:,2])
+ ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([1,1, 1, 1]))
+ #投影后
ax.scatter(new_points[:,0],new_points[:,1],c="black")
ax.plot(new_points[:,0],new_points[:,1],c="black")
+ #原来与移动后点两两连接
+ for i in range(len(mv_points)):
+ ax.plot([ori_points[i,0],mv_points[i,0]],[ori_points[i,1],mv_points[i,1]],[ori_points[i,2],mv_points[i,2]],c="pink",linestyle='--')
+ #两组点两两连接
+ for i in range(len(mv_points)):
+ ax.plot([mv_points[i,0],view_point[0]],[mv_points[i,1],view_point[1]],[mv_points[i,2],view_point[2]],c='y',linestyle='dashdot')
ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})
-
-
plt.show()
+#视点(0,0,-1,1)
+view_point = np.array([4,4,-2,1],dtype=np.float32)
+#以(0,0,0)为原点的正方体
+points= np.array([[0,0,0,1],
+ [2,0,0,1],
+ [2,2,0,1],
+ [0,2,0,1],
+ [0,0,0,1],
+ [0,0,2,1],
+ [2,0,2,1],
+ [2,2,2,1],
+ [0,2,2,1],
+ [0,0,2,1],
+ [0,0,0,1],
+ [2,0,0,1],
+ [2,0,2,1],
+ [2,2,2,1],
+ [2,2,0,1],
+ [0,2,0,1],
+ [0,2,2,1]],dtype=np.float32)
+
+#获得透视移动后的点和投影后的点
+#per_points=one_point_perspective(6,5,1,view_point,points)
+#per_points=two_point_perspective(6,5,1,40,view_point,points)
+#透视移动后的点
+per_points=three_point_perspective(1,-3,3,45,30,view_point,points)
+#投影后的点
+pro_points=projection_trans(view_point,per_points)
+#转为笛卡尔坐标系
+per_points=homo2cart(per_points)
+pro_points=homo2cart(pro_points)
-draw(view_point,ori_points,new_points)
\ No newline at end of file
+#画图
+draw(view_point,points,per_points,pro_points)
\ No newline at end of file
diff --git a/perspective/pic/Figure_1.png b/perspective/pic/Figure_1.png
new file mode 100644
index 0000000..a4a4618
Binary files /dev/null and b/perspective/pic/Figure_1.png differ
diff --git a/perspective/pic/Figure_2.png b/perspective/pic/Figure_2.png
new file mode 100644
index 0000000..7f959e9
Binary files /dev/null and b/perspective/pic/Figure_2.png differ
diff --git a/perspective/pic/Figure_3.png b/perspective/pic/Figure_3.png
new file mode 100644
index 0000000..70c6a7c
Binary files /dev/null and b/perspective/pic/Figure_3.png differ
diff --git a/perspective/pic/Figure_4.png b/perspective/pic/Figure_4.png
new file mode 100644
index 0000000..e136c46
Binary files /dev/null and b/perspective/pic/Figure_4.png differ
diff --git a/perspective/pic/Figure_5.png b/perspective/pic/Figure_5.png
new file mode 100644
index 0000000..b93f161
Binary files /dev/null and b/perspective/pic/Figure_5.png differ
diff --git a/perspective/pic/Figure_6.png b/perspective/pic/Figure_6.png
new file mode 100644
index 0000000..21cfd6a
Binary files /dev/null and b/perspective/pic/Figure_6.png differ
diff --git a/perspective/pic/Untitled.png b/perspective/pic/Untitled.png
new file mode 100644
index 0000000..a2fb873
Binary files /dev/null and b/perspective/pic/Untitled.png differ