# Bijection between spherical and planar triangle surfaces

I subdivide a unit sphere, centered at origin, onto 20 spherical triangles. For the sake of argument let's take one such triangle $$Ts$$, in $$\mathbb{R}^3$$, that has vertices $$Normalize(-1,0,g), Normalize(0,g,1)$$, and $$Normalize(1,0,g)$$, where $$g = \frac{1.0+\sqrt{5}}{2}$$.

In the same time there is another equilateral planar triangle $$Tp$$, in $$\mathbb{R}^2$$, that has the following vertices $$(0,0), (1,0),(0.5, \frac{\sqrt{3}}{2})$$.

I'm looking for a projection (exact formula) that would create bijection of surface points of $$Ts$$ to surface points of $$Tp$$. It's crucial that such mapping maximize uniformity of distortions (not sure how to express this in strict math terms).

• Take any similitude carrying the vertices of $Ts$ to $Tp$, followed by the obvious "flattening" of $Ts$. – Aretino Feb 10 at 20:45
• I'm good with transforming $Ts$ vertexes to $Tp$ ones. They match perfectly. However I'm clearly struggling with "flattening" part. With naive (inverse $Tp$, in $\mathbb{R}^2$ to $Ts$, in $\mathbb{R}^3$) mapping I'm getting points that are outside of the planar triangle. See the picture: i.snag.gy/GVYsAX.jpg Red marks represent roughly where the edge of my planar triangle is. – lhog Feb 10 at 22:09

Suppose then you applied a suitable transformation, so that the vertices of the spherical triangle are the same as the vertices of the plane triangle, sitting then on plane $$z=0$$. Let $$O=(x_0,y_0,z_0)$$ be the center of the transformed sphere and $$P=(x,y,z)$$ any point on the spherical triangle. You can then:

1. Apply a translation carrying $$O$$ at the origin: $$P\to P-O=(x-x_0,y-y_0,z-z_0)$$;

2. Slide $$P$$ along $$PO$$ until its $$z$$ coordinate becomes $$-z_0$$: $$P\to {-z_0\over z-z_0}P=\left(-{x-x_0\over z-z_0}z_0,-{y-y_0\over z-z_0}z_0,-z_0 \right);$$

3. Translate back: $$P\to P+(x_0,y_0,z_0)=\left({x_0z-xz_0\over z-z_0},{y_0z-yz_0\over z-z_0},0 \right).$$ Please ask if anything is not clear.

• I'm yet to try this. Let me ask you one question in advance though. – lhog Feb 11 at 23:57
• Sincere "thank you" for your answer. I'm sure it's right, but unfortunately I've just managed to solve it myself. I guess I'll add my own answer for the sake of future reader's awareness. – lhog Feb 12 at 0:11

I'm sure that the answer @Aretino provided works too, but I'm leaving my own solution for the sake of completeness.

So this is what I have done myself. As readers might have guessed my goal was to try to project surface points within icosahedron face onto respective spherical triangle. The issue I had was that with naive mapping spherical triangle would "take" planar surface points that are outside of planar triangle. See my lame picture, where I outlined the rough edge of planar triangle on of the sides: https://i.snag.gy/GVYsAX.jpg

Initially I did the mapping the following way:

• get barycentric coordinates: $$baryP = getTriangleBarycentric(pos, icoFace[0], icoFace[1], icoFace[2]);$$

$$pos$$ is point on the sphere. $$icoFace[0..3]$$ are vertexes of an icosahedron and corresponding spherical triangle.

• $$planarPoint$$ = $$baryP.x * [0.0, 0.0] + baryP.y * [1.0, 0.0] + baryP.z * [0.5, \frac{\sqrt{3}}{2}]$$

$$planarPoint$$ is two component vector that represents points of triangle I map from. $$[0.0, 0.0] ; [1.0, 0.0] ; [0.5, \frac{\sqrt{3}}{2}]$$ are points of triangle I do mapping from. Note: this triangle is similar (and equilateral) to original icosahedron planar triangle. It's just a matter of preference to work with "unit" triangle.

So that was the original approach and it didn't work.

What made it work is the following transformation of $$pos$$ before it's used to calculate barycentric coordinate corresponding to $$pos$$.

$$triangleToPointDist = DistancePointToTriangle(pos, icoFace[0], icoFace[1], icoFace[2])$$ $$pos = pos * (1.0 - triangleToPointDist)$$

These two lines essentially project $$pos$$ from being on spherical triangle surface to being on icosahedron's triangle.

The lack of projection from sphere to planar triangle of icodahedron was my only mistake.

P.S. As I do it for WebGL shader (a program that is executed on GPU), I just can't resist temptation to share the link to the excellent final result: https://shaderfrog.com/app/view/2360