Sort a set of 3-D points in clockwise/counter-clockwise order

后端 未结 2 976
野趣味
野趣味 2020-12-28 22:56

In 3-D space I have an unordered set of, say, 6 points; something like this:

           (A)*
                          (C)*
(E)*
                         (F)         


        
2条回答
  •  爱一瞬间的悲伤
    2020-12-28 23:27

    I can't attest for the efficiency of this code, but it works, and you can optimize parts of it as needed, I'm just not good at it.
    Code is in C#, using system collection classes, and linq.
    Vector3 is a class with floats x, y, z, and static vector math functions.
    Node is a class with Vector3 variable called pos

    //Sort nodes with positions in 3d space.
    //Assuming the points form a convex shape.
    //Assuming points are on a single plain (or close to it).
    
    public List sortVerticies( Vector3 normal, List nodes ) {
    
        Vector3 first = nodes[0].pos;
    
        //Sort by distance from random point to get 2 adjacent points.
        List temp = nodes.OrderBy(n => Vector3.Distance(n.pos, first ) ).ToList();
    
        //Create a vector from the 2 adjacent points,
        //this will be used to sort all points, except the first, by the angle to this vector.
        //Since the shape is convex, angle will not exceed 180 degrees, resulting in a proper sort.
        Vector3 refrenceVec = (temp[1].pos - first);
    
        //Sort by angle to reference, but we are still missing the first one.
        List results = temp.Skip(1).OrderBy(n => Vector3.Angle(refrenceVec,n.pos - first)).ToList();
    
        //insert the first one, at index 0.
        results.Insert(0,nodes[0]);
    
        //Now that it is sorted, we check if we got the direction right, if we didn't we reverse the list.
        //We compare the given normal and the cross product of the first 3 point.
        //If the magnitude of the sum of the normal and cross product is less than Sqrt(2) then then there is more than 90 between them.
        if ( (Vector3.Cross( results[1].pos-results[0].pos, results[2].pos - results[0].pos ).normalized + normal.normalized).magnitude < 1.414f ) {
            results.Reverse();
        }
    
        return results;
    }
    

提交回复
热议问题