예제 #1
0
        /// <summary>
        /// Updates the second points.
        /// </summary>
        /// <param name="xStart">The Start X Value</param>
        /// <param name="yStart">The Start Y Value</param>
        /// <param name="xEnd">The End X Value</param>
        /// <param name="yEnd">The End Y Value</param>
        /// <param name="leftThickness">The Left Thickness</param>
        /// <param name="rightThickness">The Right Thickness</param>
        private void UpdatePoints2(double xStart, double yStart, double xEnd, double yEnd, double leftThickness, double rightThickness)
        {
            LineSegment3D.GetLinePoints(xStart, yStart, xEnd, yEnd, leftThickness, rightThickness, point2);

            bool isIntersecting = this.FindIntersectingPoint(
                this.point1[0],
                this.point1[1],
                this.point1[2],
                this.point1[3],
                this.point2[0],
                this.point2[1],
                this.point2[2],
                this.point2[3]);

            if (isIntersecting)
            {
                var  diff1   = this.intersectingPoint.X - this.point1[2];
                var  diff2   = this.point2[0] - this.point1[2];
                bool canSwap = false;
                if (diff1 < 0)
                {
                    canSwap = diff1 >= -3;
                }
                else
                {
                    canSwap = diff2 >= diff1 || (diff1 - diff2) <= 3;
                }
                if (canSwap)
                {
                    this.point1[2] = this.intersectingPoint.X;
                    this.point1[3] = this.intersectingPoint.Y;

                    this.point2[0] = this.intersectingPoint.X;
                    this.point2[1] = intersectingPoint.Y;

                    this.point2[8] = this.intersectingPoint.X;
                    this.point2[9] = this.intersectingPoint.Y;
                }
            }

            isIntersecting = this.FindIntersectingPoint(
                this.point1[6],
                this.point1[7],
                this.point1[4],
                this.point1[5],
                this.point2[6],
                this.point2[7],
                this.point2[4],
                this.point2[5]);

            if (isIntersecting)
            {
                var  diff1 = this.intersectingPoint.X - this.point1[4];
                var  diff2 = this.point2[6] - this.point1[4];
                bool canSwap;
                if (diff1 < 0)
                {
                    canSwap = diff1 >= -3;
                }
                else
                {
                    canSwap = diff2 >= diff1 || (diff1 - diff2) <= 3;
                }
                if (canSwap)
                {
                    this.point1[4] = this.intersectingPoint.X;
                    this.point1[5] = this.intersectingPoint.Y;

                    this.point2[6] = this.intersectingPoint.X;
                    this.point2[7] = this.intersectingPoint.Y;
                }
            }
        }
예제 #2
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);
                }
            }
        }