2018-03-06 22:22:58 +01:00
|
|
|
|
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
|
2024-02-03 21:01:53 +01:00
|
|
|
|
// Copyright © 2024 Clemens Fischer
|
2018-03-06 22:22:58 +01:00
|
|
|
|
// Licensed under the Microsoft Public License (Ms-PL)
|
|
|
|
|
|
|
|
|
|
|
|
using System;
|
2024-05-22 11:25:32 +02:00
|
|
|
|
#if UWP
|
2022-12-04 20:10:00 +01:00
|
|
|
|
using WindowsUI = Windows.UI;
|
2024-05-22 11:25:32 +02:00
|
|
|
|
#else
|
|
|
|
|
|
using WindowsUI = Microsoft.UI;
|
2021-06-14 21:41:37 +02:00
|
|
|
|
#endif
|
2018-03-06 22:22:58 +01:00
|
|
|
|
|
|
|
|
|
|
namespace MapControl
|
|
|
|
|
|
{
|
2019-10-25 19:56:23 +02:00
|
|
|
|
/// <summary>
|
2022-12-04 20:10:00 +01:00
|
|
|
|
/// Replaces Windows.UI.Xaml.Media.Matrix for double floating point precision.
|
2019-10-25 19:56:23 +02:00
|
|
|
|
/// </summary>
|
2018-03-06 22:22:58 +01:00
|
|
|
|
public struct Matrix
|
|
|
|
|
|
{
|
|
|
|
|
|
public Matrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY)
|
|
|
|
|
|
{
|
|
|
|
|
|
M11 = m11;
|
|
|
|
|
|
M12 = m12;
|
|
|
|
|
|
M21 = m21;
|
|
|
|
|
|
M22 = m22;
|
|
|
|
|
|
OffsetX = offsetX;
|
|
|
|
|
|
OffsetY = offsetY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-01 23:01:06 +01:00
|
|
|
|
public double M11 { get; set; }
|
|
|
|
|
|
public double M12 { get; set; }
|
|
|
|
|
|
public double M21 { get; set; }
|
|
|
|
|
|
public double M22 { get; set; }
|
|
|
|
|
|
public double OffsetX { get; set; }
|
|
|
|
|
|
public double OffsetY { get; set; }
|
|
|
|
|
|
|
2022-12-04 20:10:00 +01:00
|
|
|
|
public static implicit operator WindowsUI.Xaml.Media.Matrix(Matrix m)
|
2018-03-08 07:48:41 +01:00
|
|
|
|
{
|
2022-12-04 20:10:00 +01:00
|
|
|
|
return new WindowsUI.Xaml.Media.Matrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static implicit operator Matrix(WindowsUI.Xaml.Media.Matrix m)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new Matrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY);
|
2018-03-08 07:48:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-06 22:22:58 +01:00
|
|
|
|
public Point Transform(Point p)
|
|
|
|
|
|
{
|
2022-12-04 20:10:00 +01:00
|
|
|
|
return new Point(
|
|
|
|
|
|
M11 * p.X + M21 * p.Y + OffsetX,
|
|
|
|
|
|
M12 * p.X + M22 * p.Y + OffsetY);
|
2018-03-06 22:22:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Translate(double x, double y)
|
|
|
|
|
|
{
|
|
|
|
|
|
OffsetX += x;
|
|
|
|
|
|
OffsetY += y;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Rotate(double angle)
|
|
|
|
|
|
{
|
|
|
|
|
|
angle = (angle % 360d) / 180d * Math.PI;
|
|
|
|
|
|
|
|
|
|
|
|
if (angle != 0d)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cos = Math.Cos(angle);
|
|
|
|
|
|
var sin = Math.Sin(angle);
|
|
|
|
|
|
|
2022-12-03 20:55:17 +01:00
|
|
|
|
// Multiply(new Matrix(cos, sin, -sin, cos, 0d, 0d));
|
|
|
|
|
|
|
2018-03-06 22:22:58 +01:00
|
|
|
|
SetMatrix(
|
|
|
|
|
|
cos * M11 - sin * M12,
|
|
|
|
|
|
sin * M11 + cos * M12,
|
|
|
|
|
|
cos * M21 - sin * M22,
|
|
|
|
|
|
sin * M21 + cos * M22,
|
|
|
|
|
|
cos * OffsetX - sin * OffsetY,
|
|
|
|
|
|
sin * OffsetX + cos * OffsetY);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void Invert()
|
|
|
|
|
|
{
|
|
|
|
|
|
var invDet = 1d / (M11 * M22 - M12 * M21);
|
|
|
|
|
|
|
|
|
|
|
|
if (double.IsInfinity(invDet))
|
|
|
|
|
|
{
|
2018-08-25 18:50:52 +02:00
|
|
|
|
throw new InvalidOperationException("Matrix is not invertible.");
|
2018-03-06 22:22:58 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetMatrix(
|
2018-03-07 22:19:16 +01:00
|
|
|
|
invDet * M22, invDet * -M12, invDet * -M21, invDet * M11,
|
2018-03-06 22:22:58 +01:00
|
|
|
|
invDet * (M21 * OffsetY - M22 * OffsetX),
|
|
|
|
|
|
invDet * (M12 * OffsetX - M11 * OffsetY));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-12-03 20:55:17 +01:00
|
|
|
|
public void Multiply(Matrix m)
|
|
|
|
|
|
{
|
|
|
|
|
|
SetMatrix(
|
|
|
|
|
|
M11 * m.M11 + M12 * m.M21,
|
|
|
|
|
|
M11 * m.M12 + M12 * m.M22,
|
|
|
|
|
|
M21 * m.M11 + M22 * m.M21,
|
|
|
|
|
|
M21 * m.M12 + M22 * m.M22,
|
|
|
|
|
|
OffsetX * m.M11 + OffsetY * m.M21 + m.OffsetX,
|
|
|
|
|
|
OffsetX * m.M12 + OffsetY * m.M22 + m.OffsetY);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-06 22:22:58 +01:00
|
|
|
|
private void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY)
|
|
|
|
|
|
{
|
|
|
|
|
|
M11 = m11;
|
|
|
|
|
|
M12 = m12;
|
|
|
|
|
|
M21 = m21;
|
|
|
|
|
|
M22 = m22;
|
|
|
|
|
|
OffsetX = offsetX;
|
|
|
|
|
|
OffsetY = offsetY;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|