[Python] Numpy で3D座標変換 その2

[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) の位置に変換している。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA