コード例 #1
0
ファイル: BspTree.cs プロジェクト: ibebbs/Uno.SfChart
        /// <summary>
        /// Cuts the out front polygon.
        /// </summary>
        /// <param name="polyPoints">The poly points.</param>
        /// <param name="vwiwc">The Vertical Index Classification.</param>
        /// <param name="points">The points.</param>
        private static void CutOutFrontPolygon(List <Vector3DIndexClassification> polyPoints, Vector3DIndexClassification vwiwc, List <Vector3D> points)
        {
            points.Clear();

            var curVW = vwiwc;

            while (true)
            {
                curVW.AlreadyCuttedFront = true;
                points.Add(curVW.Vector);

                var curVWPair = polyPoints[curVW.CuttingFrontPairIndex];

                if (curVW.CuttingFrontPoint)
                {
                    if (!curVWPair.AlreadyCuttedFront)
                    {
                        curVW = curVWPair;
                    }
                    else
                    {
                        var curVWPrev = polyPoints[BspTreeBuilder.GetNext(curVW.Index - 1, polyPoints.Count)];
                        var curVWNext = polyPoints[BspTreeBuilder.GetNext(curVW.Index + 1, polyPoints.Count)];

                        if ((curVWPrev.Result == ClassifyPointResult.OnFront) && !curVWPrev.AlreadyCuttedFront)
                        {
                            curVW = curVWPrev;
                        }
                        else
                        if ((curVWNext.Result == ClassifyPointResult.OnFront) && !curVWNext.AlreadyCuttedFront)
                        {
                            curVW = curVWNext;
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                else
                {
                    var curPrev = polyPoints[BspTreeBuilder.GetNext(curVW.Index - 1, polyPoints.Count)];
                    var curNext = polyPoints[BspTreeBuilder.GetNext(curVW.Index + 1, polyPoints.Count)];

                    if ((curPrev.Result != ClassifyPointResult.OnBack) && !curPrev.AlreadyCuttedFront)
                    {
                        curVW = curPrev;
                    }
                    else
                    if ((curNext.Result != ClassifyPointResult.OnBack) && !curNext.AlreadyCuttedFront)
                    {
                        curVW = curNext;
                    }
                    else
                    {
                        return;
                    }
                }
            }
        }
コード例 #2
0
ファイル: BspTree.cs プロジェクト: ibebbs/Uno.SfChart
        /// <summary>
        /// Split the polygon.
        /// </summary>
        /// <param name="poly">The Polygon</param>
        /// <param name="part">The Part</param>
        /// <param name="backPoly">The Back Polygon</param>
        /// <param name="frontPoly">The Front Polygon</param>
        private static void SplitPolygon(Polygon3D poly, Polygon3D part, out Polygon3D[] backPoly, out Polygon3D[] frontPoly)
        {
            var backP  = new List <Polygon3D>();
            var frontP = new List <Polygon3D>();

            // this code looks for points which lie on the part plane and divide polygon into two parts
            if (poly.Points != null)
            {
                var polyPoints      = new List <Vector3DIndexClassification>();
                var backPartPoints  = new List <Vector3DIndexClassification>();
                var frontPartPoints = new List <Vector3DIndexClassification>();

                var outpts = new List <Vector3D>();
                var inpts  = new List <Vector3D>();

                var count = poly.Points.Length;
                for (var i = 0; i < count; i++)
                {
                    var ptB   = poly.Points[i];
                    var ptC   = poly.Points[BspTreeBuilder.GetNext(i + 1, count)];
                    var sideB = ClassifyPoint(ptB, part);
                    var sideC = ClassifyPoint(ptC, part);

                    var vwiwcB = new Vector3DIndexClassification(ptB, polyPoints.Count, sideB);
                    polyPoints.Add(vwiwcB);

                    if ((sideB != sideC) && (sideB != ClassifyPointResult.OnPlane) &&
                        (sideC != ClassifyPointResult.OnPlane))
                    {
                        var v   = ptB - ptC;
                        var dir = part.Normal * (-part.D) - ptC;

                        var sv    = dir & part.Normal;
                        var sect  = sv / (part.Normal & v);
                        var ptP   = ptC + v * sect;
                        var vwiwc = new Vector3DIndexClassification(
                            ptP,
                            polyPoints.Count,
                            ClassifyPointResult.OnPlane);

                        polyPoints.Add(vwiwc);
                        backPartPoints.Add(vwiwc);
                        frontPartPoints.Add(vwiwc);
                    }
                    else
                    if (sideB == ClassifyPointResult.OnPlane)
                    {
                        var ptA   = poly.Points[BspTreeBuilder.GetNext(i - 1, count)];
                        var sideA = ClassifyPoint(ptA, part);
                        if ((sideA == sideC))
                        {
                            continue;
                        }

                        if ((sideA != ClassifyPointResult.OnPlane) && (sideC != ClassifyPointResult.OnPlane))
                        {
                            backPartPoints.Add(vwiwcB);
                            frontPartPoints.Add(vwiwcB);
                        }
                        else
                        if (sideA == ClassifyPointResult.OnPlane)
                        {
                            switch (sideC)
                            {
                            case ClassifyPointResult.OnBack:
                                backPartPoints.Add(vwiwcB);
                                break;

                            case ClassifyPointResult.OnFront:
                                frontPartPoints.Add(vwiwcB);
                                break;
                            }
                        }
                        else
                        if (sideC == ClassifyPointResult.OnPlane)
                        {
                            switch (sideA)
                            {
                            case ClassifyPointResult.OnBack:
                                backPartPoints.Add(vwiwcB);
                                break;

                            case ClassifyPointResult.OnFront:
                                frontPartPoints.Add(vwiwcB);
                                break;
                            }
                        }
                    }
                }

                if ((frontPartPoints.Count != 0) || (backPartPoints.Count != 0))
                {
                    for (var i = 0; i < backPartPoints.Count - 1; i += 2)
                    {
                        var vwiwc1 = backPartPoints[i];
                        var vwiwc2 = backPartPoints[i + 1];
                        vwiwc1.CuttingBackPoint     = true;
                        vwiwc2.CuttingBackPoint     = true;
                        vwiwc1.CuttingBackPairIndex = vwiwc2.Index;
                        vwiwc2.CuttingBackPairIndex = vwiwc1.Index;
                    }

                    for (var i = 0; i < frontPartPoints.Count - 1; i += 2)
                    {
                        var vwiwc1 = frontPartPoints[i];
                        var vwiwc2 = frontPartPoints[i + 1];
                        vwiwc1.CuttingFrontPoint     = true;
                        vwiwc2.CuttingFrontPoint     = true;
                        vwiwc1.CuttingFrontPairIndex = vwiwc2.Index;
                        vwiwc2.CuttingFrontPairIndex = vwiwc1.Index;
                    }

                    for (var i = 0; i < backPartPoints.Count - 1; i++)
                    {
                        var vwiwc = backPartPoints[i];
                        if (vwiwc.AlreadyCuttedBack)
                        {
                            continue;
                        }

                        BspTreeBuilder.CutOutBackPolygon(polyPoints, vwiwc, outpts);

                        if (outpts.Count > 2)
                        {
                            var points  = outpts.ToArray();
                            var polygon = new Polygon3D(points, poly);
                            polygon.CalcNormal(points[0], points[1], points[2]);
                            polygon.CalcNormal();
                            backP.Add(polygon);
                        }
                    }

                    for (var i = 0; i < frontPartPoints.Count - 1; i++)
                    {
                        var vwiwc = frontPartPoints[i];
                        if (vwiwc.AlreadyCuttedFront)
                        {
                            continue;
                        }

                        BspTreeBuilder.CutOutFrontPolygon(polyPoints, vwiwc, inpts);
                        if (inpts.Count > 2)
                        {
                            var points  = inpts.ToArray();
                            var polygon = new Polygon3D(points, poly);
                            polygon.CalcNormal(points[0], points[1], points[2]);
                            polygon.CalcNormal();
                            frontP.Add(polygon);
                        }
                    }
                }
            }
            else
            {
                backP.Add(poly);
                frontP.Add(poly);
            }

            backPoly  = backP.ToArray();
            frontPoly = frontP.ToArray();
        }
コード例 #3
0
ファイル: BspTree.cs プロジェクト: ibebbs/Uno.SfChart
        /// <summary>
        /// Builds the specified collection of polygons.
        /// </summary>
        /// <param name="arlist">The collection of polygons.</param>
        /// <returns>Returns the built <see cref="BspNode"/>.</returns>
        public BspNode Build(List <Polygon3D> arlist)
        {
            if (arlist.Count < 1)
            {
                return(null);
            }

            var bspNode = new BspNode();
            var plane   = arlist[0];

            bspNode.Plane = plane;
            var arleft  = new List <Polygon3D>(arlist.Count);
            var arright = new List <Polygon3D>(arlist.Count);

            for (int i = 1, len = arlist.Count; i < len; i++)
            {
                var pln = arlist[i];

                if (pln == plane)
                {
                    continue;
                }

                var r = ClassifyPolygon(plane, pln);

                switch (r)
                {
                case ClassifyPolyResult.OnPlane:
                case ClassifyPolyResult.ToRight:
                    arright.Add(pln);
                    break;

                case ClassifyPolyResult.ToLeft:
                    arleft.Add(pln);
                    break;

                case ClassifyPolyResult.Unknown:
                    if (pln is Line3D || pln is UIElement3D)
                    {
                        arleft.Add(pln);
                    }
                    else if (pln is PolyLine3D)
                    {
                        arright.Add(pln);
                    }
                    else
                    {
                        Polygon3D[] ps1, ps2;
                        BspTreeBuilder.SplitPolygon(pln, plane, out ps1, out ps2);
                        arleft.AddRange(ps1);
                        arright.AddRange(ps2);
                    }

                    break;
                }
            }

            if (arleft.Count > 0)
            {
                bspNode.Back = this.Build(arleft);
            }

            if (arright.Count > 0)
            {
                bspNode.Front = this.Build(arright);
            }

            return(bspNode);
        }