Get border edges of mesh - in winding order

后端 未结 3 1429
心在旅途
心在旅途 2021-02-12 22:04

I have a triangulated mesh. Assume it looks like an bumpy surface. I want to be able to find all edges that fall on the surrounding border of the mesh. (forget about inner verti

3条回答
  •  遥遥无期
    2021-02-12 23:01

    Well as the saying goes - get it working - then get it working better. I noticed on my above example it assumes all the edges in the edges array do in fact link up in a nice border. This may not be the case in the real world (as I have discovered from my input files i am using!) In fact some of my input files actually have many polygons and all need borders detected. I also wanted to make sure the winding order is correct. So I have fixed that up as well. see below. (Feel I am making headway at last!)

        private static List OrganizeEdges(List edges, List positions)
        {
            var visited = new Dictionary();
            var edgeList = new List();
            var resultList = new List();
            var nextIndex = -1;
            while (resultList.Count < edges.Count)
            {
                if (nextIndex < 0)
                {
                    for (int i = 0; i < edges.Count; i += 2)
                    {
                        if (!visited.ContainsKey(i))
                        {
                            nextIndex = edges[i];
                            break;
                        }
                    }
                }
    
                for (int i = 0; i < edges.Count; i += 2)
                {
                    if (visited.ContainsKey(i))
                        continue;
    
                    int j = i + 1;
                    int k = -1;
                    if (edges[i] == nextIndex)
                        k = j;
                    else if (edges[j] == nextIndex)
                        k = i;
    
                    if (k >= 0)
                    {
                        var edge = edges[k];
                        visited[i] = true;
                        edgeList.Add(nextIndex);
                        edgeList.Add(edge);
                        nextIndex = edge;
                        i = 0;
                    }
                }
    
                // calculate winding order - then add to final result.
                var borderPoints = new List();
                edgeList.ForEach(ei => borderPoints.Add(positions[ei]));
                var winding = CalculateWindingOrder(borderPoints);
                if (winding > 0)
                    edgeList.Reverse();
    
                resultList.AddRange(edgeList);
                edgeList = new List();
                nextIndex = -1;
            }
    
            return resultList;
        }
    
    
    
    
        /// 
        /// returns 1 for CW, -1 for CCW, 0 for unknown.
        /// 
        public static int CalculateWindingOrder(IList points)
        {
            // the sign of the 'area' of the polygon is all we are interested in.
            var area = CalculateSignedArea(points);
            if (area < 0.0)
                return 1;
            else if (area > 0.0)
                return - 1;        
            return 0; // error condition - not even verts to calculate, non-simple poly, etc.
        }
    
        public static double CalculateSignedArea(IList points)
        {
            double area = 0.0;
            for (int i = 0; i < points.Count; i++)
            {
                int j = (i + 1) % points.Count;
                area += points[i].X * points[j].Y;
                area -= points[i].Y * points[j].X;
            }
            area /= 2.0f;
    
            return area;
        }
    

提交回复
热议问题