Пример #1
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);
        }
Пример #2
0
        /// <summary>
        /// Redraws the segments.
        /// </summary>
        internal void ReDraw()
        {
            if (VectorPoints == null || VectorPoints.Length <= 0)
            {
                return;
            }
            var transform   = Graphics3D.Transform;
            var segmentPath = Element as Path;

            if (segmentPath == null)
            {
                return;
            }
            var figure          = new PathFigure();
            var segmentGeometry = new PathGeometry();

            if (transform != null)
            {
                figure.StartPoint = transform.ToScreen(VectorPoints[0]);
                foreach (var lineSegment in VectorPoints.Select(item => new WindowsLineSegment {
                    Point = transform.ToScreen(item)
                }))
                {
                    figure.Segments.Add(lineSegment);
                }
            }

            segmentGeometry.Figures.Add(figure);
            segmentPath.Data = segmentGeometry;
            var lightCoefZ = (int)(2 * (Math.Abs(normal & new Vector3D(0, 0, 1)) - 1));
            var lightCoefY = (int)(2 * (Math.Abs(normal & new Vector3D(0, 1, 0)) - 1));
            var lightCoefX = (int)(2 * (Math.Abs(normal & new Vector3D(1, 0, 0)) - 1));

            var actualBrush = (Fill is SolidColorBrush) ?
                              ((SolidColorBrush)Fill).Color :
                              ((Fill is LinearGradientBrush) && ((LinearGradientBrush)Fill).GradientStops.Count > 0) ?
                              ((LinearGradientBrush)Fill).GradientStops[0].Color :
                              new SolidColorBrush(Colors.Transparent).Color;

            if (lightCoefZ == lightCoefX && Fill != null)
            {
                segmentPath.Fill = ApplyZLight(actualBrush);
            }
            else if (((lightCoefY == lightCoefZ) || (lightCoefZ != 0 && lightCoefY < lightCoefZ)) &&
                     !(Tag is LineSegment3D) && !(Tag is AreaSegment3D) && !(Tag is PieSegment3D) && Fill != null)
            {
                segmentPath.Fill = Polygon3D.ApplyXLight(actualBrush);
            }
            else if (lightCoefZ < 0 && Fill != null)
            {
                segmentPath.Fill = ApplyZLight(actualBrush);
            }
            else
            {
                segmentPath.Fill = Fill;
            }

            segmentPath.StrokeThickness = strokeThickness;
            segmentPath.Stroke          = Stroke;
        }
Пример #3
0
        /// <summary>
        /// Updates the polygon.
        /// </summary>
        /// <param name="updatedPoints">The Updated Points</param>
        /// <param name="interior">The Interior</param>
        /// <param name="visibility">The Visibility</param>
        internal void Update(Vector3D[] updatedPoints, Brush interior, Visibility visibility)
        {
            VectorPoints = updatedPoints;
            var segmentPath = Element as Path;

            if (segmentPath == null)
            {
                return;
            }
            segmentPath.Visibility = visibility;
            if (Graphics3D == null)
            {
                return;
            }
            var transform       = Graphics3D.Transform;
            var figure          = new PathFigure();
            var segmentGeometry = new PathGeometry();

            var actualBrush = (Fill is SolidColorBrush) ?
                              ((SolidColorBrush)Fill).Color :
                              ((Fill is LinearGradientBrush) && ((LinearGradientBrush)Fill).GradientStops.Count > 0) ?
                              ((LinearGradientBrush)Fill).GradientStops[0].Color :
                              new SolidColorBrush(Colors.Transparent).Color;

            if (transform != null)
            {
                figure.StartPoint = transform.ToScreen(VectorPoints[0]);
                foreach (var lineSegment in VectorPoints.Select(item => new WindowsLineSegment {
                    Point = transform.ToScreen(item)
                }))
                {
                    figure.Segments.Add(lineSegment);
                }
            }

            segmentGeometry.Figures.Add(figure);
            var lightCoefZ = (int)(2 * (Math.Abs(normal & new Vector3D(0, 0, 1)) - 1));
            var lightCoefY = (int)(2 * (Math.Abs(normal & new Vector3D(0, 1, 0)) - 1));
            var lightCoefX = (int)(2 * (Math.Abs(normal & new Vector3D(1, 0, 0)) - 1));

            if (lightCoefZ == lightCoefX && interior != null)
            {
                segmentPath.Fill = ApplyZLight(actualBrush);
            }
            else if (((lightCoefY == lightCoefZ) || (lightCoefZ != 0 && lightCoefY < lightCoefZ)) &&
                     !(Tag is LineSegment3D) && !(Tag is AreaSegment3D) && interior != null)
            {
                segmentPath.Fill = Polygon3D.ApplyXLight(actualBrush);
            }
            else if (lightCoefZ < 0 && interior != null)
            {
                segmentPath.Fill = ApplyZLight(actualBrush);
            }
            else
            {
                segmentPath.Fill = interior;
            }

            segmentPath.Data = segmentGeometry;
        }
Пример #4
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);
        }
