Rotate a Sphere to have a point on the surface be centered on screen


#1

Hi all,
this is the scenario: I have a sphere made up of an array of vec3 vertices.
When I click a button, I want that the whole sphere rotates in a way that the vertex I selected gets positioned in the center of the screen, so in world coordinates x and y should be 0. I cannot use the rotate function built in P5, so I made my own rotate functions for the 3 axis.

This is what I have until now, but clearly doesn’t work:

  m4.rotateTowardPoint = function(vertices, index) {
    let point = vertices[index];
    let normal = p5.Vector.sub(point, m4.createVector(0,0,0));
    let upVector = m4.createVector(0,0,-1);

    let n = normal.normalize();

    let angleOfRotation = n.angleBetween(upVector);
    let axisOfRotation = p5.Vector.cross(n, upVector);
    m4.verticesRotated = vertices.slice(0);

    rotateX3D(angleOfRotation*axisOfRotation.x, m4.verticesRotated);
    rotateY3D(angleOfRotation*axisOfRotation.y, m4.verticesRotated);
}

My rotate funcions:

  function rotateZ3D(t, xyz) {
      const c = Math.cos(t), s = Math.sin(t), len = xyz.length;
      for (let i = 0; i < len; i += 1) {
        const x = xyz[i].x, y = xyz[i].y;
        xyz[i].x   = x*c - y*s;
        xyz[i].y   = y*c + x*s;
      }
    }

    function rotateY3D(t, xyz) {
      const c = Math.cos(t), s = Math.sin(t), len = xyz.length;
      for (let i = 0; i < len; i += 1) {
        const x = xyz[i].x, z = xyz[i].z;
        xyz[i].x   = x*c - z*s;
        xyz[i].z  = z*c + x*s;
      }
    }

    function rotateX3D(t, xyz) {
      const c = Math.cos(t), s = Math.sin(t), len = xyz.length;
      for (let i = 0; i < len; i += 1) {
        const y = xyz[i].y, z = xyz[i].z;
        xyz[i].y = y*c - z*s;
        xyz[i].z = z*c + y*s;
      }
    }

Thank you for any help!


#2

I’ll assume that your general rotate function works, but the vertex specific one doesn’t. In that case you can just subtract the position of the vertex that you selected from all other vertices and then rotate the sphere. You can also add to all vertices a specific amount so that the selected vector will be in the center. Note that this will rotate the sphere around that vector, so the sphere will be offcentered depending on the rotation.


#3

Those 3 rotate functions seem to come from this sketch, right? :sunglasses:

Notice though that sketch is using: angleMode(DEGREES): :exclamation:
p5js.org/reference/#/p5/angleMode

Otherwise, you’re gonna need to convert all angle arguments passed to parameter t to radians(): :currency_exchange:
p5js.org/reference/#/p5/radians

That’s exactly what the Java Mode version does inside mouseDragged() btW: :coffee: