Java 基于直线的2个点计算正方形的4个点

Java 基于直线的2个点计算正方形的4个点,java,geometry,line,point,trigonometry,Java,Geometry,Line,Point,Trigonometry,我对这个网站并不陌生,因为我以前使用过它,但这是我第一次发布一个问题:D 首先,我使用Y轴作为上下方向 我试图计算一个正方形在三维空间中的4个点,它垂直于由两个给定点组成的线。该广场必须: 垂直于由两个给定点定义的线 厚度或宽度/长度为1 对齐,使两侧始终垂直于Y轴 我自己也尝试过编写这个代码,虽然有点成功,但这并不是我想要的。以下是我的代码片段: 注:Vert是一个将坐标存储在3个变量x、y和z中的类。FourVert是一个存储4个顶点的类,构造函数是我正在尝试开发的。两个Vert参数为给定点

我对这个网站并不陌生,因为我以前使用过它,但这是我第一次发布一个问题:D

首先,我使用Y轴作为上下方向

我试图计算一个正方形在三维空间中的4个点,它垂直于由两个给定点组成的线。该广场必须:

垂直于由两个给定点定义的线 厚度或宽度/长度为1 对齐,使两侧始终垂直于Y轴 我自己也尝试过编写这个代码,虽然有点成功,但这并不是我想要的。以下是我的代码片段:

注:Vert是一个将坐标存储在3个变量x、y和z中的类。FourVert是一个存储4个顶点的类,构造函数是我正在尝试开发的。两个Vert参数为给定点,浮点t为输出4点之间所需的厚度或间隔。Add是一个函数,它将给定顶点的坐标值作为偏移量添加到四顶点的所有4个点。这仅用于重新定位右侧位置(第一个顶点)上的点。我可能有一些奇怪的命名约定,但我用一种我能理解的方式来写

编辑:根据评论中的要求添加评论。没有双关语

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.
}
我已经处理好了渲染,我知道效果很好,因为我已经用givens测试过了

这里起作用的是方位角值,它们可以实现完美的横向移动。垂直移动、高度或“俯仰”功能不正常。我尝试过许多其他方法,但都没有成功

问题/部分不起作用,我认为:

    float py = (float) (Math.cos(ady + 1.570796327) * t);
    float ny = (float) (Math.cos(ady - 1.570796327) * t);
这对我来说是一个三角学,我快把自己逼疯了。提前谢谢


我的代码可能看起来效率很低,但优化是在之后进行的,我需要先让它发挥作用,然后才能进行我想要的优化。

我会避免所有的三角函数。对于其中一个边方向,需要同时垂直于V1的向量− V2和Y轴。叉积可用于获得垂直于两个给定向量的向量。所以你可以这样计算:

[0][x2− x1][z2− z1][dz] [1]×[y2-y1]=[0]=[0]=w₁ [0][z2-z1][x1− x2][−dx] 对于第二个边方向,您希望垂直于第一个边方向,同时也垂直于V1− 再一次。同样的故事:

[dz][dx][dx*dy][ex] [0]×[dy]=[− dx²− dz²]=:[ey]=w₂ [ −dx][dz][dz*dy][ez] 您必须规范化这些向量,以确保它们的长度为1,然后就完成了。在里面事实上,我会将它们规格化为长度½,因为这样您就可以使用±该向量来描述围绕原点对称的位置,就像您自己的代码那样。对于拐角,您需要±w1±w2,这将给出四种可能的符号组合

公共四伏V1,垂直V2,浮动t { 浮点dx=V2.x-V1.x; float dy=V2.y-V1.y; 浮点数dz=V2.z-V1.z; 浮点数ex=dx*dz; 浮点数ey=-dx*dx-dz*dz; 浮点数ez=dz*dy; float d=float/2*数学sqrtdx*dx+dz*dz; float e=float/2*Math.sqrtex*ex+ey*ey+ez*ez; dx*=d;dz*=d; ex*=e;ey*=e;ez*=e; v1=新垂直dz+ex,ey,-dx+ez; v2=新垂直dz ex,-ey,-dx ez; v3=新垂直dz ex,-ey,dx-ez; v4=新垂直dz+ex、ey、dx+ez; addV1; } 您现在可能不再需要这个了,但是为了完整性:而不是

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的事实。

只是一个建议,试着对你的代码稍加注释,让你自己和其他人知道你在某一行或某一段代码中做了什么。在这种代码中,3-4行的注释都很有用。干得好。看,就在这里,清晰度提高了一个数量级。不需要三角学+1.改进问题:非常感谢!它几乎可以完美地工作。不过,当接近Y轴的负侧时,正方形的非水平侧在绕Y轴旋转时会发生弯曲,这是一个小问题。他们做了一个像\=\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。我已经尝试过修复它,但它是相当难以捉摸的,我怀疑它是一个倒置的正负符号在代码中的某个地方,但我不确定。