Пример #5
0
        /// <summary>
        /// Classify the polygon.
        /// </summary>
        /// <param name="polygon1">The First Polygon.</param>
        /// <param name="polygon2">The Second Polygon.</param>
        /// <returns>Returns the classified result.</returns>
        private static ClassifyPolyResult ClassifyPolygon(Polygon3D polygon1, Polygon3D polygon2)
        {
            var res    = ClassifyPolyResult.Unknown;
            var points = polygon2.Points;

            if (points == null)
            {
                return(res);
            }

            var onBack  = 0;
            var onFront = 0;
            var onPlane = 0;
            var normal  = polygon1.Normal; // root node normailized value perpendicular direction
            var d       = polygon1.D;      // constant of the plan or depth

            for (int i = 0, len = points.Length; i < len; i++)
            {
                var r = -d - (points[i] & normal); // Comparision of Plane point depth with the other nodes

                if (r > EPSILON)
                {
                    onBack++;
                }
                else if (r < -EPSILON)
                {
                    onFront++;
                }
                else
                {
                    onPlane++;
                }

                if ((onBack > 0) && (onFront > 0))
                {
                    break;
                }
            }

            if (onPlane == points.Length)
            {
                res = ClassifyPolyResult.OnPlane;
            }
            else if (onFront + onPlane == points.Length)
            {
                res = ClassifyPolyResult.ToRight;
            }
            else if (onBack + onPlane == points.Length)
            {
                res = ClassifyPolyResult.ToLeft;
            }
            else
            {
                res = ClassifyPolyResult.Unknown;
            }

            return(res);
        }
Пример #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Graphics3D"/> class.
        /// </summary>
        /// <summary>
        /// Adds the polygon to the drawing.
        /// </summary>
        /// <param name="polygon">The <see cref="Polygon3D"/>.</param>
        /// <returns>Returns the last index.</returns>
        public int AddVisual(Polygon3D polygon)
        {
            if ((polygon == null) || (polygon.Test()))
            {
                return(-1);
            }

            polygon.Graphics3D = this;
            return(this.treeBuilder.Add(polygon));
        }
Пример #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Polygon3D"/> class.
 /// </summary>
 /// <param name="points">The points.</param>
 /// <param name="polygon">The plane.</param>
 public Polygon3D(Vector3D[] points, Polygon3D polygon)
     : this(points)
 {
     polygon.Element = null;
     Element         = new Path();
     Index           = polygon.Index;
     Stroke          = polygon.Stroke;
     Tag             = polygon.Tag;
     Graphics3D      = polygon.Graphics3D;
     Fill            = polygon.Fill;
     strokeThickness = polygon.strokeThickness;
 }
Пример #8
0
        /// <summary>
        /// This method used to gets the chart data point at a position.
        /// </summary>
        /// <param name="point">The Mouse Position</param>
        /// <returns>Returns the data point.</returns>
        internal override ChartDataPointInfo GetDataPoint(Point point)
        {
            var frontPlane = new Polygon3D(new Vector3D(0, 0, 1), 0);
            var transform  = (ActualArea as SfChart3D).Graphics3D.Transform;

            frontPlane.Transform(transform.View);

            var position = transform.ToPlane(point, frontPlane);

            Rect           rect;
            int            startIndex, endIndex;
            List <int>     hitIndexes = new List <int>();
            IList <double> xValues    = (ActualXValues is IList <double>) ? ActualXValues as IList <double> : GetXValues();

            this.CalculateHittestRect(new Point(position.X, position.Y), out startIndex, out endIndex, out rect);

            for (int i = startIndex; i <= endIndex; i++)
            {
                this.hitPoint.X = this.IsIndexed ? i : xValues[i];
                this.hitPoint.Y = this.YValues[i];

                if (rect.Contains(this.hitPoint))
                {
                    hitIndexes.Add(i);
                }
            }

            if (hitIndexes.Count > 0)
            {
                int i = hitIndexes[hitIndexes.Count / 2];
                hitIndexes = null;

                this.dataPoint   = new ChartDataPointInfo();
                dataPoint.Index  = i;
                dataPoint.Series = this;
                dataPoint.XData  = xValues[i];
                dataPoint.YData  = this.YValues[i];
                if (ActualData.Count > i)
                {
                    dataPoint.Item = this.ActualData[i];
                }

                return(this.dataPoint);
            }
            else
            {
                return(this.dataPoint);
            }
        }
Пример #9
0
        /// <summary>
        /// Classifies the point.
        /// </summary>
        /// <param name="point3D">The 3D Point</param>
        /// <param name="polygon3D">The 3D Polygon</param>
        /// <returns>Returns the classified point result.</returns>
        private static ClassifyPointResult ClassifyPoint(Vector3D point3D, Polygon3D polygon3D)
        {
            var res = ClassifyPointResult.OnPlane;
            var sv  = -polygon3D.D - (point3D & polygon3D.Normal);

            if (sv > EPSILON)
            {
                res = ClassifyPointResult.OnBack;
            }
            else if (sv < -EPSILON)
            {
                res = ClassifyPointResult.OnFront;
            }

            return(res);
        }
Пример #10
0
            /// <summary>
            /// Returns the intercept point of mouse ray with the specified plane.
            /// </summary>
            /// <param name="point">The point.</param>
            /// <param name="plane">The plane.</param>
            /// <returns></returns>
            public Vector3D ToPlane(Point point, Polygon3D plane)
            {
                var vec1 = new Vector3D(point.X, point.Y, 0);
                var vec2 = vec1 + new Vector3D(0, 0, 1);

                vec1 = centeredMatrix * vec1;
                vec2 = centeredMatrix * vec2;

                vec1 = Matrix3D.GetInvertal(perspective) * vec1;
                vec2 = Matrix3D.GetInvertal(perspective) * vec2;

                vec1 = plane.GetPoint(vec1, vec2 - vec1);

                vec1 = Matrix3D.GetInvertal(viewMatrix) * vec1;
                vec1 = Matrix3D.GetInvertal(centeredMatrix) * vec1;

                return(vec1);
            }
Пример #11
0
        public override void Update(IChartTransformer transformer)
        {
            ChartTransform.ChartCartesianTransformer cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer;

            if (cartesianTransformer != null)
            {
                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;

                // Clippiing the area series 3D.
                if (this.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;
                        }
                    }
                }

                if (this.yValues.Min() < yStart)
                {
                    List <double> tempYVal = this.yValues.ToList();
                    foreach (var yVal in tempYVal)
                    {
                        if (yVal < yStart)
                        {
                            this.yValues[this.yValues.IndexOf(yVal)] = yStart;
                        }
                    }
                }

                if (this.yValues.Max() > yEnd)
                {
                    List <double> tempYVal = this.yValues.ToList();
                    foreach (var yVal in tempYVal)
                    {
                        if (yVal > yEnd)
                        {
                            this.yValues[this.yValues.IndexOf(yVal)] = yEnd;
                        }
                    }
                }

                // End of clipping logic
                double       x             = this.xValues[0];
                double       y             = !(Series as AreaSeries3D).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;
                List <Point> areaPoint = new List <Point>();
                areaPoint.Add(previousPoint);
                this.topPolygonCollection = new Polygon3D[this.yValues.Count];
                Vector3D vector1, vector2, vector3, vector4;
                for (int i = 1; i < this.xValues.Count; i++)
                {
                    x = this.xValues[i];
                    y = !(Series as AreaSeries3D).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);
                    vector1      = new Vector3D(previousPoint.X, previousPoint.Y, startDepth);
                    vector2      = new Vector3D(currentPoint.X, currentPoint.Y, startDepth);
                    vector3      = new Vector3D(currentPoint.X, currentPoint.Y, endDepth);
                    vector4      = new Vector3D(previousPoint.X, previousPoint.Y, endDepth);
                    var points = new Vector3D[] { vector1, vector2, vector3, vector4 };
                    this.topPolygonCollection[i] = new Polygon3D(points, this, Series.Segments.IndexOf(this), Stroke, StrokeThickness, Interior);
                    this.topPolygonCollection[i].CalcNormal(points[0], points[1], points[2]);
                    this.topPolygonCollection[i].CalcNormal();
                    previousPoint = currentPoint;
                    areaPoint.Add(currentPoint);
                }

                x = this.xValues[0];
                y = !(Series as AreaSeries3D).IsAnimated && !Series.EnableAnimation ? this.yValues[0] : (this.Y < this.yValues[0] && this.Y > 0) ? this.Y : this.yValues[0];
                Point topLeft = transformer.TransformToVisible(x, y);
                x = this.xValues[this.xValues.Count - 1];
                y = !(Series as AreaSeries3D).IsAnimated && !Series.EnableAnimation ? this.yValues[this.xValues.Count - 1] : (this.Y < this.yValues[this.yValues.Count - 1]) ? this.Y : this.yValues[this.yValues.Count - 1];
                Point  topRight = transformer.TransformToVisible(x, y);
                double origin   = Series.ActualYAxis.Origin < yStart ? yStart : Series.ActualYAxis.Origin;
                x = this.xValues[0];
                Point bottomLeft = transformer.TransformToVisible(x, origin);
                x = this.xValues[this.xValues.Count - 1];
                Point bottomRight = transformer.TransformToVisible(x, origin);
                areaPoint.Add(bottomRight);
                areaPoint.Add(bottomLeft);

                Vector3D   tlfVector   = new Vector3D(topLeft.X, topLeft.Y, startDepth);
                Vector3D   tldVector   = new Vector3D(topLeft.X, topLeft.Y, endDepth);
                Vector3D   trfVector   = new Vector3D(topRight.X, topRight.Y, startDepth);
                Vector3D   trdVector   = new Vector3D(topRight.X, topRight.Y, endDepth);
                Vector3D   blfVector   = new Vector3D(bottomLeft.X, bottomLeft.Y, startDepth);
                Vector3D   bldVector   = new Vector3D(bottomLeft.X, bottomLeft.Y, endDepth);
                Vector3D   brfVector   = new Vector3D(bottomRight.X, bottomRight.Y, startDepth);
                Vector3D   brdVector   = new Vector3D(bottomRight.X, bottomRight.Y, endDepth);
                Vector3D[] leftVectors = new Vector3D[4] {
                    tlfVector, tldVector, bldVector, blfVector
                };
                Vector3D[] rightVectors = new Vector3D[4] {
                    trfVector, trdVector, brdVector, brfVector
                };
                Vector3D[] bottomVectors = new Vector3D[4] {
                    blfVector, bldVector, brdVector, brfVector
                };
                Vector3D[] frontVector = new Vector3D[areaPoint.Count];
                Vector3D[] backVector  = new Vector3D[areaPoint.Count];
                for (int i = 0; i < areaPoint.Count; i++)
                {
                    Point point = areaPoint[i];
                    frontVector[i] = new Vector3D(point.X, point.Y, startDepth);
                    backVector[i]  = new Vector3D(point.X, point.Y, endDepth);
                }

                if ((Series as AreaSeries3D).IsAnimated || !Series.EnableAnimation)
                {
                    this.leftPolygon = new Polygon3D(
                        leftVectors,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        Interior);
                    this.leftPolygon.CalcNormal(leftVectors[0], leftVectors[1], leftVectors[2]);
                    this.leftPolygon.CalcNormal();
                    this.area.Graphics3D.AddVisual(this.leftPolygon);

                    this.rightPolygon = new Polygon3D(
                        rightVectors,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        Interior);
                    this.rightPolygon.CalcNormal(rightVectors[0], rightVectors[1], rightVectors[2]);
                    this.rightPolygon.CalcNormal();
                    this.area.Graphics3D.AddVisual(this.rightPolygon);

                    this.bottomPolygon = new Polygon3D(
                        bottomVectors,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        Interior);
                    this.bottomPolygon.CalcNormal(bottomVectors[0], bottomVectors[1], bottomVectors[2]);
                    this.bottomPolygon.CalcNormal();
                    this.area.Graphics3D.AddVisual(this.bottomPolygon);

                    this.frontPolygon = new Polygon3D(
                        frontVector,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        Interior);
                    this.frontPolygon.CalcNormal(frontVector[0], frontVector[1], frontVector[2]);
                    this.frontPolygon.CalcNormal();
                    this.area.Graphics3D.AddVisual(this.frontPolygon);

                    this.backPolygon = new Polygon3D(
                        backVector,
                        this,
                        Series.Segments.IndexOf(this),
                        Stroke,
                        StrokeThickness,
                        Interior);
                    this.backPolygon.CalcNormal(backVector[0], backVector[1], backVector[2]);
                    this.backPolygon.CalcNormal();
                    this.area.Graphics3D.AddVisual(this.backPolygon);

                    for (int i = 1; i < this.yValues.Count; i++)
                    {
                        this.area.Graphics3D.AddVisual(this.topPolygonCollection[i]);
                    }
                }
            }
        }
