创建一个只有 2 个已知点的立方体

Creating a cube with only 2 known points

我目前正在制作一个程序,根据用户给出的 2 分生成立方体。我知道立方体可以仅基于 2 个点以无限多种方式旋转。但是,例如 geogebra 仅基于 2 个点生成一个立方体,我想复制它。我对矢量的了解非常有限,但我猜我需要从 2 个点与这 3 个矢量总共形成的矢量创建 2 个法线我能够创建立方体。

我的问题是我不知道如何创建 2 条相互对齐的法线,使我可以使用它们创建立方体,因为 3 中的向量有无限多条法线维space。我的猜测是我需要在计算法线时丢弃一个轴。但我不知道该怎么做。

编辑。 我的代码只是计算每个角的点,立方体的面积和中心点,没有图形只是将每个点的x,y,z保存到立方体class。我只需要我需要添加到我的代码中的数学来计算每个角点。

假设您的 2 个点定义立方体的内部对角线 u(蓝色)。

从这2点我们已经知道立方体的2个顶点,它们的平均值是立方体的中心p

现在我们需要 select 平面,其中两条 u,v 对角线将使用任何不(反)平行于对角线 u 的方向并将其用作平面的法线n(绿色)。在这种情况下,我通常使用 (1.0,0.0,0.0)(0.0,1.0,0.0) 取决于第一个是否平行(可以用​​点积来决定)。您还可以使用相机向前和向右的方向,这样无论相机方向如何,立方体都以相同的方式对齐。

现在为了获得红色对角线,我们只需将蓝色对角线围绕对齐向量 n 和中心 p.

旋转 ~70.529deg = 2*atan(1/sqrt(2))

最后,为了获得最后缺失的 2 条对角线(代码中的 U,V),我们只需将前两条 (u,v) 围绕 n' 旋转 90deg 并居中 pn' 只是 u-v 中间的方向,所以 n'=u-v.

这里是使用我的 GLSL style vector math 的小 C++ 代码(你可以使用任何其他类似 GLM 的东西,甚至你只需要 v+v,v-v,v*c,v/c,dot,cross,length)还要注意角度 a0,a1 以弧度表示:

//---------------------------------------------------------------------------
vec3 A=vec3(-0.7,-0.8,+0.5),    // input points
     B=vec3(+0.5,+0.6,-0.4);
vec3 pnt[8];                    // output cube points
//---------------------------------------------------------------------------
// return rotated p around axis (center is (0,0,0))
vec3 rotate(float ang,vec3 axis,vec3 p)
    {
    float c=cos(ang),s=sin(ang);// precompute goniometrics
    vec3 u,v,w;                 // bazis vectors
    float x,y,z,xx,yy;
    w=normalize(axis);          // w is rotation axis
    u=vec3(1.0,0.0,0.0);        // u = any unit align vector not parallel to w
    if (fabs(dot(u,w))>0.75) u=vec3(0.0,1.0,0.0);
    u=cross(u,w);               // make u paralel to w and align vector
    v=cross(u,w);               // make v paralel to u and w
    // convert to basis vectors local coordinates
    xx=dot(p,u);
    yy=dot(p,v);
    z =dot(p,w);
    // rotate XY plane
    x=xx*c-yy*s;
    y=xx*s+yy*c;
    // convert back to global coordinates
    p=(x*u)+(y*v)+(z*w);
    return p;
    }
//---------------------------------------------------------------------------
// compute pnt[] from A,B
void diagonal2cube()
    {
    const float a0=1.230959417340774682134929178248;    // 70.5288 deg
    const float a1=1.5707963267948966192313216916398;   // 90.0000 deg
    float a;
    vec3 p,u,v,U,V,n;
    p=0.5*(A+B);        // center of cube
    u=A-p;              // half diagonal from center to pnt[0]
    a=length(u);        // half size of cube's diagonal
    u=normalize(u);     // normalize u
    n=vec3(1.0,0.0,0.0);// n = any unit align vector not parallel to u
    if (fabs(dot(u,n))>0.75) n=vec3(0.0,1.0,0.0);
    n=cross(u,n);       // make n paralel to u and align vector
    u*=a;               // rescale u back to original size
    v=rotate(a0,n,u);   // v is u rotated by 70.5288 deg around n
    n=u-v;              // n is axis perpendicular to n and in the same plane as u,v
    U=rotate(a1,n,u);   // U is u rotated by 90.0 deg around n
    V=rotate(a1,n,v);   // V is v rotated by 90.0 deg around n
    pnt[0]=p+u;         // construct the cube vertexes
    pnt[6]=p-u;
    pnt[1]=p+v;
    pnt[7]=p-v;
    pnt[3]=p+U;
    pnt[5]=p-U;
    pnt[2]=p+V;
    pnt[4]=p-V;
    }
//---------------------------------------------------------------------------

此处预览使用 OpenGL 生成的立方体: