Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rotate object to face point

I would like to rotate an object to face a point which I'm have a bit of of trouble with.

So I'm starting with an object that has a base at zero and is aligned on the y axis.

enter image description here

I would like to rotate it so that the top of the object is facing the destination

enter image description here

My process so far is to: Given axis A

  1. find the distance between my position and my look position: D
  2. create a direction vector: V = D.normalize()
  3. find the right vector: R = A cross D
  4. find the up vector: U = D cross R
  5. find the angle between up and direction: ANGLE = acos((U dot D) / (U.length * D.length))
  6. rotate by angle scaled by direction on each axis

here is the code representation of that. I'm not sure what exactly is wrong with this I've worked it out on paper and to my knowledge this approach should work but the results are completely incorrect when drawn. If anyone sees any flaws and could point me in the right direction it would be great.

    Vector3 distance = new Vector3(from.x, from.y, from.z).sub(to.x, to.y, to.z);
    final Vector3 axis = new Vector3(0, 1, 0);
    final Vector3 direction = distance.clone().normalize();

    final Vector3 right = (axis.clone().cross(direction));
    final Vector3 up = (distance.clone().cross(right));

    float angle = (float) Math.acos((up.dot(direction)/ (up.length() * direction.length()))); 
    bondObject.rotateLocal(angle, direction.x , direction.y, direction.z);
like image 272
William Gervasio Avatar asked May 16 '14 03:05

William Gervasio


People also ask

How do you rotate an object on a point?

If you want to rotate around a pivot ( pivotX , pivotY ) you have to: Translate the object so that the pivot point is moved to (0, 0). Rotate the object. Move the object so that the pivot point moves in its original position.


1 Answers

The basic idea here is as follows.

  • Determine which way the object is facing: directionA
  • Determine which way the object should be facing: directionB
  • Determine the angle between those directions: rotationAngle
  • Determine the rotation axis: rotationAxis

Here's the modified code.

Vector3 distance = new Vector3(from.x, from.y, from.z).sub(to.x, to.y, to.z);

if (distance.length() < DISTANCE_EPSILON)
{
    //exit - don't do any rotation
    //distance is too small for rotation to be numerically stable
}

//Don't actually need to call normalize for directionA - just doing it to indicate
//that this vector must be normalized.
final Vector3 directionA = new Vector3(0, 1, 0).normalize();
final Vector3 directionB = distance.clone().normalize();

float rotationAngle = (float)Math.acos(directionA.dot(directionB));

if (Math.abs(rotationAngle) < ANGLE_EPSILON)
{
    //exit - don't do any rotation
    //angle is too small for rotation to be numerically stable
}

final Vector3 rotationAxis = directionA.clone().cross(directionB).normalize();

//rotate object about rotationAxis by rotationAngle
like image 111
Timothy Shields Avatar answered Oct 10 '22 08:10

Timothy Shields