Пример #12
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)
        {
            if (transformer == null)
            {
                return;
            }

            var cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer;

            if (cartesianTransformer == null)
            {
                return;
            }

            if (double.IsNaN(this.YData) && !Series.ShowEmptyPoints)
            {
                return;
            }

            var xBase          = cartesianTransformer.XAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.XAxis).LogarithmicBase : 1;
            var xIsLogarithmic = cartesianTransformer.XAxis.IsLogarithmic;
            var left           = xIsLogarithmic ? Math.Log(this.Left, xBase) : this.Left;
            var right          = xIsLogarithmic ? Math.Log(this.Right, xBase) : this.Right;
            var yBase          = cartesianTransformer.YAxis.IsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.YAxis).LogarithmicBase : 1;
            var yIsLogarithmic = cartesianTransformer.YAxis.IsLogarithmic;
            var bottom         = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.Start) : cartesianTransformer.YAxis.VisibleRange.Start;
            var top            = yIsLogarithmic ? Math.Pow(yBase, cartesianTransformer.YAxis.VisibleRange.End) : cartesianTransformer.YAxis.VisibleRange.End;
            var xStart         = cartesianTransformer.XAxis.VisibleRange.Start;
            var xEnd           = cartesianTransformer.XAxis.VisibleRange.End;

            double z1 = startDepth, z2 = endDepth;

            var zSeries = this.Series as XyzDataSeries3D;

            bool isZAxis = cartesianTransformer.ZAxis != null && zSeries.ActualZAxis != null && zSeries.ActualZValues != null;

            double spacing = (Series as ISegmentSpacing).SegmentSpacing;

            if (!(left <= xEnd && right >= xStart))
            {
                return;
            }

            // WPF -14524 3D Column and Bar Series is rendering out of the pane. while cross the bar value to visualRange of axis.
            double topValue;

            if (this.Top < 0)
            {
                topValue = this.Top > bottom ? this.Top : bottom;
            }
            else
            {
                topValue = this.Top < top ? this.Top : top;
            }

            this.Bottom = this.Bottom > top ? top : this.Bottom;
            if (spacing > 0 && spacing <= 1)
            {
                double leftpos  = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, right, left);
                double rightpos = (Series as ISegmentSpacing).CalculateSegmentSpacing(spacing, left, right);
                this.Left  = leftpos;
                this.Right = rightpos;
            }

            var area      = Series.ActualArea as SfChart3D;
            var tlfVector = new Vector3D(0, 0, 0);
            var brbVector = new Vector3D(0, 0, 0);

            var tlpoint = transformer.TransformToVisible(left > xStart ? this.Left : xStart, topValue < bottom ? bottom : topValue);
            var rbpoint = transformer.TransformToVisible(xEnd > right ? this.Right : xEnd, bottom > this.Bottom ? bottom : this.Bottom);

            if (isZAxis)
            {
                double zStart = cartesianTransformer.ZAxis.VisibleRange.Start;
                double zEnd   = cartesianTransformer.ZAxis.VisibleRange.End;

                var zIsLogarithmic = cartesianTransformer.ZAxis.IsLogarithmic;
                var zBase          = zIsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.ZAxis).LogarithmicBase : 1;

                var actualZ1 = zIsLogarithmic ? Math.Log(z1, zBase) : z1;
                var actualZ2 = zIsLogarithmic ? Math.Log(z2, zBase) : z2;

                if (!(actualZ1 <= zEnd && actualZ2 >= zStart))
                {
                    return;
                }

                tlfVector = cartesianTransformer.TransformToVisible3D(this.Left > xStart ? this.Left : xStart, topValue <bottom?bottom : topValue, z1> zStart ? z1 : zStart);
                brbVector = cartesianTransformer.TransformToVisible3D(xEnd > this.Right ? this.Right : xEnd, bottom > this.Bottom ? bottom : this.Bottom, zEnd > z2 ? z2 : zEnd);
            }
            else
            {
                var rect = new Rect(tlpoint, rbpoint);

                tlfVector = new Vector3D(rect.Left, rect.Top, z1);
                brbVector = new Vector3D(rect.Right, rect.Bottom, z2);
            }

            if (this.plans == null)
            {
                this.plans = Polygon3D.CreateBox(
                    tlfVector,
                    brbVector,
                    this,
                    Series.Segments.IndexOf(this),
                    area.Graphics3D,
                    this.Stroke,
                    Interior,
                    this.StrokeThickness,
                    Series.IsActualTransposed);
            }
            else
            {
                Polygon3D.UpdateBox(this.plans, tlfVector, brbVector, this.Interior, tlpoint.Y == rbpoint.Y ? Visibility.Collapsed : Visibility.Visible);
            }
        }
