- Home /
spherical projection of points to plane, precision error?
Working on a spherical to planar mapping and have run into what seems like a precision error and am not sure how to address. To start with, I'm considering two points on the sphere. I want to get a planar vector that represents the difference of these two points on the planar projection. To setup the projection, I assume the first point is the center of the projection and I create a rotation to bring this point onto the xz plane. I then project the second point onto the plane associated w/ the center point, then rotate this projection via the computed rotation. It does seem to work for the most part, but my accuracy seems to be only about 3 decimal places. If my math is correct, I should be able to compute this projection from p1 to p2 and from p2 to p1 and get the same answer but in reverse. Code and results are below. Anyone see what I'm doing wrong or see ways of improving the accuracy?
static Quaternion ComputeRotation(Vector3 vector) {
// compute xy angle/rotation
var xyProjection = new Vector3(vector.x, vector.y, 0);
var xyAngle = Vector3.Angle(xyProjection, Vector3.up);
var xyRot = Quaternion.Euler(0, 0, (vector.x>0.0f) ? xyAngle : -xyAngle);
// compute yz angle/rotation
var yzProjection = xyRot * vector;
var yzAngle = Vector3.Angle(yzProjection, Vector3.up);
var yzRot = Quaternion.Euler((vector.z>0.0f) ? -yzAngle : yzAngle, 0, 0);
return yzRot * xyRot;
}
public static Vector3 ProjectPoint(Vector3 centerVector, Vector3 point, float scale=1.0f) {
var rotation = ComputeRotation(centerVector);
var projection = rotation * Vector3.ProjectOnPlane(point*scale, centerVector.normalized);
return projection;
}
[TestFixture]
public class TestProjection {
[Test]
public void TestProjectPoint() {
var p1 = new Vector3(0.195f, 0.981f, 0.0f);
var p2 = new Vector3(0.377f, 0.911f, -0.167f);
var pp12 = Projection.ProjectPoint(p1, p2, 1.0f);
var pp21 = Projection.ProjectPoint(p2, p1, 1.0f);
Debug.Log("pp12: " + pp12.ToString("F4") + " pp21: " + pp21.ToString("F4"));
Assert.True(Geometry.CloseEnough(pp12, -pp21));
}
}
pp12: (0.1922, 0.0000, -0.1670) pp21: (-0.1949, 0.0000, 0.1638) UnityEngine.Debug:Log(Object) TestProjection:TestProjectPoint() (at Assets/Editor/Tests/TestProjection.cs:15)
Is there a specific reason for the projection ins$$anonymous$$d of trigonometry?
Yep. I'm actually trying to compute a planar projection of a larger surface of the sphere. I'm creating a grid of equal area quads and then projecting a set of those quads onto a plane, given a center point. I could probably change to use great circle distances (I had thought about it) and then use that as the magnitude of my directional vector, but the directional vector using the rotation I think would still have the precision issue w/ rotation. The current magnitude precision w/ the same data points looks like:
pp12.mag: 0.254583 pp21.mag: 0.254640
UnityEngine.Debug:Log(Object)
If there is a better way of setting up a projection using trig, I'd love to hear about it. $$anonymous$$y trig is really rusty. Thanks!