1 /* 2 * NPlot - A charting library for .NET 3 * 4 * Transform2D.cs 5 * Copyright (C) 2003-2006 Matt Howlett and others. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without modification, 9 * are permitted provided that the following conditions are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, this 12 * list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 26 * OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 using System.Drawing; 30 31 namespace NPlot 32 { 33 /// <summary> 34 /// Encapsulates functionality for transforming world to physical coordinates optimally. 35 /// </summary> 36 /// <remarks>The existence of the whole ITransform2D thing might need revising. Not convinced it's the best way.</remarks> 37 public class Transform2D 38 { 39 /// <summary> 40 /// Constructs the optimal ITransform2D object for the supplied x and y axes. 41 /// </summary> 42 /// <param name="xAxis">The xAxis to use for the world to physical transform.</param> 43 /// <param name="yAxis">The yAxis to use for the world to physical transform.</param> 44 /// <returns>An ITransform2D derived object for converting from world to physical coordinates.</returns> GetTransformer(PhysicalAxis xAxis, PhysicalAxis yAxis)45 public static ITransform2D GetTransformer(PhysicalAxis xAxis, PhysicalAxis yAxis) 46 { 47 ITransform2D ret = null; 48 49 // if (xAxis.Axis.IsLinear && yAxis.Axis.IsLinear && !xAxis.Axis.Reversed && !yAxis.Axis.Reversed) 50 // ret = new FastTransform2D( xAxis, yAxis ); 51 // else 52 // ret = new DefaultTransform2D( xAxis, yAxis ); 53 54 ret = new DefaultTransform2D(xAxis, yAxis); 55 56 return ret; 57 } 58 59 /// <summary> 60 /// This class does world -> physical transforms for the general case 61 /// </summary> 62 public class DefaultTransform2D : ITransform2D 63 { 64 private readonly PhysicalAxis xAxis_; 65 private readonly PhysicalAxis yAxis_; 66 67 /// <summary> 68 /// Constructor 69 /// </summary> 70 /// <param name="xAxis">The x-axis to use for transforms</param> 71 /// <param name="yAxis">The y-axis to use for transforms</param> DefaultTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis)72 public DefaultTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis) 73 { 74 xAxis_ = xAxis; 75 yAxis_ = yAxis; 76 } 77 78 /// <summary> 79 /// Transforms the given world point to physical coordinates 80 /// </summary> 81 /// <param name="x">x coordinate of world point to transform.</param> 82 /// <param name="y">y coordinate of world point to transform.</param> 83 /// <returns>the corresponding physical point.</returns> Transform(double x, double y)84 public PointF Transform(double x, double y) 85 { 86 return new PointF( 87 xAxis_.WorldToPhysical(x, false).X, 88 yAxis_.WorldToPhysical(y, false).Y); 89 } 90 91 /// <summary> 92 /// Transforms the given world point to physical coordinates 93 /// </summary> 94 /// <param name="worldPoint">the world point to transform</param> 95 /// <returns>the corresponding physical point</returns> Transform(PointD worldPoint)96 public PointF Transform(PointD worldPoint) 97 { 98 return new PointF( 99 xAxis_.WorldToPhysical(worldPoint.X, false).X, 100 yAxis_.WorldToPhysical(worldPoint.Y, false).Y); 101 } 102 } 103 104 /// <summary> 105 /// This class does highly efficient world->physical and physical->world transforms 106 /// for linear axes. 107 /// </summary> 108 public class FastTransform2D : ITransform2D 109 { 110 private readonly PageAlignedPhysicalAxis xAxis_; 111 private readonly PageAlignedPhysicalAxis yAxis_; 112 113 /// <summary> 114 /// Constructor 115 /// </summary> 116 /// <param name="xAxis">The x-axis to use for transforms</param> 117 /// <param name="yAxis">The y-axis to use for transforms</param> FastTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis)118 public FastTransform2D(PhysicalAxis xAxis, PhysicalAxis yAxis) 119 { 120 xAxis_ = new PageAlignedPhysicalAxis(xAxis); 121 yAxis_ = new PageAlignedPhysicalAxis(yAxis); 122 } 123 124 /// <summary> 125 /// Transforms the given world point to physical coordinates 126 /// </summary> 127 /// <param name="x">x coordinate of world point to transform.</param> 128 /// <param name="y">y coordinate of world point to transform.</param> 129 /// <returns>the corresponding physical point.</returns> Transform(double x, double y)130 public PointF Transform(double x, double y) 131 { 132 return new PointF( 133 xAxis_.WorldToPhysicalClipped(x), 134 yAxis_.WorldToPhysicalClipped(y)); 135 } 136 137 /// <summary> 138 /// Transforms the given world point to physical coordinates 139 /// </summary> 140 /// <param name="worldPoint">the world point to transform</param> 141 /// <returns>the corresponding physical point</returns> Transform(PointD worldPoint)142 public PointF Transform(PointD worldPoint) 143 { 144 return new PointF( 145 xAxis_.WorldToPhysical(worldPoint.X), 146 yAxis_.WorldToPhysical(worldPoint.Y)); 147 } 148 } 149 } 150 }