Пример #13
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();
        }
Пример #14
0
        /// <summary>
        /// Creates the <see cref="Polygon3D"/> with the specified values.
        /// </summary>
        /// <param name="vector1">The First Vector</param>
        /// <param name="vector2">The Second Vector</param>
        /// <param name="tag">The Tag</param>
        /// <param name="index">The Index</param>
        /// <param name="graphics3D">The Graphics 3D</param>
        /// <param name="stroke">The Stroke</param>
        /// <param name="fill">The Fill Color</param>
        /// <param name="strokeThickness">The Stroke Thickness</param>
        /// <param name="inverse">The Inverse</param>
        /// <returns>Returns the created <see cref="Polygon3D"/>.</returns>
        internal static Polygon3D[] CreateBox(
            Vector3D vector1,
            Vector3D vector2,
            DependencyObject tag,
            int index,
            Graphics3D graphics3D,
            Brush stroke,
            Brush fill,
            double strokeThickness,
            bool inverse)
        {
            var res = new Polygon3D[6];

            var p1 = new[]
            {
                new Vector3D(vector1.X, vector1.Y, vector1.Z),
                new Vector3D(vector2.X, vector1.Y, vector1.Z),
                new Vector3D(vector2.X, vector2.Y, vector1.Z),
                new Vector3D(vector1.X, vector2.Y, vector1.Z)
            };

            var p2 = new[]
            {
                new Vector3D(vector1.X, vector1.Y, vector2.Z),
                new Vector3D(vector2.X, vector1.Y, vector2.Z),
                new Vector3D(vector2.X, vector2.Y, vector2.Z),
                new Vector3D(vector1.X, vector2.Y, vector2.Z)
            };

            var p3 = new[]
            {
                new Vector3D(vector1.X, vector1.Y, vector2.Z),
                new Vector3D(vector2.X, vector1.Y, vector2.Z),
                new Vector3D(vector2.X, vector1.Y, vector1.Z),
                new Vector3D(vector1.X, vector1.Y, vector1.Z)
            };

            var p4 = new[]
            {
                new Vector3D(vector1.X, vector2.Y, vector2.Z),
                new Vector3D(vector2.X, vector2.Y, vector2.Z),
                new Vector3D(vector2.X, vector2.Y, vector1.Z),
                new Vector3D(vector1.X, vector2.Y, vector1.Z)
            };

            var p5 = new[]
            {
                new Vector3D(vector1.X, vector1.Y, vector1.Z),
                new Vector3D(vector1.X, vector1.Y, vector2.Z),
                new Vector3D(vector1.X, vector2.Y, vector2.Z),
                new Vector3D(vector1.X, vector2.Y, vector1.Z)
            };

            var p6 = new[]
            {
                new Vector3D(vector2.X, vector1.Y, vector1.Z),
                new Vector3D(vector2.X, vector1.Y, vector2.Z),
                new Vector3D(vector2.X, vector2.Y, vector2.Z),
                new Vector3D(vector2.X, vector2.Y, vector1.Z)
            };

            res[0] = new Polygon3D(p1, tag, index, stroke, strokeThickness, fill);
            res[0].CalcNormal(p1[0], p1[1], p1[2]);
            res[0].CalcNormal();

            res[1] = new Polygon3D(p2, tag, index, stroke, strokeThickness, fill);
            res[1].CalcNormal(p2[0], p2[1], p2[2]);
            res[1].CalcNormal();

            res[2] = new Polygon3D(p3, tag, index, stroke, strokeThickness, fill);
            res[2].CalcNormal(p3[0], p3[1], p3[2]);
            res[2].CalcNormal();

            res[3] = new Polygon3D(p4, tag, index, stroke, strokeThickness, fill);
            res[3].CalcNormal(p4[0], p4[1], p4[2]);
            res[3].CalcNormal();

            res[4] = new Polygon3D(p5, tag, index, stroke, strokeThickness, fill);
            res[4].CalcNormal(p5[0], p5[1], p5[2]);
            res[4].CalcNormal();

            res[5] = new Polygon3D(p6, tag, index, stroke, strokeThickness, fill);
            res[5].CalcNormal(p6[0], p6[1], p6[2]);
            res[5].CalcNormal();

            if (inverse)
            {
                graphics3D.AddVisual(res[0]);
                graphics3D.AddVisual(res[1]);
                graphics3D.AddVisual(res[2]);
                graphics3D.AddVisual(res[3]);
                graphics3D.AddVisual(res[4]);
                graphics3D.AddVisual(res[5]);
            }
            else
            {
                graphics3D.AddVisual(res[5]);
                graphics3D.AddVisual(res[4]);
                graphics3D.AddVisual(res[0]);
                graphics3D.AddVisual(res[1]);
                graphics3D.AddVisual(res[2]);
                graphics3D.AddVisual(res[3]);
            }

            return(res);
        }
