如果您不使用球坐标系,则此任务无法解决,因为在投影前丢弃 Z 坐标会移除投影点的距离,因此您不知道如何应用透视。
你有两个选择(除非我忽略了什么):
-
应用 3D 变换矩阵
然后只使用 x,y - 结果的坐标
-
为旋转/投影创建 3x3 变换矩阵
并在应用它之前或之后添加偏移向量。请注意,这种方法不使用齐次坐标!!!
[Edit1] 清晰的方程式
不要忘记3x3 矩阵+向量变换不是累积的!!!这就是使用4x4 转换的原因。现在你可以扔掉最后一行矩阵/向量(Xz,Yz,Zz), (z0),然后输出向量就是(x', y')。当然,在这之后你不能使用逆变换,因为你失去了 Z 坐标。
通过改变轴方向向量的大小来实现缩放
顺便说一句。如果您的投影平面也是 XY-plane 没有旋转,那么:
x' = (x-x0)*d/(z-z0)
y' = (y-y0)*d/(z-z0)
(x,y,z) - 指向项目
(x',y') - 投影点
(x0,y0,z0) - 投影原点
d - 焦距
[Edit2]问题编辑后的意思完全不同
我假设您希望精灵始终面向相机。它很丑陋,但简化了草、树等事物......
M - 你的矩阵
P - M 内的投影矩阵
如果您的原点是 M = (0,0,0) 没有旋转/缩放/倾斜,那么 M=P
pnt - 你的广告牌点(我假设是中心) (w=1) [GCS]
dx,dy - 广告牌的一半大小[LCS]
A,B,C,D - 广告牌的投影边缘[GCS]
[GCS] - 全球坐标系
[LCS] - 局部坐标系
-
如果你知道投影矩阵
我假设它是 glFrustrum 或 gluPerspective ...然后:
(x,y,z,w)=(M*(P^-1))*pnt // transformed center of billboard without projection
A=P*(x-dx,y-dy,z,w)
B=P*(x-dx,y+dy,z,w)
C=P*(x+dx,y+dy,z,w)
D=P*(x+dx,y-dy,z,w)
-
如果您的 M 矩阵过于复杂,#1 无法工作
MM=(M*(P^-1)) // transform matrix without projection
XX=MM(Xx,Xy,Xz) // X - axis vector from MM [GCS](look at the image above on the right for positions inside matrix)
YY=MM(Yx,Yy,Yz) // Y - axis vector from MM [GCS]
X =(M^-1)*XX*dx // X - axis vector from MM [LCS] scaled to dx
Y =(M^-1)*YY*dy // Y - axis vector from MM [LCS] scaled to dy
A = M*(pnt-X-Y)
B = M*(pnt-X+Y)
C = M*(pnt+X+Y)
D = M*(pnt+X-Y)
[Edit3] 仅缩放
MM=(M*(P^-1)) // transform matrix without projection
sx=|MM(Xx,Xy,Xz)| // size of X - axis vector from MM [GCS] = scale x
sy=|MM(Yx,Yy,Yz)| // size of Y - axis vector from MM [GCS] = scale y