I want to find out the correct order of a set of vertex in a polygon that is given in unordered way. For this issue, I develop an algorithm based on computational geometry concepts. First, I get the convex hull of the set of vertex sorted in counterclockwise. Then, I keep with the remaining vertices sorted by its polar angle, starting for a pivot which is the vertex with the lowest X coordenate, and I will insert then using the absolute value of the cross product compute between the vertex that I want to add and the two end points of the edge in the convex hull. With this information I will insert the corresponding vertex between the two point with lowest absolute value on its cross product, same as I explain above.
Here is my problem, this heuristic not always is true and I having problems to get the sorted sequence of vertex of the polygon. Is important keep in mind that the polygon could be a complex polygon. I want to know if there is any algorithm that allow me do that in a more consistent way, or someone could help me to improve the algorithm explained above.
Here, an snippet of my code, if not enough ask me more, and using c# and .NET 4.5:
var CH = JarvisMarch(P); // P is the set of unsorted vertex of the polygon
var V = (from v in P where !CH.Contains(v) select v).ToArray();
var pivot = (from v in V orderby v.Y, v.X select v).FirstOrDefault();
if (CH.Count < P.Length)
{
QuickSortPolar(ref V, 0, V.Length - 1, pivot);
foreach (var rm in V)
{
var C = CH.ToArray();
var T = new RedBlackTree(); // this is not entirely necessary
var wlk = new List<IComparable>();
var min = float.MaxValue;
var succ = default(GeometryVertex); // this structure have the X and Y coordenate of the vertex
QuickSortCoorX(ref C, 0, C.Length - 1); // for the sweep plane algorithm
for (int i = 0; i < C.Length; i++) // this is just to build the segments in a appropriate way
{
var j = CH.IndexOf(C[i]) == CH.Count - 1 ?
0 : CH.IndexOf(C[i]) + 1;
var sgm = new GeometrySegment()
{
Start = CH[j == 0 ? CH.Count - 1 : j - 1],
End = CH[j]
};
var find = T.Search(sgm);
if (find == null || find == RedBlackTree.sentinel)
T.Insert(sgm);
}
T.Inorder(T.root, ref wlk);
foreach (var sgm in wlk) // Here is the key of the algorithm
{
var s = (GeometrySegment)sgm;
var curr = (float)Math.Abs(cw(s.Start, rm, s.End));
if (curr < min || (curr == min && s.End < succ))
{
min = curr;
succ = s.End;
}
}
CH.Insert(CH.IndexOf(succ), rm);
}
Thanks in advanced!!
PD: If any step of the algorithm explained above is not clear and any need more information for help me with the issue, feel free to ask.