Пример #15
0
 /// <summary>
 /// Removes the specified polygon.
 /// </summary>
 /// <param name="polygon">The polygon.</param>
 public void Remove(Polygon3D polygon)
 {
     this.Polygons.Remove(polygon);
 }
Пример #16
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);
        }
Пример #17
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);
                }
            }
        }
        /// <summary>
        /// Renders the 3D tick lines.
        /// </summary>
        /// <param name="linesRecycler">The Line Recycler</param>
        /// <param name="orientation">The Orientation</param>
        /// <param name="tickSize">The Tick Size</param>
        /// <param name="tickPosition">The Tick Position</param>
        /// <param name="values">The Values</param>
        private void RenderTicks3D(
            UIElementsRecycler <Line> linesRecycler,
            Orientation orientation,
            double tickSize,
            AxisElementPosition tickPosition,
            IList <double> values)
        {
            var area3D = Axis.Area as SfChart3D;
            var actualRotationAngle = area3D.ActualRotationAngle;
            var labelsCount         = values.Count;
            var linesCount          = linesRecycler.Count;

            for (var i = 0; i < labelsCount; i++)
            {
                if (i >= linesCount)
                {
                    continue;
                }
                double x1 = 0, y1 = 0, x2 = 0, y2 = 0;
                var    line  = linesRecycler[i];
                var    value = Axis.ValueToCoefficientCalc(values[i]);
                value = double.IsNaN(value) ? 0 : value;

                if (orientation == Orientation.Horizontal)
                {
                    var tempaxis = axis as ChartAxisBase3D;
                    if (tempaxis.IsManhattanAxis && (axis.RegisteredSeries[i] as ChartSeries3D).Segments != null && (axis.RegisteredSeries[i] as ChartSeries3D).Segments.Count > 0)
                    {
                        var segment = (axis.RegisteredSeries[i] as ChartSeries3D).Segments[0] as ChartSegment3D;
                        x1 = x2 = segment.startDepth + (segment.endDepth - segment.startDepth) / 2;
                    }
                    else
                    {
                        x1 = x2 = Math.Round(Axis.ActualPlotOffset + (Axis.RenderedRect.Width * value));
                    }
                }
                else
                {
                    y1 = y2 = Math.Round(Axis.ActualPlotOffset + (Axis.RenderedRect.Height * (1 - value)));
                }

                CalculatePosition3D(tickPosition, tickSize, ref x1, ref y1, ref x2, ref y2, actualRotationAngle);
                var verticalAxis = area3D.InternalSecondaryAxis.Orientation == Orientation.Vertical ? area3D.InternalSecondaryAxis : area3D.InternalPrimaryAxis;

                if ((axis as ChartAxisBase3D).IsZAxis)
                {
                    // Adding one to prevent the tick hidding.
                    var leftPosition = !verticalAxis.OpposedPosition && actualRotationAngle >= 0 && actualRotationAngle < 180 ? axis.ArrangeRect.Left + 1 : axis.ArrangeRect.Left;

                    ((SfChart3D)Axis.Area).Graphics3D.AddVisual(Polygon3D.CreateLine(line, leftPosition, y1, leftPosition, y2, x1, x1, false));
                }
                else
                {
                    double depth  = 0d;
                    var    axis3D = this.axis as ChartAxisBase3D;
                    Line3D line3D = null;
                    if (orientation == Orientation.Vertical)
                    {
                        if (axis.ShowAxisNextToOrigin)
                        {
                            if (actualRotationAngle >= 90 && actualRotationAngle < 270)
                            {
                                depth = (axis.Area as SfChart3D).ActualDepth;
                            }

                            line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true);
                        }
                        else
                        {
                            if (axis3D.AxisPosition3D == AxisPosition3D.DepthBackRight || axis3D.AxisPosition3D == AxisPosition3D.DepthBackLeft ||
                                axis3D.AxisPosition3D == AxisPosition3D.DepthFrontRight || axis3D.AxisPosition3D == AxisPosition3D.DepthFrontLeft)
                            {
                                line3D = Polygon3D.CreateLine(line, axis.ArrangeRect.Left, y1, axis.ArrangeRect.Left, y2, x1, x2, false);
                            }
                            else
                            {
                                depth  = axis3D.AxisDepth;
                                line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true);
                            }
                        }
                    }
                    else
                    {
                        depth  = axis3D.AxisDepth;
                        line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true);
                    }

                    ((SfChart3D)Axis.Area).Graphics3D.AddVisual(line3D);
                }
            }
        }
