Beispiel #1
0
        /// <summary>
        /// Renders the front polygon.
        /// </summary>
        /// <param name="point1">The Points Array</param>
        /// <param name="startDepth">The Start Depth</param>
        /// <param name="endDepth">The End Depth</param>
        /// <param name="color">The Color</param>
        private void RenderFrontPolygon(double[] point1, double startDepth, double endDepth, Brush color)
        {
            Vector3D[] frontVectors = new Vector3D[]
            {
                new Vector3D(point1[0], point1[1], startDepth),
                new Vector3D(point1[2], point1[3], startDepth),
                new Vector3D(point1[4], point1[5], startDepth),
                new Vector3D(point1[6], point1[7], startDepth),
                new Vector3D(point1[8], point1[9], startDepth)
            };

            Vector3D[] backVectors = new Vector3D[]
            {
                new Vector3D(point1[0], point1[1], endDepth),
                new Vector3D(point1[2], point1[3], endDepth),
                new Vector3D(point1[4], point1[5], endDepth),
                new Vector3D(point1[6], point1[7], endDepth),
                new Vector3D(point1[8], point1[9], endDepth)
            };

            Polygon3D frontPolygon = new Polygon3D(frontVectors, this, 0, Stroke, 1, color);

            frontPolygon.CalcNormal(frontVectors[0], frontVectors[1], frontVectors[2]);
            frontPolygon.CalcNormal();
            this.area.Graphics3D.AddVisual(frontPolygon);

            Polygon3D backPolygon = new Polygon3D(backVectors, this, 0, Stroke, 1, color);

            backPolygon.CalcNormal(backVectors[0], backVectors[1], backVectors[2]);
            backPolygon.CalcNormal();
            this.area.Graphics3D.AddVisual(backPolygon);
        }
Beispiel #2
0
        /// <summary>
        /// Method used to remove the polygon in Queue.
        /// </summary>
        /// <param name="points">The Points</param>
        /// <param name="tag">The Tag</param>
        /// <param name="index">The Index</param>
        /// <param name="stroke">The stroke</param>
        /// <param name="strokeThickness">The stroke Thickness</param>
        /// <param name="fill">The Fill</param>
        /// <returns>Returns the polygon.</returns>
        public Polygon3D DequeuePolygon(Vector3D[] points, DependencyObject tag, int index, Brush stroke, double strokeThickness, Brush fill)
        {
            if (polygonCache.Count > pointer)
            {
                polygon         = polygonCache[pointer];
                polygon.Element = new Path();
                polygon.Tag     = tag;
                polygon.Index   = index;
                polygon.Stroke  = stroke;
                polygon.CalcNormal(points[0], points[1], points[2]);
                polygon.VectorPoints = points;
                polygon.CalcNormal();

                pointer++;
            }
            else if (polygonCache.Count <= pointer)
            {
                polygon = new Polygon3D(points, tag, index, stroke, strokeThickness, fill);
                polygon.CalcNormal(points[0], points[1], points[2]);
                polygon.CalcNormal();
                polygonCache.Add(polygon);
                pointer++;
            }

            return(polygon);
        }
