External/OxyPlot/OxyPlot/Axes/MagnitudeAxis.cs
author moel.mich
Sat, 08 Jun 2013 16:53:22 +0000
changeset 391 5be8f2773237
permissions -rw-r--r--
Added the source code of OxyPlot as of commit d190d7748a73 (6.5.2013).
     1 // --------------------------------------------------------------------------------------------------------------------
     2 // <copyright file="MagnitudeAxis.cs" company="OxyPlot">
     3 //   The MIT License (MIT)
     4 //
     5 //   Copyright (c) 2012 Oystein Bjorke
     6 //
     7 //   Permission is hereby granted, free of charge, to any person obtaining a
     8 //   copy of this software and associated documentation files (the
     9 //   "Software"), to deal in the Software without restriction, including
    10 //   without limitation the rights to use, copy, modify, merge, publish,
    11 //   distribute, sublicense, and/or sell copies of the Software, and to
    12 //   permit persons to whom the Software is furnished to do so, subject to
    13 //   the following conditions:
    14 //
    15 //   The above copyright notice and this permission notice shall be included
    16 //   in all copies or substantial portions of the Software.
    17 //
    18 //   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    19 //   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    20 //   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    21 //   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    22 //   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    23 //   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    24 //   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    25 // </copyright>
    26 // <summary>
    27 //   Represents a magnitude axis for polar plots.
    28 // </summary>
    29 // --------------------------------------------------------------------------------------------------------------------
    30 namespace OxyPlot.Axes
    31 {
    32     using System;
    33 
    34     /// <summary>
    35     /// Represents a magnitude axis for polar plots.
    36     /// </summary>
    37     public class MagnitudeAxis : LinearAxis
    38     {
    39         /// <summary>
    40         /// Initializes a new instance of the <see cref="MagnitudeAxis"/> class.
    41         /// </summary>
    42         public MagnitudeAxis()
    43         {
    44             this.Position = AxisPosition.Bottom;
    45             this.IsPanEnabled = false;
    46             this.IsZoomEnabled = false;
    47 
    48             this.MajorGridlineStyle = LineStyle.Solid;
    49             this.MinorGridlineStyle = LineStyle.Solid;
    50         }
    51 
    52         /// <summary>
    53         /// Initializes a new instance of the <see cref="MagnitudeAxis"/> class.
    54         /// </summary>
    55         /// <param name="minimum">
    56         /// The minimum.
    57         /// </param>
    58         /// <param name="maximum">
    59         /// The maximum.
    60         /// </param>
    61         /// <param name="majorStep">
    62         /// The major step.
    63         /// </param>
    64         /// <param name="minorStep">
    65         /// The minor step.
    66         /// </param>
    67         /// <param name="title">
    68         /// The title.
    69         /// </param>
    70         public MagnitudeAxis(
    71             double minimum = double.NaN,
    72             double maximum = double.NaN,
    73             double majorStep = double.NaN,
    74             double minorStep = double.NaN,
    75             string title = null)
    76             : this()
    77         {
    78             this.Minimum = minimum;
    79             this.Maximum = maximum;
    80             this.MajorStep = majorStep;
    81             this.MinorStep = minorStep;
    82             this.Title = title;
    83         }
    84 
    85         /// <summary>
    86         /// Gets or sets the midpoint (screen coordinates) of the plot area. This is used by polar coordinate systems.
    87         /// </summary>
    88         internal ScreenPoint MidPoint { get; set; }
    89 
    90         /// <summary>
    91         /// Inverse transform the specified screen point.
    92         /// </summary>
    93         /// <param name="x">
    94         /// The x coordinate.
    95         /// </param>
    96         /// <param name="y">
    97         /// The y coordinate.
    98         /// </param>
    99         /// <param name="yaxis">
   100         /// The y-axis.
   101         /// </param>
   102         /// <returns>
   103         /// The data point.
   104         /// </returns>
   105         public override DataPoint InverseTransform(double x, double y, Axis yaxis)
   106         {
   107             var angleAxis = yaxis as AngleAxis;
   108             if (angleAxis == null)
   109             {
   110                 throw new InvalidOperationException("Polar angle axis not defined!");
   111             }
   112 
   113             x -= this.MidPoint.x;
   114             y -= this.MidPoint.y;
   115             double th = Math.Atan2(y, x);
   116             double r = Math.Sqrt((x * x) + (y * y));
   117             x = (r / this.scale) + this.offset;
   118             y = (th / angleAxis.Scale) + angleAxis.Offset;
   119             return new DataPoint(x, y);
   120         }
   121 
   122         /// <summary>
   123         /// Determines whether the axis is used for X/Y values.
   124         /// </summary>
   125         /// <returns>
   126         /// <c>true</c> if it is an XY axis; otherwise, <c>false</c> .
   127         /// </returns>
   128         public override bool IsXyAxis()
   129         {
   130             return false;
   131         }
   132 
   133         /// <summary>
   134         /// Renders the axis on the specified render context.
   135         /// </summary>
   136         /// <param name="rc">The render context.</param>
   137         /// <param name="model">The model.</param>
   138         /// <param name="axisLayer">The rendering order.</param>
   139         /// <param name="pass"></param>
   140         public override void Render(IRenderContext rc, PlotModel model, AxisLayer axisLayer, int pass)
   141         {
   142             if (this.Layer != axisLayer)
   143             {
   144                 return;
   145             }
   146 
   147             var r = new MagnitudeAxisRenderer(rc, model);
   148             r.Render(this, pass);
   149         }
   150 
   151         /// <summary>
   152         /// Transforms the specified point to screen coordinates.
   153         /// </summary>
   154         /// <param name="x">
   155         /// The x value (for the current axis).
   156         /// </param>
   157         /// <param name="y">
   158         /// The y value.
   159         /// </param>
   160         /// <param name="yaxis">
   161         /// The y axis.
   162         /// </param>
   163         /// <returns>
   164         /// The transformed point.
   165         /// </returns>
   166         public override ScreenPoint Transform(double x, double y, Axis yaxis)
   167         {
   168             var angleAxis = yaxis as AngleAxis;
   169             if (angleAxis == null)
   170             {
   171                 throw new InvalidOperationException("Polar angle axis not defined!");
   172             }
   173 
   174             double r = (x - this.Offset) * this.scale;
   175             double theta = (y - angleAxis.Offset) * angleAxis.Scale;
   176 
   177             return new ScreenPoint(this.MidPoint.x + (r * Math.Cos(theta)), this.MidPoint.y - (r * Math.Sin(theta)));
   178         }
   179 
   180         /// <summary>
   181         /// Updates the scale and offset properties of the transform from the specified boundary rectangle.
   182         /// </summary>
   183         /// <param name="bounds">
   184         /// The bounds.
   185         /// </param>
   186         internal override void UpdateTransform(OxyRect bounds)
   187         {
   188             double x0 = bounds.Left;
   189             double x1 = bounds.Right;
   190             double y0 = bounds.Bottom;
   191             double y1 = bounds.Top;
   192 
   193             this.ScreenMin = new ScreenPoint(x0, y1);
   194             this.ScreenMax = new ScreenPoint(x1, y0);
   195 
   196             this.MidPoint = new ScreenPoint((x0 + x1) / 2, (y0 + y1) / 2);
   197 
   198             this.ActualMinimum = 0;
   199             double r = Math.Min(Math.Abs(x1 - x0), Math.Abs(y1 - y0));
   200             this.scale = 0.5 * r / (this.ActualMaximum - this.ActualMinimum);
   201             this.Offset = this.ActualMinimum;
   202         }
   203 
   204     }
   205 }