Пример #19
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)
        {
            Rect   rect;
            double x, y, width, height;

            if (transformer == null)
            {
                return;
            }
            var cartesianTransformer = transformer as ChartTransform.ChartCartesianTransformer;

            if (cartesianTransformer == null)
            {
                return;
            }
            if (double.IsNaN(YData) && !Series.ShowEmptyPoints)
            {
                return;
            }

            ScatterSeries3D series         = (Series as ScatterSeries3D);
            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;
            var             xValue         = xIsLogarithmic ? Math.Log(X, xBase) : X;
            var             yValue         = yIsLogarithmic ? Math.Log(Y, yBase) : Y;
            var             yStart         = cartesianTransformer.YAxis.VisibleRange.Start;
            var             yEnd           = cartesianTransformer.YAxis.VisibleRange.End;
            var             xStart         = cartesianTransformer.XAxis.VisibleRange.Start;
            var             xEnd           = cartesianTransformer.XAxis.VisibleRange.End;
            var             zSeries        = this.Series as XyzDataSeries3D;
            bool            isZAxis        = cartesianTransformer.ZAxis != null && zSeries.ActualZAxis != null && (zSeries as XyzDataSeries3D).ActualZValues != null;
            Point           tlpoint        = new Point(0, 0);
            double          frontDepth     = 0d;
            double          backDepth      = 0d;

            if (isZAxis)
            {
                var z1value    = startDepth;
                var z2value    = endDepth;
                var depthDelta = (this.Series as ScatterSeries3D).GetSegmentDepth((this.Series.ActualArea as SfChart3D).ActualDepth).Delta / 2;
                var zStart     = cartesianTransformer.ZAxis.VisibleRange.Start;
                var zEnd       = cartesianTransformer.ZAxis.VisibleRange.End;

                var zIsLogarithmic = cartesianTransformer.ZAxis.IsLogarithmic;
                var zBase          = zIsLogarithmic ? ((LogarithmicAxis3D)cartesianTransformer.ZAxis).LogarithmicBase : 1;

                var actualZ1 = zIsLogarithmic ? Math.Log(z1value, zBase) : z1value;
                var actualZ2 = zIsLogarithmic ? Math.Log(z2value, zBase) : z2value;

                if (!(actualZ1 <= zEnd && actualZ2 >= zStart))
                {
                    return;
                }

                var zLogStart = zIsLogarithmic ? Math.Pow(zBase, zStart) : zStart;
                var zLogEnd   = zIsLogarithmic ? Math.Pow(zBase, zEnd) : zEnd;
                var tldpoint  = cartesianTransformer.TransformToVisible3D(xValue, yValue, actualZ1 <zStart?zLogStart : actualZ1> zEnd ? zLogEnd : z1value);
                tlpoint = new Point(tldpoint.X, tldpoint.Y);

                frontDepth = (z1value == zStart) ? tldpoint.Z : tldpoint.Z - ScatterHeight / 2 < tldpoint.Z - depthDelta ? tldpoint.Z - depthDelta : tldpoint.Z - ScatterHeight / 2;
                backDepth  = (z2value == zEnd) ? tldpoint.Z : tldpoint.Z + ScatterHeight / 2 > tldpoint.Z + depthDelta ? tldpoint.Z + depthDelta : tldpoint.Z + ScatterHeight / 2;
            }
            else
            {
                tlpoint = transformer.TransformToVisible(X, Y);
            }

            if (!series.Area.SeriesClipRect.Contains(tlpoint) &&
                ((xValue != xEnd && xValue != xStart) || (yValue != yEnd && yValue != yStart)) && !(series.IsTransposed))
            {
                return;
            }

            if (series.ScatterHeight <= 0 || series.ScatterWidth <= 0)
            {
                return;
            }

            x      = (xValue == (series.IsTransposed ? xEnd : xStart)) ? tlpoint.X : tlpoint.X - (series.IsTransposed ? ScatterHeight / 2 : ScatterWidth / 2);
            y      = (yValue == (series.IsTransposed ? yStart : yEnd)) ? tlpoint.Y : tlpoint.Y - (series.IsTransposed ? ScatterWidth / 2 : ScatterHeight / 2);
            width  = (xValue == xStart) || (xValue == xEnd) ? ScatterWidth / 2 : ScatterWidth;
            height = (yValue == yStart) || (yValue == yEnd) ? ScatterHeight / 2 : ScatterHeight;
            rect   = new Rect(x, y, width, height);

            if (!series.IsTransposed)
            {
                // Clipping segment of nearest range point
                if (!Series.ActualArea.SeriesClipRect.Contains(new Point(x, y)))
                {
                    rect = new Rect(x, Series.ActualArea.SeriesClipRect.Top, width, height + y);
                }
                if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left, rect.Bottom)))
                {
                    rect = new Rect(x, y, width, Math.Abs(height + (Series.ActualArea.SeriesClipRect.Bottom - rect.Bottom) > ScatterHeight ? height : height + (Series.ActualArea.SeriesClipRect.Bottom - rect.Bottom)));
                }
                if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left, rect.Top)))
                {
                    var modifiedWidth = Math.Abs(width - (Series.ActualXAxis.RenderedRect.X - rect.X));
                    rect = new Rect(Series.ActualXAxis.RenderedRect.X, y, modifiedWidth, rect.Height);
                }

                if (!Series.ActualArea.SeriesClipRect.Contains(new Point(rect.Left + rect.Width, rect.Top)))
                {
                    var modifiedWidth = Math.Abs(rect.Width + (Series.ActualArea.SeriesClipRect.Right - rect.Right));
                    rect = new Rect(rect.X, rect.Y, modifiedWidth, rect.Height);
                }
            }
            else
            {
                rect = new Rect(x, y, height, width);
                if (x < tlpoint.X && xValue == xStart && yValue == yStart)
                {
                    rect = new Rect(tlpoint.X, y, height, width);
                }
                if (y < tlpoint.Y && yValue == yStart)
                {
                    rect = new Rect(tlpoint.X, tlpoint.Y, height, width);
                }
                if (y == tlpoint.Y && yValue == yStart)
                {
                    rect = new Rect(tlpoint.X, tlpoint.Y - ScatterWidth / 2, height, width);
                }
                if (y < tlpoint.Y && xValue == xEnd)
                {
                    rect = new Rect(tlpoint.X, tlpoint.Y, height, width);
                }
                if (x == tlpoint.X && xValue == xEnd)
                {
                    rect = new Rect(tlpoint.X, tlpoint.Y, height, width);
                }
                if (x == tlpoint.X && xValue == xEnd && yValue != yStart)
                {
                    rect = new Rect(tlpoint.X - ScatterHeight / 2, tlpoint.Y, height, width);
                }
            }

            var area = Series.ActualArea as SfChart3D;

            Vector3D tlfVector = new Vector3D(0, 0, 0);
            Vector3D brbVector = new Vector3D(0, 0, 0);

            if (isZAxis)
            {
                tlfVector = new Vector3D(rect.Left, rect.Top, frontDepth);
                brbVector = new Vector3D(rect.Right, rect.Bottom, backDepth);
            }
            else
            {
                tlfVector = new Vector3D(rect.Left, rect.Top, startDepth);
                brbVector = new Vector3D(rect.Right, rect.Bottom, startDepth + ScatterHeight > endDepth ? endDepth : startDepth + ScatterHeight);
            }

            if (plans == null)
            {
                plans = Polygon3D.CreateBox(
                    tlfVector,
                    brbVector,
                    this,
                    series.Segments.IndexOf(this),
                    area.Graphics3D,
                    Stroke,
                    Interior,
                    StrokeThickness,
                    Series.IsActualTransposed);
            }
            else
            {
                Polygon3D.UpdateBox(plans, tlfVector, brbVector, Interior, Visibility.Visible);
            }
        }
Пример #20
0
 /// <summary>
 /// Removes the specified polygon.
 /// </summary>
 /// <param name="polygon">The polygon.</param>
 public void Remove(Polygon3D polygon)
 {
     this.treeBuilder.Remove(polygon);
 }
Пример #21
0
 /// <summary>
 /// Adds the specified poly.
 /// </summary>
 /// <param name="poly">The poly.</param>
 /// <returns>Returns the last index.</returns>
 public int Add(Polygon3D poly)
 {
     this.Polygons.Add(poly);
     return(this.Polygons.Count - 1);
 }