0

I have 2 THREE.Vector3()s .

I want to draw a circle around one vector and use second vector as tangent.

I have radius of the circle geometry which is distance between vectors.

how can i rotate circle to touch second vector?

how can i get rotation (declination) of circle in radians?

Can i use THREE framework functions or do i need to use mathematical approach?

(i hope it should be some core function of 3D framework).

enter image description here

Spektre
  • 49,595
  • 11
  • 110
  • 380
Martin
  • 2,575
  • 6
  • 32
  • 53
  • what is the problem you do not know hw to compute the angles or do not know how to compute rotation ? also do you use transform matrices or you transform coordinates yourself ? Also see [glCircle3D](http://stackoverflow.com/a/25182327/2521214) it might help a bit – Spektre Jul 22 '15 at 08:21
  • Im asking for correct approach. I can use goniometric formula on triangle, but im asking if threee can do it by some function, for example getAngle(a,b,c) etc... it is ineffective to write pythagoras formules to js sourcecode. – Martin Jul 22 '15 at 08:25

1 Answers1

0

In 3D vector graphics is the trick done with 4x4 homogenous transform matrices

  • You create the matrix and apply it on the whole geometry
  • that is usually done on gfx HW side
  • in your case you don't even need to calculate the angles just compute the basis vectors

This is the glCircle3D in C++/OpenGL of mine:

void glCircle3D(double *pos,double *nor,double r,bool _fill)
    {
    int i,n=36;
    double a,da=divide(pi2,n),p[3],dp[3],x[3],y[3];
    // set x to something not parallel to normal vector
         if (fabs(nor[0]-nor[1])>1e-6) vector_ld(x,nor[1],nor[0],nor[2]);
    else if (fabs(nor[0]-nor[2])>1e-6) vector_ld(x,nor[2],nor[1],nor[0]);
    else if (fabs(nor[1]-nor[2])>1e-6) vector_ld(x,nor[0],nor[2],nor[1]);
    else                       vector_ld(x,1.0,0.0,0.0);
    vector_mul(x,x,nor); // x=cross(x,nor)
    vector_mul(y,x,nor); // y=cross(x,nor)
    vector_len(x,x,r);   // x=r*x/|x| ... r is scalar
    vector_len(y,y,r);   // y=r*y/|y| ... r is scalar
    if (_fill)
        {
        glBegin(GL_TRIANGLE_FAN);
        glVertex3dv(pos);
        }
    else glBegin(GL_LINE_STRIP);
    for (a=0.0,i=0;i<=n;i++,a+=da)
        {
        vector_mul(dp,x,cos(a)); vector_add(p,pos,dp);
        vector_mul(dp,y,sin(a)); vector_add(p,p  ,dp);
        glVertex3dv(p);
        }
    glEnd();
    }
  • nor is circle normal (in your case second vector)
  • pos is circle center position (in your case 0,0,0)
  • r is radius (in your case size of your first vector)
  • x,y vectors are basis vectors with nor defining orthogonal coordinate system
  • if you want to construct the transform matrix then just copy the x,y,nor,pos to appropriate fields of the matrix
  • and use circle geometry with radius 1
  • as you can see no atan2 or acos(dot(v1,v2)) is needed
  • just simple cross product suffice...
  • the code of mine use mine vector library
  • so you just need to code functions like
  • vector_ld(a,x,y,z) a[]={ x,y,z }
  • vector_mul(a,b,c) a[]=b[] x c[]
  • vector_mul(a,b,c) a[]=b[] * c
  • vector_add(a,b,c) a[]=b[] + c[]
  • vector_sub(a,b,c) a[]=b[] - c[]
  • vector_len(a,b,c) a[]=b[]* c / |b[]|
  • The circle coordinates are simple: p=pos+x*cos(alpha)+y*sin(alpha);
  • radius r is inside x,y basis vectors already so no need to multiply by it
Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380