Esempio n. 1
0
        public override void Render(IRenderContext rc)
        {
            var origin = XAxis.InverseTransform(XAxis.ScreenMin.X, YAxis.ScreenMin.Y, YAxis);
            var end    = XAxis.InverseTransform(XAxis.ScreenMax.X, YAxis.ScreenMax.Y, YAxis);

            var state = new BufferState
            {
                MinX   = origin.X,
                MaxX   = end.X,
                MinY   = origin.Y,
                MaxY   = end.Y,
                Width  = XAxis.ScreenMax.X - XAxis.ScreenMin.X,
                Height = YAxis.ScreenMax.Y - YAxis.ScreenMin.Y
            };

            if (!state.Equals(_buffer))
            {
                var g      = Math.Max(1, (Int32)Math.Sqrt(state.Width * state.Height / 50000.0));
                var width  = (Int32)state.Width / g;
                var height = (Int32)state.Height / g;
                var scaleX = (XAxis.ScreenMax.X - XAxis.ScreenMin.X) / width;
                var scaleY = (YAxis.ScreenMax.Y - YAxis.ScreenMin.Y) / height;
                var pixels = new OxyColor[width, height];
                _buffer.ReplaceWith(state);

                var dx = (end.X - origin.X) / width;
                var dy = (end.Y - origin.Y) / height;
                var sx = XAxis.ScreenMin.X;
                var z  = new ScalarValue(origin.X, 0.0);

                for (var i = 0; i < width; i++)
                {
                    var sy = YAxis.ScreenMin.Y;
                    z.ImaginaryValue = origin.Y;

                    for (var j = 0; j < height; j++)
                    {
                        var value = _f(z);
                        pixels[i, j]      = value.GetColor();
                        sy               += scaleY;
                        z.ImaginaryValue += dy;
                    }

                    z.Value += dx;
                    sx      += scaleX;
                }

                _points = OxyImage.Create(pixels, ImageFormat.Png);
            }

            rc.DrawImage(_points, XAxis.ScreenMin.X, YAxis.ScreenMin.Y, state.Width, state.Height, 1.0, true);
        }
Esempio n. 2
0
        private Point InverseTransform(Point point)
        {
            if (XAxis != null)
            {
                return(XAxis.InverseTransform(point.X, point.Y, YAxis));
            }

            if (YAxis != null)
            {
                return(new Point(0, YAxis.InverseTransform(point.Y)));
            }

            return(new Point());
        }
Esempio n. 3
0
        /// <summary>
        /// Calculates the actual minimums and maximums.
        /// </summary>
        protected virtual void CalculateActualMinimumsMaximums()
        {
            this.actualMinimumX = Math.Max(this.MinimumX, this.XAxis.ActualMinimum);
            this.actualMaximumX = Math.Min(this.MaximumX, this.XAxis.ActualMaximum);
            this.actualMinimumY = Math.Max(this.MinimumY, this.YAxis.ActualMinimum);
            this.actualMaximumY = Math.Min(this.MaximumY, this.YAxis.ActualMaximum);

            if (!this.ClipByXAxis)
            {
                double right = XAxis.InverseTransform(PlotModel.PlotArea.Right);
                double left  = XAxis.InverseTransform(PlotModel.PlotArea.Left);
                this.actualMaximumX = Math.Max(left, right);
                this.actualMinimumX = Math.Min(left, right);
            }

            if (!this.ClipByYAxis)
            {
                double bottom = YAxis.InverseTransform(PlotModel.PlotArea.Bottom);
                double top    = YAxis.InverseTransform(PlotModel.PlotArea.Top);
                this.actualMaximumY = Math.Max(top, bottom);
                this.actualMinimumY = Math.Min(top, bottom);
            }
        }
Esempio n. 4
0
 internal Vector2 InverseTransformVector(WindowsVector vector)
 {
     return((CheckAxes() ? (WindowsVector)XAxis.InverseTransform(vector.X, vector.Y, YAxis, isVector: true) : vector).ToVector2());
 }
Esempio n. 5
0
 internal Vector2 InverseTransformPoint(WindowsPoint point)
 {
     return((CheckAxes() ? XAxis.InverseTransform(point.X, point.Y, YAxis) : point).ToVector2());
 }
