Rotate Point A on Sphere to Point B on Sphere

Imagine a globe (sphere). I have Point A (Miami FL) and Point B (Portland OR). I would like to rotate the globe so that:

  1. The position of the globe and main camera do not move
  2. Point A ends up where Point B was
  3. The globe rotates along the an axis that runs through the center of the sphere and is normal to the plane created by Point A, Point B, and the center of the sphere.

I have been using Quaternion.FromToRotation but I have not been able to come up with a good solution.

Any suggestions?

Thanks, Mike


Vector3 pointA;
Vector3 pointB;
GameObject sphere;

//What should I put here?

sphere.transform.rotation = resultRotation

I hope i understand it right. If so i had a similar problem yesterday.

I used this:

Quaternion rotation = Quaternion.LookRotation(targetVector);
Vector3 point = new Vector(x,y,z);
point = rotation  * point ;

Also instead of using a Vector you rotate it should work if you use the rotation on a transform.rotation of a GameObject.


So i played around a little bit. I added one sphere in the middle of my scene, and two cubes.

    // the cubes
    public GameObject pointA;
    public GameObject pointB;
    // the sphere
    public GameObject globe;

    Quaternion rotationA;
    Quaternion rotationB;

void Start()
     // get the start rotation of the points
     rotationA = Quaternion.LookRotation(pointA.transform.position);
     rotationB = Quaternion.LookRotation(pointB.transform.position);

void Update()
    // here the sphere rotate from point a to b
    // to make the cubes follow the sphere, you have to calculat there position, 
    // or put the gameobjects from the cbes inside the sphere
    globe.transform.rotation = Quaternion.Slerp(rotationA, rotationB, Time.time * 0.1f);    

was the function which helped me, it worked for me but im not sure if this is the best way to do it

I think you are on the right track with FromToRotation.

for the following to work your sphere would have to be at global (0,0,0)

Quaternion rot = Quaternion.FromToRotation (pointA, pointB);
sphere.transform.rotation *= rot; //Multiply rotations to get the resultant rotation.

if your sphere is not at global (0,0,0) you need to make sure that pointA and pointB relative to the sphere coord system and then use the following:

Quaternion rot = Quaternion.FromToRotation (pointA, pointB);
sphere.transform.localRotation *= rot; //Multiply rotations to get the resultant rotation.

cnc guy helped answer my question. This is the code I ended up with. It allows a user to grab a point on a sphere and rotate the sphere from that point.

using UnityEngine; 
using System.Collections; 

public class EarthTouchMovement : MonoBehaviour { 

    bool hasGrabbedPoint = false;
    Vector3 grabbedPoint;

   void Update () 
      if (Input.GetMouseButton(0)) 
            hasGrabbedPoint = true;                                             
            grabbedPoint = getTouchedPoint();
            Vector3 targetPoint = getTouchedPoint();
            Quaternion rot = Quaternion.FromToRotation (grabbedPoint, targetPoint);
            transform.localRotation *= rot;             
        hasGrabbedPoint = false;      

   Vector3 getTouchedPoint()
        RaycastHit hit;
        Physics.Raycast (Camera.main.ScreenPointToRay(Input.mousePosition), out hit);

        return transform.InverseTransformPoint(hit.point);

Is there a simple way to modify this solution to constrain the globe to stay right side up? Meaning, I want to keep the North Pole at the top instead of it ending up getting spun on its side. I guess it would spin on it’s Y and X axis but not Z. Thanks.