我不是这个网站的新手,因为我之前使用过它,但这是我第一次发帖提问:D
首先,我使用Y轴上下。
我试图计算三维空间中4个正方形的点,该点与两个给定点形成的直线垂直。这个方块必须是:
我自己尝试过编码,我有点成功,但这并不是我想要的。这是我所拥有的代码片段:
注意:Vert是一个将坐标存储在3个变量x,y和z中的类。 FourVert是一个存储4个Verts的类,构造函数是我想要开发的。两个Vert参数是给定点,浮点t是输出4点之间所需的厚度或间隔。 Add是一个函数,它将给定的Vert坐标值作为偏移添加到FourVert的所有4个点。这仅用于重新定位右侧位置的第一个Vert。我可能有奇怪的命名约定,但我以我理解的方式编写它。
编辑:根据评论中的要求添加了评论。 (没有双关语)
public FourVert(Vert V1, Vert V2, float t)
{
float dx = V2.x - V1.x; //Position our points at the origin to convert into
float dy = V2.y - V1.y; //polar coordinates using Math.atan2();
float dz = V2.z - V1.z;
float d = (float) Math.sqrt(dx*dx+dz*dz); //Get the lateral distance to use
float axz = (float) -Math.atan2(dx, dz); //in relation with the y value to
float ady = (float) Math.atan2(d, dy); //calculate the altitude angle
float px = (float) (Math.cos(axz) * t);
float py = (float) (Math.cos(ady + 1.570796327) * t); //add half PI
float ny = (float) (Math.cos(ady - 1.570796327) * t);
float pz = (float) (Math.sin(axz) * t);
v1 = new Vert(px, py, pz); //Use the calculated values to produce 4 points
v2 = new Vert(-px, py, -pz); //v1, v2, v3, and v4 are our Vert fields of the
v3 = new Vert(-px, ny, -pz); //FourVert class
v4 = new Vert(px, ny, pz);
add(V1); //take our FourVert back to where we want it, not on the origin.
}
我已经完成了渲染,并且我知道它运行良好,因为我已经测试过它。
这里有效的是方位角值,它们功能完美(横向移动)。垂直移动或高度或“音高”无法正常工作。我已经尝试了很多其他方法来做到这一点无济于事。
我认为问题/不起作用的部分在这里:
float py = (float) (Math.cos(ady + 1.570796327) * t);
float ny = (float) (Math.cos(ady - 1.570796327) * t);
这对我来说是很多三角函数,我让自己疯了。提前谢谢。
我的代码可能看起来效率低下,但之后会进行优化,我需要先让它运行然后才能优化我想要的。
答案 0 :(得分:0)
我会避免所有那些三角学。对于其中一个边缘方向,您需要一个同时垂直于 V 1 - V 2的矢量和 Y 轴。交叉积可用于获得垂直于两个给定的矢量。所以你计算它是这样的:
[ 0 ] [ x2 − x1 ] [ z2 − z1 ] [ dz ]
[ 1 ] × [ y2 - y1 ] = [ 0 ] = [ 0 ] = w₁
[ 0 ] [ z2 - z1 ] [ x1 − x2 ] [ −dx ]
对于第二个边缘方向,您希望垂直于第一个边缘方向,并且还垂直于 V 1 - V 2 。所以同样的故事:
[ dz ] [ dx ] [ dx*dy ] [ ex ]
[ 0 ] × [ dy ] = [ − dx² − dz² ] =: [ ey ] = w₂
[ −dx ] [ dz ] [ dz*dy ] [ ez ]
你必须规范化这些向量以确保它们的长度为1,然后你就完成了。在。事实上我将它们标准化为长度½因为那时你可以使用±该向量来描述在原点周围对称的位置,也就是你自己的代码所做的那样。对于角落,您需要± w 1 ± w 2 ,这提供了四种可能的符号组合。
public FourVert(Vert V1, Vert V2, float t)
{
float dx = V2.x - V1.x;
float dy = V2.y - V1.y;
float dz = V2.z - V1.z;
float ex = dx*dz;
float ey = -dx*dx-dz*dz;
float ez = dz*dy;
float d = (float)(t/(2*Math.sqrt(dx*dx+dz*dz)));
float e = (float)(t/(2*Math.sqrt(ex*ex+ey*ey+ez*ez)));
dx *= d; dz *= d;
ex *= e; ey *= e; ez *= e;
v1 = new Vert( dz+ex, ey, -dx+ez);
v2 = new Vert( dz-ex, -ey, -dx-ez);
v3 = new Vert(-dz-ex, -ey, dx-ez);
v4 = new Vert(-dz+ex, ey, dx+ez);
add(V1);
}
你现在可能不再需要这个,但为了完整起见:而不是
float py = (float) (Math.cos(ady + 1.570796327) * t);
float ny = (float) (Math.cos(ady - 1.570796327) * t);
我会写
float py = (float) (-Math.sin(ady) * t);
float ny = (float) ( Math.sin(ady) * t);
这利用了sin和cos相差π/ 2的事实。