[Python] Numpy で3D座標変換 その2
import numpy as np
# ローカルの頂点座標
v1 = np.array([-1.0,1.0,-1.0,1.0])
# Model のワールド座標
wPost = np.array([1.0,1.5,3.0])
# カメラポジション
eye = np.array([0.0, 0.0,-5.0])
at = np.array([0.0,0.0,0.0])
up = np.array([0.0,1.0,0.0])
# スクリーンサイズ
width = 640
height = 480
# Near/Far Z
zn = 0.01
zf = 100.0
# 移動行列
trans = np.mat(
[
[1.0,0.0,0.0,0.0],
[0.0,1.0,0.0,0.0],
[0.0,0.0,1.0,0.0],
[wPost[0],wPost[1],wPost[2],1.0],
]
)
v1 = np.matmul(v1,trans)
# zaxis
a = at - eye
b = np.linalg.norm(at-eye)
zaxis = a / b
# xaxis
d = np.cross(up, zaxis)
e = np.linalg.norm(d)
xaxis = d / e
# yaxis
yaxis = np.cross(zaxis, xaxis)
view = np.mat(
[
[xaxis[0], yaxis[0], zaxis[0], 0.0],
[xaxis[1], yaxis[1], zaxis[1], 0.0],
[xaxis[2], yaxis[2], zaxis[2], 0.0],
[-np.dot(xaxis, eye), -np.dot(yaxis, eye), -np.dot(zaxis,eye),1.0]
]
)
povy = 0.785398163
yscale = 1.0 / np.tan(povy/2.0)
aspect = width / height
xscale = yscale / aspect
proj = np.mat(
[
[xscale, 0, 0, 0],
[0, yscale, 0, 0],
[0, 0, zf / (zf-zn), 1 ],
[0, 0, -zn * zf / (zf-zn), 0]
]
)
v1 = np.matmul(v1,view)
v1 = np.matmul(v1,proj)
w = width/2
h = height/2
viewport = np.mat(
[
[w, 0, 0, 0],
[0, -h, 0, 0],
[0, 0, 1, 0],
[w, h, 0, 1]
]
)
v1 = v1 / v1[0,3]
v1 = np.matmul(v1, viewport)
v1
Numpy で実行した時の出力結果は下記になる。
matrix([[320. , 33.06740882, 0.9986713 , 1. ]])
X, Y が座標変換後のスクリーン座標。(320, 33) 位置になる。
Z が Depth Buffer に書かれる値。Z 0.99867
World 座標の Transform で (1.0, 1.5, 3.0) の位置に変換している。