Esempio n. 1
0
        /// <summary>
        /// Builds isoline data for 2d scalar field contained in data source.
        /// </summary>
        /// <returns>Collection of data describing built isolines.</returns>
        public IsolineCollection BuildIsoline()
        {
            VerifyDataSource();

            segments = new IsolineCollection();

            minMax = (double.IsNaN(missingValue) ? dataSource.GetMinMax() : dataSource.GetMinMax(missingValue));

            segments.Min = minMax.Min;
            segments.Max = minMax.Max;

            if (!minMax.IsEmpty)
            {
                values = dataSource.Data;
                double[] levels = GetLevelsForIsolines();

                foreach (double level in levels)
                {
                    PrepareCells(level);
                }

                if (segments.Lines.Count > 0 && segments.Lines[segments.Lines.Count - 1].OtherPoints.Count == 0)
                {
                    segments.Lines.RemoveAt(segments.Lines.Count - 1);
                }
            }
            return(segments);
        }
        private IEnumerable <double> GetAdditionalIsolines(IsolineCollection collection)
        {
            var dataSource         = DataSource;
            var visibleMinMax      = dataSource.GetMinMax(Plotter2D.Visible);
            var visibleMinMaxRatio = (collection.Max - collection.Min) / visibleMinMax.GetLength();

            var log = Math.Log10(visibleMinMaxRatio);

            if (log > 0.9)
            {
                var upperLog     = Math.Ceiling(log);
                var divisionsNum = Math.Pow(10, upperLog);
                var delta        = (collection.Max - collection.Min) / divisionsNum;

                var start = Math.Ceiling(visibleMinMax.Min / delta) * delta;

                var x = start;
                while (x < visibleMinMax.Max)
                {
                    yield return(x);

                    x += delta;
                }
            }
        }
        protected IEnumerable <double> GetAdditionalLevels(IsolineCollection collection)
        {
            var    dataSource         = DataSource;
            var    visibleMinMax      = dataSource.GetMinMax(Plotter2D.Visible);
            double totalDelta         = collection.Max - collection.Min;
            double visibleMinMaxRatio = totalDelta / visibleMinMax.GetLength();
            double defaultDelta       = totalDelta / 12;

            if (true || 2 * defaultDelta < visibleMinMaxRatio)
            {
                double number = Math.Ceiling(visibleMinMaxRatio * 4);
                number = Math.Pow(2, Math.Ceiling(Math.Log(number) / Math.Log(2)));
                double delta = totalDelta / number;
                double x     = collection.Min + Math.Ceiling((visibleMinMax.Min - collection.Min) / delta) * delta;

                List <double> result = new List <double>();
                while (x < visibleMinMax.Max)
                {
                    result.Add(x);
                    x += delta;
                }

                return(result);
            }

            return(Enumerable.Empty <double>());
        }
Esempio n. 4
0
        /// <summary>
        /// Annotates the specified isoline collection.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="visible">The visible rectangle.</param>
        /// <returns></returns>
        public Collection <IsolineTextLabel> Annotate(IsolineCollection collection, DataRect visible)
        {
            Collection <IsolineTextLabel> res = new Collection <IsolineTextLabel>();

            foreach (var line in collection.Lines)
            {
                double way = 0;

                var forwardSegments = line.GetSegments();
                using (var forwardEnumerator = forwardSegments.GetEnumerator())
                {
                    forwardEnumerator.MoveNext();

                    foreach (var segment in line.GetSegments())
                    {
                        bool hasForwardSegment = forwardEnumerator.MoveNext();

                        double length = segment.GetLength();
                        way += length;
                        if (way > wayBeforeText)
                        {
                            way = 0;

                            var rotation = (segment.Max - segment.Min).ToAngle();
                            if (hasForwardSegment)
                            {
                                var forwardSegment = forwardEnumerator.Current;
                                rotation = (rotation + (forwardSegment.Max - forwardSegment.Min).ToAngle()) / 2;
                            }

                            res.Add(new IsolineTextLabel
                            {
                                Value    = line.RealValue,
                                Position = segment.Max,
                                Rotation = rotation
                            });
                        }
                    }
                }
            }

            return(res);
        }
        private void RenderLabels(DrawingContext dc, IsolineCollection collection)
        {
            if (Plotter2D == null)
            {
                return;
            }
            if (collection == null)
            {
                return;
            }
            if (!DrawLabels)
            {
                return;
            }

            var viewportBounds = ViewportPanel.GetViewportBounds(this);

            if (viewportBounds.IsEmpty)
            {
                return;
            }

            var strokeThickness = StrokeThickness;
            var visible         = Plotter2D.Visible;
            var output          = Plotter2D.Viewport.Output;

            var transform         = Plotter2D.Transform.WithRects(viewportBounds, new Rect(RenderSize));
            var labelStringFormat = LabelStringFormat;

            // drawing constants
            var labelRectangleFill = Brushes.White;

            var biggerViewport = viewportBounds.ZoomOutFromCenter(1.1);

            // getting and filtering annotations to draw only visible ones
            Annotater.WayBeforeText = Math.Sqrt(visible.Width * visible.Width + visible.Height * visible.Height) / 100 * WayBeforeTextMultiplier;
            var annotations = Annotater.Annotate(collection, visible)
                              .Where(annotation =>
            {
                Point viewportPosition = annotation.Position.DataToViewport(transform);
                return(biggerViewport.Contains(viewportPosition));
            });

            // drawing annotations
            foreach (var annotation in annotations)
            {
                FormattedText text     = CreateFormattedText(annotation.Value.ToString(LabelStringFormat));
                Point         position = annotation.Position.DataToScreen(transform);

                var labelTransform = CreateTransform(annotation, text, position);

                // creating rectange stroke
                double colorRatio = (annotation.Value - collection.Min) / (collection.Max - collection.Min);
                colorRatio = MathHelper.Clamp(colorRatio);
                Color           rectangleStrokeColor    = Palette.GetColor(colorRatio);
                SolidColorBrush rectangleStroke         = new SolidColorBrush(rectangleStrokeColor);
                Pen             labelRectangleStrokePen = new Pen(rectangleStroke, 2);

                dc.PushTransform(labelTransform);
                {
                    var bounds = RectExtensions.FromCenterSize(position, new Size(text.Width, text.Height));
                    bounds = bounds.ZoomOutFromCenter(1.3);
                    dc.DrawRoundedRectangle(labelRectangleFill, labelRectangleStrokePen, bounds, 8, 8);

                    DrawTextInPosition(dc, text, position);
                }
                dc.Pop();
            }
        }
        protected void RenderIsolineCollection(DrawingContext dc, double strokeThickness, IsolineCollection collection, CoordinateTransform transform)
        {
            foreach (LevelLine line in collection)
            {
                StreamGeometry lineGeometry = new StreamGeometry();
                using (var context = lineGeometry.Open())
                {
                    context.BeginFigure(line.StartPoint.ViewportToScreen(transform), false, false);
                    if (!UseBezierCurves)
                    {
                        context.PolyLineTo(line.OtherPoints.ViewportToScreen(transform).ToArray(), true, true);
                    }
                    else
                    {
                        context.PolyBezierTo(BezierBuilder.GetBezierPoints(line.AllPoints.ViewportToScreen(transform).ToArray()).Skip(1).ToArray(), true, true);
                    }
                }
                lineGeometry.Freeze();

                Pen pen = new Pen(new SolidColorBrush(Palette.GetColor(line.Value01)), strokeThickness);

                dc.DrawGeometry(null, pen, lineGeometry);
            }
        }