For whatever its worth to anyone who might still come to this post (it was toward the top of Google for me), I used Sebastian's Atan2 for my solution and it worked quite well. In my case, I'm programmatically generating parameterized primitives in Unity, so the origin point is always (0, 0, 0), whether the primitive is 2D or 3D (for the sake of Mesh vertices). So for a sphere, I needed to order all of the vertices in a specific way so that regardless of the parameters, an int[] could be properly built for the triangles needed for the mesh.
My sorting is done using:
this.vertices = vertList.OrderByDescending(o => o.y)
.ThenBy(o => Utilities.GetAngle(o)).ToArray();
And the GetAngle()
method looks like this:
public static float GetAngle(Vector3 v)
{
return Mathf.Atan2(0, 0) - Mathf.Atan2(v.z, v.x);
}
It works to sort the list of vertices from top to bottom (so a 1 unit sphere would have a "top" point at (0f, 0.5f, 0f), and that would be the first vertex), and then ordered by the resulting float from the angular calculation along the X- and Z-planes. This sorting works wonderfully and surprisingly quickly for Linq
.
One additional note: because it ignores the Y-plane, it doesn't matter that each layer/level/band of vertices is at different points on the Y - it basically calculates each as if they were just at y = 0
. If you were trying to sort across X/Y or Y/Z, you could do the same thing just omitting the plane you want to ignore.
This would likely not work in more complex situations, or where your origin is not (0, 0, 0), but worked at least for my case.