0

Im currently making a program that generates a cube based on 2 points the user has given. I do know that the cube could be rotated in an infinite number of ways based on only 2 points . However for example geogebra generates a cube only based on 2 points and I want to replicate that. My knowledge of vectors is very limited but Im guessing I need 2 normals created from the vector that the 2 points make with those 3 vectors in total Im able to create the cube.

My problem is I dont know how to create 2 normals that are aligned with each other in a way that makes it possible for me to create the cube using them since there are an infinite number of normals for a vector in 3 dimensional space. My guess is that I need to discard one axis when calculating the normals. But I have no clue how to do that.

Edit. My code just calculates the points of each corner, the area of the cube and the center point, no graphics just saves x,y,z of each point to the cube class. I just need the math that I need to add to my code in order to calculate each corner point.

Spektre
  • 49,595
  • 11
  • 110
  • 380
Juho
  • 23
  • 2
  • Hi, can you add more details? what are you aiming for? an algorithm or a peace of code, please structure your question so we know the kind of answer you want to get – Daniel Cruz Feb 20 '22 at 00:54
  • Added more details – Juho Feb 20 '22 at 01:05
  • so you want an algorithm that, given two points gives you "the" cube that seems more intuitive for the user for those two points? – Daniel Cruz Feb 20 '22 at 01:21
  • Pretty much yes. – Juho Feb 20 '22 at 01:30
  • well... what programming language are you using? – Daniel Cruz Feb 20 '22 at 01:31
  • I'm using java. – Juho Feb 20 '22 at 01:32
  • My java is really rusted... some pseudocode would work for you? – Daniel Cruz Feb 20 '22 at 01:37
  • Yes thats fine! – Juho Feb 20 '22 at 01:40
  • If we are going with my original idea the vector math in itself is pretty simple yes, but I have no Idea where to start, how should I decide the alignment of the cube with only the 2 points given. More importantly the program needs to figure it out itself based on something but I dont know what. This might be a given for some people but my vector math knowledge is really basic. Edit. Location of the points doesnt matter for me they just need to be at any corner of the cube – Juho Feb 20 '22 at 09:38
  • I added answer with vector approach using the 2 points as cubes internal diagonal (have reworded it slightly to make it more understandable, updated image and repair some typos in code comments) – Spektre Feb 21 '22 at 06:45

1 Answers1

0

lets assume your 2 points are defining the cube's internal diagonal u (blue).

cube diagonals

From these 2 points we already know 2 vertexes of cube and their average is center of the cube p.

Now we need to select plane in which both u,v diagonals will be by using any direction not (anti)parallel to diagonal u and use it as normal of the plane n (green). In such cases I usually use either (1.0,0.0,0.0) or (0.0,1.0,0.0) depending on if the first is parallel or not (that can be decided with dot product). You can also use camera forward and right directions so the cube aligns the same way regardless on camera orientation.

Now to obtain the red diagonal we just rotate the blue one by ~70.529deg = 2*atan(1/sqrt(2)) around align vector n and center p.

Finally to obtain last missing 2 diagonals (U,V in code) we just rotate the first two (u,v) by 90deg around n' and center p. The n' is just direction in the midle u and -v so n'=u-v.

Here small C++ code for this using my GLSL style vector math (you can use any other like GLM or even own you just need v+v,v-v,v*c,v/c,dot,cross,length) also note angles a0,a1 are in radians:

//---------------------------------------------------------------------------
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;
    }
//---------------------------------------------------------------------------

Here preview of generated cube using OpenGL:

preview

Spektre
  • 49,595
  • 11
  • 110
  • 380