# A point on a sphere surface needs to be converted to origin coordinate

I have a central point, a planet is moving around it on the orbit A (a circle)

And the planet is rotating at a certain speed on its axis ( B ) I have a Data Structure representing the Base Mesh information that is static and calculated around the origin point that is static.

Think:

float3[] pointsList


Where all the point are calculated around 0,0,0 instead of where the planet is ( it's easier to convert 1 point on a frame rather than a list with thousands of point each frame )

Around that planet, I have a collider to be able to catch raycasts on it. The sphere collider is roughly the size of the mesh so it matches well.

Here is what I need :

How can I convert the point from the raycast back to an "origin" state.

Here is an illustration : From My understanding I would need :

To Revert the rotation on the Axis (A) BUT following the (C) Line along the surface to find the base point as if the mesh did not rotate at all and then Translate the point so it is in the origin referential. (Around 0,0,0 , where the base mesh have been calculated)

Now...what are the maths that I need to do behind the scenes to do that?

TLDR: I am trying to convert a raycast point on the surface of a sphere back to an "origin" kind of point to do stuff behind with it with the base mesh coordinates.

Edit : Adding representation of the planet VS the stored point Array ( please note that A is at 0,0,0 ) : Here : B is the representation of the points array and is STATIC & A Is the position of the planet with the collider & the mesh created from B's Points, all rotating on it's axis ( cf : Other screenshot )

So how do I "revert" a point from the collider around the mesh to get a point as if the raycast Happened on the A sphere ?

Edit 2 : Result with InvertTransform

        if (!Physics.Raycast(MainCamera.ScreenPointToRay(Input.mousePosition), out hit))
{
return;
}
RaycastHit hit;

Vector3 localHit = TargetPlanet.transform.InverseTransformPoint(hit.point);
GameObject rayCastHit = GameObject.CreatePrimitive(PrimitiveType.Sphere);
rayCastHit.name = "RayCastHit";
rayCastHit.transform.position = hit.point;
rayCastHit.transform.localScale = new Vector3(0.025f,0.025f,0.025f);

GameObject targetLocal = GameObject.CreatePrimitive(PrimitiveType.Sphere);
targetLocal.name = "TargetLocal";
targetLocal.transform.position = localHit;
targetLocal.transform.localScale = new Vector3(0.025f,0.025f,0.025f);

Vector3 planetHit = TargetPlanet.transform.TransformPoint(targetLocal.transform.position);
GameObject targetPlanet =GameObject.CreatePrimitive(PrimitiveType.Sphere);
targetPlanet.name = "TargetPlanet";
targetPlanet.transform.parent = TargetPlanet.transform;
targetPlanet.transform.position = planetHit;
targetPlanet.transform.localScale = new Vector3(0.025f,0.025f,0.025f);


Then Clicking on the same point again and again without mooving the mouse give me that :

For the raycast hit : For The TargetLocal : ( On the reference Sphere at origin ) For The TargetPlanet: ( On the Surface of the planet & the view of the collider ) Both the hit on the surface & on the reference seems OFF and never hit the same point

Edit 3 : Movement Code :

public float3 EvaluatePlanetOrbit(int planetID, float t)
{
float angle = t * 360 * Mathf.Deg2Rad;
float x = math.sin(angle) * Orbits[planetID].XAxis; // Orbits[planetID].XAxis -> Float
float z = math.cos(angle) * Orbits[planetID].ZAxis; // same

return new float3(x, 0, z);
}

//That is the code managing the movement of the planet

planetData.OrbitalProgress += time * (1 /planetData.CurrentOrbit) * planetData.OrbitalSpeed;
PlanetGridGameObject.transform.position = EvaluatePlanetOrbit(planetData.PlanetID, planetData.OrbitalProgress);

// Rotations
planetData.CurrentAngleRotation += time * GameSettings.RotationPlanetSpeed;
planetData.CurrentAngleRotation %= 360;

Quaternion rotationAboutAxis = Quaternion.Euler(0, planetData.CurrentAngleRotation, 0);
Quaternion tiltOfAxis = Quaternion.Euler(0, 0, GameSettings.RotationPlanetAxis);

PlanetGameObject.transform.rotation = (Quaternion) tiltOfAxis * rotationAboutAxis ;

• Added the results for invert & all so you can visualise what's happening with it :) That's Why that solution is not working. the point that you get is not consistent even if it's is awfully close ^^ May 29, 2022 at 18:30
• It's not clear to me what error those images are meant to illustrate. What makes the result "seem off"? May 29, 2022 at 19:06
• Well the raycast hit is apparently not on the surface but offsetted from the surface. for whatever reason. My test show that if I remove the position update ( but keep the rotation ) I get the good point but when I update the poisiton, of the planet the raycast hit is offsetted May 29, 2022 at 19:36
• Could this be due to a difference between the position of the Rigidbody as of the last physics step, and the Transform in the current frame? Does calling SyncTransforms before the raycast change anything? May 29, 2022 at 19:47
• Shit , It actually fix the issue. But the thing is both actions take place at the same frame. The movement is done BEFORE any input check is done. Can you elaborate in what situation that can happen ? So I maybe be able to fix the issue at the source. May 29, 2022 at 20:08