对于学校作业我和朋友一直在使用2D库(光滑)在2D表面(屏幕)上渲染立方体
为此,我们使用此处描述的方法3D-projection - Wikipedia the free encyclopedia。
我们使用3x3矩阵来旋转3D矢量,这些矢量表示立方体表面上的点。然后我们使用这种方法将3D矢量投影到位于正X轴上的平面(屏幕)上:
public Vector2D translate2D(Vector3D v){
Vector3D trans = translate(v);//Rotates the vector into position
float w = -trans.getX()/(700) + 1;
float x = (trans.getZ())/w;
float y = (trans.getY())/w;
return new Vector2D(x, y);
}
其中translate()将向量旋转到正确的位置,w向立方体添加一些透视。
现在问题出在这里:
我需要知道要渲染的立方体的哪些边以及不渲染的边(哪些面向观察者,哪些不是)。只要你不使用透视(w),这很容易。多维数据集始终向用户显示三个方面,并找到所需的全部内容:
这是因为屏幕直接位于正X轴上。
现在,由于透视,观察者面向1-3个侧面,具体取决于立方体的旋转。 如何在计算中补偿透视并确定哪一侧面向观察者?如上所述,我可以访问每一侧的法线(直接指向每一侧的单位矢量)和处理轮换以及上述方法。
(编辑)谢谢你的答案horatius83,但这是我的问题:我不知道他表面正常,因为侧面的正常因为增加的视角而略微扭曲。
以下是一些可以进一步描述我的问题的图片
没有透视(边的法线=表面法线):
透视显示3个边(边的正常!=表面法线):
透视显示3个边但应该只显示1(边的正常!=表面法线)
(编辑)确定是否应该渲染边的代码非常简单而且不完全正确,因为我们使用边的法线就像没有透视一样(如图1中所示)。如果有观点,必须以某种方式补偿。我只是不知道如何。
public boolean sideVisible(Vector3D normal){
if (translate(normal).getX()>0) {
return true;
}else{
return false;
}
}
答案 0 :(得分:2)
取视图矢量的点积(想象一个箭头从相机中出来)和表面法线。如果它是负数,则可以看到面部。
(编辑:你想在世界空间中进行这些计算,即遵循模型进行世界转换)
答案 1 :(得分:0)
首先感谢horatius83和asawyer提供了许多有用的提示。以下是如何在不知道曲面法线的情况下解决这个问题,只需使用边的法线以及屏幕和查看器的位置。
有关更长的说明,请参阅this link