Beispiel #3
0
        /// <summary>
        /// Creates the sector.
        /// </summary>
        /// <returns>Returns the sector.</returns>
        internal Polygon3D[][] CreateSector()
        {
            Points.Clear();
            var count = (int)Math.Ceiling(ActualEndValue / 6d);

            if (count < 1d)
            {
                return(null);
            }
            var res = new Polygon3D[4][];
            var f   = ActualEndValue / count;

            var opts = new Point[count + 1];
            var ipts = new Point[count + 1];

            for (var i = 0; i < count + 1; i++)
            {
                var ox = (float)(Center.X + radius * Math.Cos((ActualStartValue + i * f) * DtoR));
                var oy = (float)(Center.Y + radius * Math.Sin((ActualStartValue + i * f) * DtoR));

                opts[i] = new Point(ox, oy);

                var ix = (float)(Center.X + inSideRadius * Math.Cos((ActualStartValue + i * f) * DtoR));
                var iy = (float)(Center.Y + inSideRadius * Math.Sin((ActualStartValue + i * f) * DtoR));

                ipts[i] = new Point(ix, iy);
                Points.Add(new Point(ox, oy));
            }

            var oplgs = new Polygon3D[count];

            #region outside rounded polygons

            for (var i = 0; i < count; i++)
            {
                Vector3D[] vts =
                {
                    new Vector3D(opts[i].X,     opts[i].Y,         0),
                    new Vector3D(opts[i].X,     opts[i].Y,     depth),
                    new Vector3D(opts[i + 1].X, opts[i + 1].Y, depth),
                    new Vector3D(opts[i + 1].X, opts[i + 1].Y, 0)
                };

                oplgs[i] = new Polygon3D(vts, this, Index, Stroke, StrokeThickness, Interior);
                oplgs[i].CalcNormal(vts[0], vts[1], vts[2]);
                oplgs[i].CalcNormal();
            }

            res[1] = oplgs;
            #endregion

            #region inside rounded polygons for doughnut

            if (inSideRadius > 0)
            {
                var iplgs = new Polygon3D[count];

                for (int i = 0; i < count; i++)
                {
                    var vts = new[]
                    {
                        new Vector3D(ipts[i].X, ipts[i].Y, 0),
                        new Vector3D(ipts[i].X, ipts[i].Y, depth),
                        new Vector3D(ipts[i + 1].X, ipts[i + 1].Y, depth),
                        new Vector3D(ipts[i + 1].X, ipts[i + 1].Y, 0)
                    };

                    iplgs[i] = new Polygon3D(vts, this, Index, Stroke, StrokeThickness, Interior);
                    iplgs[i].CalcNormal(vts[0], vts[1], vts[2]);
                    iplgs[i].CalcNormal();
                }

                res[3] = iplgs;
            }
            #endregion

            #region front and backside polygons(similar 2D accumulation)

            var tvtxs = new List <Vector3D>();
            var bvtxs = new List <Vector3D>();

            for (int i = 0; i < count + 1; i++)
            {
                tvtxs.Add(new Vector3D(opts[i].X, opts[i].Y, 0));
                bvtxs.Add(new Vector3D(opts[i].X, opts[i].Y, depth));
            }

            if (inSideRadius > 0)
            {
                for (int i = count; i > -1; i--)
                {
                    tvtxs.Add(new Vector3D(ipts[i].X, ipts[i].Y, 0));
                    bvtxs.Add(new Vector3D(ipts[i].X, ipts[i].Y, depth));
                }
            }
            else
            {
                tvtxs.Add(Center);
                bvtxs.Add(new Vector3D(Center.X, Center.Y, depth));
            }

            var poly1 = new Polygon3D(tvtxs.ToArray(), this, Index, Stroke, StrokeThickness, Interior);
            poly1.CalcNormal(tvtxs.ToArray()[0], tvtxs.ToArray()[1], tvtxs.ToArray()[2]);
            poly1.CalcNormal();
            var poly2 = new Polygon3D(bvtxs.ToArray(), this, Index, Stroke, StrokeThickness, Interior);
            poly2.CalcNormal(bvtxs.ToArray()[0], bvtxs.ToArray()[1], bvtxs.ToArray()[2]);
            poly2.CalcNormal();
            res[0] = new[] { poly1, poly2 };
            #endregion

            #region Inside two polygons for every segments

            if (inSideRadius > 0)
            {
                Vector3D[] rvts =
                {
                    // To avoid overlap subtract 0.1 value for every segment start value(90 to 270 dgree)
                    // and add 0.1 value for (270-360 and 0-90 degree)
                    new Vector3D(opts[0].X, (ActualStartValue >= 0 && ActualStartValue <= 90) || (ActualStartValue >= 270 && ActualStartValue <= 360) ? opts[0].Y + 0.1 : opts[0].Y - 0.1,     0),
                    new Vector3D(opts[0].X, (ActualStartValue >= 0 && ActualStartValue <= 90) || (ActualStartValue >= 270 && ActualStartValue <= 360) ? opts[0].Y + 0.1 : opts[0].Y - 0.1, depth),
                    new Vector3D(ipts[0].X, ipts[0].Y,                                                                                                                                     depth),
                    new Vector3D(ipts[0].X, ipts[0].Y, 0)
                };

                Vector3D[] lvts =
                {
                    new Vector3D(opts[count].X, opts[count].Y,     0),
                    new Vector3D(opts[count].X, opts[count].Y, depth),
                    new Vector3D(ipts[count].X, ipts[count].Y, depth),
                    new Vector3D(ipts[count].X, ipts[count].Y, 0)
                };

                var poly3 = new Polygon3D(rvts, this, Index, Stroke, StrokeThickness, Interior);
                poly3.CalcNormal(rvts[0], rvts[1], rvts[2]);
                poly3.CalcNormal();

                var poly4 = new Polygon3D(lvts, this, Index, Stroke, StrokeThickness, Interior);
                poly4.CalcNormal(lvts[0], lvts[1], lvts[2]);
                poly4.CalcNormal();

                res[2] = new[]
                {
                    poly3, poly4
                };
            }
            else
            {
                Vector3D[] rvts =
                {
                    new Vector3D(opts[0].X, (ActualStartValue >= 0 && ActualStartValue <= 90) || (ActualStartValue >= 270 && ActualStartValue <= 360) ? opts[0].Y + 0.1 : opts[0].Y - 0.1,     0),
                    new Vector3D(opts[0].X, (ActualStartValue >= 0 && ActualStartValue <= 90) || (ActualStartValue >= 270 && ActualStartValue <= 360) ? opts[0].Y + 0.1 : opts[0].Y - 0.1, depth),
                    new Vector3D(Center.X,  Center.Y,                                                                                                                                      depth),
                    new Vector3D(Center.X,  Center.Y, 0)
                };

                Vector3D[] lvts =
                {
                    new Vector3D(opts[count].X, opts[count].Y,     0),
                    new Vector3D(opts[count].X, opts[count].Y, depth),
                    new Vector3D(Center.X,      Center.Y,      depth),
                    new Vector3D(Center.X,      Center.Y, 0)
                };

                var poly5 = new Polygon3D(rvts, this, Index, Stroke, StrokeThickness, Interior);
                poly5.CalcNormal(rvts[0], rvts[1], rvts[2]);
                poly5.CalcNormal();

                var poly6 = new Polygon3D(lvts, this, Index, Stroke, StrokeThickness, Interior);
                poly6.CalcNormal(lvts[0], lvts[1], lvts[2]);
                poly6.CalcNormal();

                res[2] = new[]
                {
                    poly5,
                    poly6
                };
            }
            #endregion
            return(res);
        }
