public List <Segment3D> Calculate()
        {
            Vector3Extensions.EliminateDuplicatePoints(_polygonPointsOnSamePlane);
            if (_polygonPointsOnSamePlane.Count < 3)
            {
                return(new List <Segment3D>());
            }

            List <Vector3> workingPointList = new List <Vector3>(_polygonPointsOnSamePlane);

            Vector3 minPoint, maxPoint;

            CalculateInitialMinMaxPoints(out minPoint, out maxPoint);
            workingPointList.RemoveAll(item => item == minPoint || item == maxPoint);

            List <Segment3D> allHullSegments       = new List <Segment3D>();
            Segment3D        minMaxSegment         = new Segment3D(minPoint, maxPoint);
            Plane            minMaxSegmentPlane    = GetSegmentPlane(minMaxSegment);
            bool             furthestPointIsBehind = false;
            int indexOfPointFurthestFromPlane      = minMaxSegmentPlane.GetIndexOfFurthestPointInFront(workingPointList);

            if (indexOfPointFurthestFromPlane < 0)
            {
                indexOfPointFurthestFromPlane = minMaxSegmentPlane.GetIndexOfFurthestPointBehind(workingPointList);
                furthestPointIsBehind         = true;
            }
            if (indexOfPointFurthestFromPlane >= 0)
            {
                Vector3 furthestPointFromPlane = workingPointList[indexOfPointFurthestFromPlane];
                workingPointList.RemoveAt(indexOfPointFurthestFromPlane);

                List <Segment3D> hullSegments = new List <Segment3D>();
                if (furthestPointIsBehind)
                {
                    hullSegments.Add(new Segment3D(minMaxSegment.EndPoint, furthestPointFromPlane));
                    hullSegments.Add(new Segment3D(furthestPointFromPlane, minMaxSegment.StartPoint));
                    hullSegments.Add(minMaxSegment);
                    QuickHull(workingPointList, hullSegments);
                }
                else
                {
                    hullSegments.Add(new Segment3D(furthestPointFromPlane, minMaxSegment.EndPoint));
                    hullSegments.Add(new Segment3D(minMaxSegment.StartPoint, furthestPointFromPlane));
                    hullSegments.Add(new Segment3D(minMaxSegment.EndPoint, minMaxSegment.StartPoint));      // Reversed min-max segment
                    QuickHull(workingPointList, hullSegments);
                }

                allHullSegments.AddRange(hullSegments);
            }

            return(allHullSegments);
        }
Example #2
0
        public void SetPointsOnPolygonPlaneAndNormal(List <Vector3> pointsOnPolygonPlane, Vector3 polygonNormal)
        {
            _normal = polygonNormal;
            _normal.Normalize();

            var quickHull = new Polygon3DQuickHull(pointsOnPolygonPlane, polygonNormal);

            _edges = quickHull.Calculate();

            _pointsOnPolygonPlane.Clear();
            foreach (var edge in _edges)
            {
                _pointsOnPolygonPlane.Add(edge.StartPoint);
                _pointsOnPolygonPlane.Add(edge.EndPoint);
            }
            Vector3Extensions.EliminateDuplicatePoints(_pointsOnPolygonPlane);
        }