Esempio n. 6
0
        /// <summary>
        /// Renders the line annotation.
        /// </summary>
        /// <param name="rc">
        /// The render context.
        /// </param>
        /// <param name="model">
        /// The plot model.
        /// </param>
        public override void Render(IRenderContext rc, PlotModel model)
        {
            base.Render(rc, model);

            bool aliased = false;

            double actualMinimumX = Math.Max(this.MinimumX, this.XAxis.ActualMinimum);
            double actualMaximumX = Math.Min(this.MaximumX, this.XAxis.ActualMaximum);
            double actualMinimumY = Math.Max(this.MinimumY, this.YAxis.ActualMinimum);
            double actualMaximumY = Math.Min(this.MaximumY, this.YAxis.ActualMaximum);

            if (!this.ClipByXAxis)
            {
                double right = XAxis.InverseTransform(PlotModel.PlotArea.Right);
                double left  = XAxis.InverseTransform(PlotModel.PlotArea.Left);
                actualMaximumX = Math.Max(left, right);
                actualMinimumX = Math.Min(left, right);
            }

            if (!this.ClipByYAxis)
            {
                double bottom = YAxis.InverseTransform(PlotModel.PlotArea.Bottom);
                double top    = YAxis.InverseTransform(PlotModel.PlotArea.Top);
                actualMaximumY = Math.Max(top, bottom);
                actualMinimumY = Math.Min(top, bottom);
            }

            // y=f(x)
            Func <double, double> fx = null;

            // x=f(y)
            Func <double, double> fy = null;

            switch (this.Type)
            {
            case LineAnnotationType.Horizontal:
                fx = x => this.Y;
                break;

            case LineAnnotationType.Vertical:
                fy = y => this.X;
                break;

            case LineAnnotationType.EquationY:
                fx = this.Equation;
                break;

            case LineAnnotationType.EquationX:
                fy = this.Equation;
                break;

            default:
                fx = x => (this.Slope * x) + this.Intercept;
                break;
            }

            var points = new List <DataPoint>();

            bool isCurvedLine = !(this.XAxis is LinearAxis) || !(this.YAxis is LinearAxis) || this.Type == LineAnnotationType.EquationY;

            if (!isCurvedLine)
            {
                // we only need to calculate two points if it is a straight line
                if (fx != null)
                {
                    points.Add(new DataPoint(actualMinimumX, fx(actualMinimumX)));
                    points.Add(new DataPoint(actualMaximumX, fx(actualMaximumX)));
                }
                else if (fy != null)
                {
                    points.Add(new DataPoint(fy(actualMinimumY), actualMinimumY));
                    points.Add(new DataPoint(fy(actualMaximumY), actualMaximumY));
                }

                if (this.Type == LineAnnotationType.Horizontal || this.Type == LineAnnotationType.Vertical)
                {
                    // use aliased line drawing for horizontal and vertical lines
                    aliased = true;
                }
            }
            else
            {
                if (fx != null)
                {
                    double x = actualMinimumX;

                    // todo: the step size should be adaptive
                    double dx = (actualMaximumX - actualMinimumX) / 100;
                    while (true)
                    {
                        points.Add(new DataPoint(x, fx(x)));
                        if (x > actualMaximumX)
                        {
                            break;
                        }

                        x += dx;
                    }
                }
                else if (fy != null)
                {
                    double y = actualMinimumY;

                    // todo: the step size should be adaptive
                    double dy = (actualMaximumY - actualMinimumY) / 100;
                    while (true)
                    {
                        points.Add(new DataPoint(fy(y), y));
                        if (y > actualMaximumY)
                        {
                            break;
                        }

                        y += dy;
                    }
                }
            }

            // transform to screen coordinates
            this.screenPoints = points.Select(p => this.Transform(p)).ToList();

            // clip to the area defined by the axes
            var clippingRectangle = OxyRect.Create(
                this.ClipByXAxis ? this.XAxis.ScreenMin.X : PlotModel.PlotArea.Left,
                this.ClipByYAxis ? this.YAxis.ScreenMin.Y : PlotModel.PlotArea.Top,
                this.ClipByXAxis ? this.XAxis.ScreenMax.X : PlotModel.PlotArea.Right,
                this.ClipByYAxis ? this.YAxis.ScreenMax.Y : PlotModel.PlotArea.Bottom);

            const double MinimumSegmentLength = 4;

            IList <ScreenPoint> clippedPoints = null;

            rc.DrawClippedLine(
                this.screenPoints,
                clippingRectangle,
                MinimumSegmentLength * MinimumSegmentLength,
                this.GetSelectableColor(this.Color),
                this.StrokeThickness,
                this.LineStyle,
                this.LineJoin,
                aliased,
                pts => clippedPoints = pts);

            ScreenPoint position;
            double      angle;
            double      margin = this.TextMargin;

            if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
            {
                margin = 0;
            }
            else
            {
                margin *= this.TextPosition < 0.5 ? 1 : -1;
            }

            if (clippedPoints != null && GetPointAtRelativeDistance(clippedPoints, this.TextPosition, margin, out position, out angle))
            {
                if (angle < -90)
                {
                    angle += 180;
                }

                if (angle > 90)
                {
                    angle -= 180;
                }

                switch (this.TextOrientation)
                {
                case AnnotationTextOrientation.Horizontal:
                    angle = 0;
                    break;

                case AnnotationTextOrientation.Vertical:
                    angle = -90;
                    break;
                }

                // Apply 'padding' to the position
                var angleInRadians = angle / 180 * Math.PI;
                var f = 1;

                if (this.TextHorizontalAlignment == HorizontalAlignment.Right)
                {
                    f = -1;
                }

                if (this.TextHorizontalAlignment == HorizontalAlignment.Center)
                {
                    f = 0;
                }

                position.X += f * this.TextPadding * Math.Cos(angleInRadians);
                position.Y += f * this.TextPadding * Math.Sin(angleInRadians);

                var cs = new CohenSutherlandClipping(clippingRectangle);
                if (!string.IsNullOrEmpty(this.Text) && cs.IsInside(position))
                {
                    rc.DrawClippedText(
                        clippingRectangle,
                        position,
                        this.Text,
                        this.ActualTextColor,
                        this.ActualFont,
                        this.ActualFontSize,
                        this.ActualFontWeight,
                        angle,
                        this.TextHorizontalAlignment,
                        this.TextVerticalAlignment);
                }
            }
        }