Files
DynamicDataDisplay/Transforms/CoordinateTransform.cs
2024-02-23 00:46:06 -05:00

188 lines
6.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Research.DynamicDataDisplay.Common;
using System.Diagnostics;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay
{
/// <summary>
/// A central class in 2d coordinate transformation in DynamicDataDisplay.
/// Provides methods to transform point from one coordinate system to another.
/// Should be immutable.
/// </summary>
public sealed class CoordinateTransform
{
private CoordinateTransform(DataRect visibleRect, Rect screenRect)
{
this.visibleRect = visibleRect;
this.screenRect = screenRect;
rxToScreen = screenRect.Width / visibleRect.Width;
ryToScreen = screenRect.Height / visibleRect.Height;
cxToScreen = visibleRect.XMin * rxToScreen - screenRect.Left;
cyToScreen = screenRect.Height + screenRect.Top + visibleRect.YMin * ryToScreen;
rxToData = visibleRect.Width / screenRect.Width;
ryToData = visibleRect.Height / screenRect.Height;
cxToData = screenRect.Left * rxToData - visibleRect.XMin;
cyToData = visibleRect.Height + visibleRect.YMin + screenRect.Top * ryToData;
}
#region Coeffs
double rxToScreen;
double ryToScreen;
double cxToScreen;
double cyToScreen;
double rxToData;
double ryToData;
double cxToData;
double cyToData;
#endregion
#region Creation methods
internal static CoordinateTransform FromRects(DataRect visibleRect, Rect screenRect)
{
CoordinateTransform result = new CoordinateTransform(visibleRect, screenRect);
return result;
}
internal CoordinateTransform WithRects(DataRect visibleRect, Rect screenRect)
{
CoordinateTransform copy = new CoordinateTransform(visibleRect, screenRect);
copy.dataTransform = dataTransform;
return copy;
}
/// <summary>
/// Creates a new instance of CoordinateTransform with the given data transform.
/// </summary>
/// <param name="dataTransform">The data transform.</param>
/// <returns></returns>
public CoordinateTransform WithDataTransform(DataTransform dataTransform)
{
if (dataTransform == null)
throw new ArgumentNullException("dataTransform");
CoordinateTransform copy = new CoordinateTransform(visibleRect, screenRect);
copy.dataTransform = dataTransform;
return copy;
}
internal CoordinateTransform WithScreenOffset(double x, double y)
{
Rect screenCopy = screenRect;
screenCopy.Offset(x, y);
CoordinateTransform copy = new CoordinateTransform(visibleRect, screenCopy);
return copy;
}
internal static CoordinateTransform CreateDefault()
{
CoordinateTransform transform = new CoordinateTransform(new Rect(0, 0, 1, 1), new Rect(0, 0, 1, 1));
return transform;
}
#endregion
#region Transform methods
/// <summary>
/// Transforms point from data coordinates to screen.
/// </summary>
/// <param name="dataPoint">The point in data coordinates.</param>
/// <returns></returns>
public Point DataToScreen(Point dataPoint)
{
Point viewportPoint = dataTransform.DataToViewport(dataPoint);
Point screenPoint = new Point(viewportPoint.X * rxToScreen - cxToScreen,
cyToScreen - viewportPoint.Y * ryToScreen);
return screenPoint;
}
/// <summary>
/// Transforms point from screen coordinates to data coordinates.
/// </summary>
/// <param name="screenPoint">The point in screen coordinates.</param>
/// <returns></returns>
public Point ScreenToData(Point screenPoint)
{
Point viewportPoint = new Point(screenPoint.X * rxToData - cxToData,
cyToData - screenPoint.Y * ryToData);
Point dataPoint = dataTransform.ViewportToData(viewportPoint);
return dataPoint;
}
/// <summary>
/// Transforms point from viewport coordinates to screen coordinates.
/// </summary>
/// <param name="viewportPoint">The point in viewport coordinates.</param>
/// <returns></returns>
public Point ViewportToScreen(Point viewportPoint)
{
Point screenPoint = new Point(viewportPoint.X * rxToScreen - cxToScreen,
cyToScreen - viewportPoint.Y * ryToScreen);
return screenPoint;
}
/// <summary>
/// Transforms point from screen coordinates to viewport coordinates.
/// </summary>
/// <param name="screenPoint">The point in screen coordinates.</param>
/// <returns></returns>
public Point ScreenToViewport(Point screenPoint)
{
Point viewportPoint = new Point(screenPoint.X * rxToData - cxToData,
cyToData - screenPoint.Y * ryToData);
return viewportPoint;
}
#endregion
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private DataRect visibleRect;
/// <summary>
/// Gets the viewport rectangle.
/// </summary>
/// <value>The viewport rect.</value>
public DataRect ViewportRect
{
get { return visibleRect; }
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Rect screenRect;
/// <summary>
/// Gets the screen rectangle.
/// </summary>
/// <value>The screen rect.</value>
public Rect ScreenRect
{
get { return screenRect; }
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private DataTransform dataTransform = DataTransforms.Identity;
/// <summary>
/// Gets the data transform.
/// </summary>
/// <value>The data transform.</value>
public DataTransform DataTransform
{
get { return dataTransform; }
}
}
}