Beispiel #4
0
        /// <summary>
        /// Updates the segments based on its data point value. This method is not
        /// intended to be called explicitly outside the Chart but it can be overridden by
        /// any derived class.
        /// </summary>
        /// <param name="transformer">Represents the view port of chart control.(refer <see cref="IChartTransformer"/>)</param>
        public override void Update(IChartTransformer transformer)
        {
            ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer;
            if (cartesianTransformer != null)
            {
                Polygon3D    bottomPolygon, topPolygon, startPolygon, endPolygon;
                LineSeries3D lineSeries = Series as LineSeries3D;
                if (this.area == null || this.xValues.Count == 1 || lineSeries.StrokeThickness == 0)
                {
                    return;
                }
                var    xBase          = cartesianTransformer.XAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.XAxis).LogarithmicBase : 1;
                var    yBase          = cartesianTransformer.YAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.YAxis).LogarithmicBase : 1;
                var    xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic;
                var    yIsLogarithmic = cartesianTransformer.YAxis.IsLogarithmic;
                double xStart         = xIsLogarithmic ? Math.Pow(xBase, cartesianTransformer.XAxis.VisibleRange.Start) : cartesianTransformer.XAxis.VisibleRange.Start;
                double xEnd           = xIsLogarithmic ? Math.Pow(xBase, cartesianTransformer.XAxis.VisibleRange.End) : cartesianTransformer.XAxis.VisibleRange.End;
                var    yStart         = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.Start) : cartesianTransformer.YAxis.VisibleRange.Start;
                var    yEnd           = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.End) : cartesianTransformer.YAxis.VisibleRange.End;

                // Clipping the line series 3D
                if (xValues.Min() < xStart)
                {
                    while (this.xValues[0] < xStart)
                    {
                        this.xValues.RemoveAt(0);
                        this.yValues.RemoveAt(0);
                    }
                }

                if (this.xValues.Max() > xEnd)
                {
                    int index = this.xValues.IndexOf(xEnd);
                    while (this.xValues[index + 1] > xEnd)
                    {
                        this.xValues.RemoveAt(index + 1);
                        this.yValues.RemoveAt(index + 1);
                        if (index >= this.xValues.Count - 1)
                        {
                            break;
                        }
                    }
                }

                var indexes = from val in this.yValues.ToList() where (val <yStart || val> yEnd) select this.yValues.IndexOf(val);

                if (this.yValues.Count - indexes.Count() < 2)
                {
                    return;
                }
                if (indexes.Count() > 0)
                {
                    foreach (var index in indexes)
                    {
                        if (yValues[index] < yStart)
                        {
                            this.yValues[index] = yStart;
                        }
                        else
                        {
                            this.yValues[index] = yEnd;
                        }
                    }
                }

                //// End of clipping logic

                double x             = this.xValues[0];
                double y             = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[0] : (this.Y < this.yValues[0] && this.Y > 0) ? this.Y : this.yValues[0];
                Point  previousPoint = transformer.TransformToVisible(x, y);
                Point  currentPoint;

                this.point2  = new double[10];
                this.point1  = new double[10];
                x            = this.xValues[1];
                y            = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[1] : (this.Y < this.yValues[1] && Y > 0) ? this.Y : this.yValues[1];
                currentPoint = transformer.TransformToVisible(x, y);
                int leftThickness  = lineSeries.StrokeThickness / 2;
                int rightThickness = (lineSeries.StrokeThickness % 2 == 0
                                                ? (lineSeries.StrokeThickness / 2) - 1
                                                : lineSeries.StrokeThickness / 2);
                LineSegment3D.GetLinePoints(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y, leftThickness, rightThickness, this.point1);
                int j = 0;

                // To reset the polygon recycler collection index.
                this.polygonRecycler.Reset();

                for (int i = 1; i < this.yValues.Count;)
                {
                    this.point2   = new double[10];
                    previousPoint = currentPoint;
                    bool isMultiColor = (Series.SegmentColorPath != null || Series.Palette != ChartColorPalette.None);
                    this.color = isMultiColor
                                      ? (Series.GetInteriorColor(i - 1))
                                      : (this.Interior);

                    if (i == 1)
                    {
                        Vector3D[] startPolygonVects = new Vector3D[]
                        {
                            new Vector3D(this.point1[6], this.point1[7], startDepth),
                            new Vector3D(this.point1[6], this.point1[7], endDepth),
                            new Vector3D(this.point1[0], this.point1[1], endDepth),
                            new Vector3D(this.point1[0], this.point1[1], startDepth)
                        };

                        startPolygon = this.polygonRecycler.DequeuePolygon(startPolygonVects, this, Series.Segments.IndexOf(this), this.Stroke, this.StrokeThickness, this.color);

                        if (lineSeries.IsAnimated || !Series.EnableAnimation)
                        {
                            this.area.Graphics3D.AddVisual(startPolygon);
                        }
                    }

                    i++;
                    if (i < this.xValues.Count)
                    {
                        x            = this.xValues[i];
                        y            = !lineSeries.IsAnimated && !Series.EnableAnimation ? this.yValues[i] : (this.Y < this.yValues[i] && this.Y > 0) ? this.Y : this.yValues[i];
                        x            = !(x >= xStart) ? xStart : !(x <= xEnd) ? xEnd : x;
                        y            = !(y >= yStart) ? yStart : !(y <= yEnd) ? yEnd : y;
                        currentPoint = transformer.TransformToVisible(x, y);
                        this.UpdatePoints2(previousPoint.X, previousPoint.Y, currentPoint.X, currentPoint.Y, leftThickness, rightThickness);
                    }

                    Vector3D[] bottomPolyVects = new Vector3D[]
                    {
                        new Vector3D(this.point1[2], this.point1[3], startDepth),
                        new Vector3D(this.point1[0], this.point1[1], startDepth),
                        new Vector3D(this.point1[0], this.point1[1], endDepth),
                        new Vector3D(this.point1[2], this.point1[3], endDepth)
                    };

                    Vector3D[] topPolyVects = new Vector3D[]
                    {
                        new Vector3D(this.point1[6], this.point1[7], startDepth),
                        new Vector3D(this.point1[4], this.point1[5], startDepth),
                        new Vector3D(this.point1[4], this.point1[5], endDepth),
                        new Vector3D(this.point1[6], point1[7], endDepth)
                    };

                    bottomPolygon = new Polygon3D(
                        bottomPolyVects,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        this.color);
                    bottomPolygon.CalcNormal(bottomPolyVects[0], bottomPolyVects[1], bottomPolyVects[2]);
                    bottomPolygon.CalcNormal();

                    topPolygon = new Polygon3D(
                        topPolyVects,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        this.color);
                    topPolygon.CalcNormal(topPolyVects[0], topPolyVects[1], topPolyVects[2]);
                    topPolygon.CalcNormal();

                    if (lineSeries.IsAnimated || !Series.EnableAnimation)
                    {
                        this.area.Graphics3D.AddVisual(bottomPolygon);
                        this.area.Graphics3D.AddVisual(topPolygon);
                        this.RenderFrontPolygon(this.point1, this.startDepth, this.endDepth, this.color);
                    }

                    if (this.point2 != null && (i < this.xValues.Count))
                    {
                        this.point1 = this.point2;
                    }
                    j++;
                }

                Vector3D[] endPolyVects = new Vector3D[]
                {
                    new Vector3D(this.point1[4], this.point1[5], startDepth),
                    new Vector3D(this.point1[4], this.point1[5], endDepth),
                    new Vector3D(this.point1[2], this.point1[3], endDepth),
                    new Vector3D(this.point1[2], this.point1[3], startDepth)
                };

                endPolygon = new Polygon3D(endPolyVects, this, 0, Stroke, 1, this.color);
                endPolygon.CalcNormal(endPolyVects[0], endPolyVects[1], endPolyVects[2]);
                endPolygon.CalcNormal();
                if (lineSeries.IsAnimated || !Series.EnableAnimation)
                {
                    this.area.Graphics3D.AddVisual(endPolygon);
                }
            }
        }
Beispiel #5
0
        /// <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();
        }