- Home /
Transforming Spherical Surface to a Planar Surface
Hello everyone! I am currently working on a personal project whose aim is to transform a section of a spherical surface into a planar surface. Later stages of this project may transform the whole spherical surface into a plane, but, I will cross that bridge when it comes as there are numerous challenges such as providing a seamless integration of it.
There are two major points around which this entire process is being made -- the first point is that the spherical world (which is a spheroid) is composed completely of triangles. Here, this image should help you understand what I mean by that:
The idea is that every triangle has a gravitational vector that points at the center of the spheroid, which is in contrast to the gravitational vectors exhibited by all points on a plane which are all facing uniformly "downwards". Put simply, this surface transformation re-orients all of the triangles in a given section of the surface based on the re-orientation of their gravitational vectors (from pointing at the center of the spheroid to pointing uniformly "downwards"). The following picture should help you understand this idea:
I have so far written code that stores an array of triangles which have expanded out from the center triangle. These triangles serve as the surface which will be transformed into a plane. Here is a video showing the gathering of these triangles:
There are numerous special steps and cases in the fine print when trying to perform a transformation like this with very specific answers, some of which are obvious and some of which are very nebulous. For example, all of the triangles share points with their neighbor triangles -- if we change the position of one point to alter one triangle, we are also fundamentally changing the characteristics of the triangles that share that point. In other words, purposely changing one triangle passively changes neighboring triangles. The question is, what do these passive changes to neighboring triangles represent and how do we deal with them? These are the real questions that need to be answered, and here is an image that might help you understand these questions:
This image shows of two particular cases where the alteration of triangles affects other triangles. The first case is when two triangles are supposed to be re-oriented using the same point. The second case is when all three points of a triangle have been passively altered. Altering this "trapped triangle" would change the triangles that have been altered before it.
I have just come to the point where I'm writing the script to actually transform the surface into a plane, but, this is definitely the hardest part of this project and may take me a while to complete.
I posted this because I was wondering if anyone can see any obvious problems or flaws in this surface transformation at the very general low detail level I have presented.
Answer by Bunny83 · Jan 06, 2017 at 01:07 PM
Well, first of all you should keep in mind that it is impossible to turn a spherical surface into a planar surface without massive distortion. There are many different ways how one could project a sphere onto a plane. Mankind has a lot experience with that kind of projection since we live on a sphere ^^.
The question is what kind of result you want to get in the end. If you always pick a single vertex / triangle and want to unwrap the sphere around that vertex / triangle, there are several ways to approach this.
One would be to use a classic Mercator projection. To keep the topography of your sphere you usually use a reference sphere and measure the "height" of each vertex in relation to the reference sphere. Now you simply convert the cartesian coordinates of each vertex into spherical coordinates. So you should have a polar angle between 0 and 360 (or -180 and 180) and an azimuth angle +- 90. Finally you have your elevation / relative radius. The mercator projection simply treats the polar angle as x axis and the azimuth angle as y axis. Note that the poles of the sphere will be infinitely large. The whole top and the whole bottom line of your plane is actually the same point on the sphere.
The distortion gets more and more the closer you get to the poles when using mercator.
For other projections, see Map projections.
edit
For your specific "partial sphere" case it's probably the easiest way to use an azimuthal projection. It will have the best results around the center point and the worst on the opposite side of the sphere. Here the conversion is from spherical coordinates to circle coordinates. So the polar angle stays an angle but the azimuth angle is treated as circle radius.
If you project earth like this with the north pole as center, the south pole would stretch around the resulting circle.
edit2
If you have trouble converting between cartesian and spherical coordinates, here are two methods i've quickly written from scratch:
Vector3 ToSpherical(Vector3 aCartesian)
{
return ToSpherical(aCartesian, Quaternion.identity);
}
Vector3 ToSpherical(Vector3 aCartesian, Quaternion aSpace)
{
var q = Quaternion.Inverse(aSpace);
var len = aCartesian.magnitude;
var v = q * aCartesian / len;
Vector3 result;
result.x = Mathf.Atan2(v.z, v.x);
result.y = Mathf.Asin(v.y);
result.z = len;
return result;
}
Vector3 ToCartesian(Vector3 aSpherical)
{
return ToCartesian(aSpherical, Quaternion.identity );
}
Vector3 ToCartesian(Vector3 aSpherical, Quaternion aSpace)
{
Vector3 result;
float c = Mathf.Cos(aSpherical.y);
result.x = Mathf.Cos(aSpherical.x) * c;
result.y = Mathf.Sin(aSpherical.y);
result.z = Mathf.Sin(aSpherical.x) * c;
result *= aSpherical.z;
result = aSpace * result;
return result;
}
The optional "space" is the space where the cartesian coordinates are defined in. Note that the spherical coordinates are specified in radians. So "x" is in range "-PI to PI" and y is in range -PI/2 to PI/2.
If you want them in degree you can multiply them with Mathf.Rad2Deg. In degree x will be in range -180 to 180 and y in range -90 to 90.
Wow, bunny, thanks! I will take a deeper look at the different methods you provided in your post. I feel like I saw this project as the tip of the iceberg when I started and now I'm actually feeling what's beneath.
Do you happen to know what the most accurate projection is?
Thanks again, Yuri
To quote the wikipedia article:
The mathematics of projection do not permit any particular map projection to be "best" for everything. Something will always get distorted. Therefore, a diversity of projections exists to service the many uses of maps and their vast range of scales.
As i already said in my first edit an azimuthal projection is probably the best for your case as the center has the least distortion.
To convert spherical coordinates to flat circle coordinates you can use:
Vector3 ToCircle (Vector3 aSpherical, float aRadius)
{
Vector3 result;
float r = -aRadius * (aSpherical.y - $$anonymous$$athf.PI/2) / $$anonymous$$athf.PI;
result.x = $$anonymous$$athf.Cos(aSpherical.x)*r;
result.y = aSpherical.z;
result.z = $$anonymous$$athf.Sin(aSpherical.x)*r;
return result;
}
Where "aRadius" is the maximum radius of the projected circle
To center the projection on a certain point on the sphere you can do something like this:
var p = transform.InverseTransformPoint(hit.point);
var r = Vector3.Cross(p, Vector3.up).normalized;
var up = Vector3.Cross(r, p).normalized;
var q = Quaternion.LookRotation(up, p.normalized);
// perform the projection of all vertices
for (int i = 0; i < vertices.Count; i++)
{
var v = ToSpherical(vertices[i], q);
v = ToCircle(v, 10);
//v.y -= $$anonymous$$SphereRadius; // optional, make the planar mesh origin be right below the mesh
vertices[i] = v;
}
Answer by slammin · Jan 18, 2017 at 09:28 PM
This is a follow up that contains an interesting observation of the rough success of this project and a couple of videos.
There is an interesting observation that I did not expect when I flattened the sphere into a plane -- it flattened into a circle!
I'm not sure what can be gleaned from the fact that the sphere flattens into a circle, but there may be something mathematically intellectual there.
As you approach the outer edge of the circle the triangles really do begin to break apart. I'm pretty sure I know the cause of this but I will spare any attempt of sharing it. So, the solution to these broken triangles was simply to average all common points between all triangles, shown in the following video:
In any case, there are still a couple of tiny problems with the script, such as flagrant triangles on the outer rim who seem to transform incorrectly, primarily because they are approaching the 180˚mark relative to the origin triangle.
That's it for now. Thanks for reading and thanks for the help!
Answer by cmcintosh · Jan 27, 2018 at 10:00 AM
I would take a look at how map projections work, i think something could be developed from that. https://en.wikipedia.org/wiki/Mercator_projection
Uhm, the $$anonymous$$ercator projection was the first i've mentioned in my answer ... ^^