Version 4.6.0: Own Point and Matrix to work around rounding errors in UWP

This commit is contained in:
ClemensFischer 2018-03-06 22:22:58 +01:00
parent 30a5b6d53f
commit a3542bf106
30 changed files with 295 additions and 269 deletions

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -4,7 +4,6 @@
using System;
#if WINDOWS_UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

View file

@ -261,7 +261,7 @@ namespace MapControl
var center = new Point(rect.X + rect.Width / 2d, rect.Y + rect.Height / 2d);
rotation = parentMap.Heading;
viewportPosition = projection.ViewportTransform.Transform(center);
viewportPosition = projection.ViewportTransformMatrix.Transform(center);
if (parentMap.MapProjection.IsContinuous &&
(viewportPosition.X < 0d || viewportPosition.X > parentMap.RenderSize.Width ||

View file

@ -25,6 +25,8 @@ namespace MapControl
public const double Wgs84EquatorialRadius = 6378137d;
public const double MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d;
private Matrix inverseViewportTransformMatrix;
/// <summary>
/// Gets or sets the WMS 1.3.0 CRS Identifier.
/// </summary>
@ -56,6 +58,11 @@ namespace MapControl
/// </summary>
public double MaxLatitude { get; protected set; } = 90d;
/// <summary>
/// Gets the transformation matrix from cartesian map coordinates to viewport coordinates (pixels).
/// </summary>
public Matrix ViewportTransformMatrix { get; private set; }
/// <summary>
/// Gets the transformation from cartesian map coordinates to viewport coordinates (pixels).
/// </summary>
@ -112,7 +119,7 @@ namespace MapControl
/// </summary>
public Point LocationToViewportPoint(Location location)
{
return ViewportTransform.Transform(LocationToPoint(location));
return ViewportTransformMatrix.Transform(LocationToPoint(location));
}
/// <summary>
@ -120,7 +127,7 @@ namespace MapControl
/// </summary>
public Location ViewportPointToLocation(Point point)
{
return PointToLocation(ViewportTransform.Inverse.Transform(point));
return PointToLocation(inverseViewportTransformMatrix.Transform(point));
}
/// <summary>
@ -128,7 +135,9 @@ namespace MapControl
/// </summary>
public BoundingBox ViewportRectToBoundingBox(Rect rect)
{
return RectToBoundingBox(ViewportTransform.Inverse.TransformBounds(rect));
var transform = new MatrixTransform { Matrix = inverseViewportTransformMatrix };
return RectToBoundingBox(transform.TransformBounds(rect));
}
/// <summary>
@ -139,9 +148,14 @@ namespace MapControl
ViewportScale = Math.Pow(2d, zoomLevel) * PixelPerDegree / TrueScale;
var center = LocationToPoint(mapCenter);
ViewportTransform.Matrix = MatrixEx.TranslateScaleRotateTranslate(
var transformMatrix = CreateTransformMatrix(
-center.X, -center.Y, ViewportScale, -ViewportScale, heading, viewportCenter.X, viewportCenter.Y);
ViewportTransformMatrix = transformMatrix;
ViewportTransform.Matrix = transformMatrix;
transformMatrix.Invert();
inverseViewportTransformMatrix = transformMatrix;
}
/// <summary>
@ -173,5 +187,17 @@ namespace MapControl
return string.Format(CultureInfo.InvariantCulture, format, CrsId,
rect.X, rect.Y, (rect.X + rect.Width), (rect.Y + rect.Height), width, height);
}
public static Matrix CreateTransformMatrix(
double translation1X, double translation1Y,
double scaleX, double scaleY, double rotationAngle,
double translation2X, double translation2Y)
{
var matrix = new Matrix(1d, 0d, 0d, 1d, translation1X, translation1Y);
matrix.Scale(scaleX, scaleY);
matrix.Rotate(rotationAngle);
matrix.Translate(translation2X, translation2Y);
return matrix;
}
}
}

View file

@ -3,7 +3,6 @@
// Licensed under the Microsoft Public License (Ms-PL)
#if WINDOWS_UWP
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
#else
@ -98,7 +97,7 @@ namespace MapControl
protected Point LocationToViewportPoint(Location location)
{
return parentMap.MapProjection.ViewportTransform.Transform(LocationToPoint(location));
return parentMap.MapProjection.ViewportTransformMatrix.Transform(LocationToPoint(location));
}
protected double GetLongitudeOffset()

View file

@ -312,7 +312,7 @@ namespace MapControl
var transform = new MatrixTransform
{
Matrix = MatrixEx.TranslateScaleRotateTranslate(-viewCenterX, -viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
Matrix = MapProjection.CreateTransformMatrix(-viewCenterX, -viewCenterY, scale, scale, -parentMap.Heading, tileCenterX, tileCenterY)
};
var bounds = transform.TransformBounds(new Rect(0d, 0d, parentMap.RenderSize.Width, parentMap.RenderSize.Height));
@ -333,7 +333,7 @@ namespace MapControl
var viewCenterX = parentMap.RenderSize.Width / 2d;
var viewCenterY = parentMap.RenderSize.Height / 2d;
((MatrixTransform)RenderTransform).Matrix = MatrixEx.TranslateScaleRotateTranslate(
((MatrixTransform)RenderTransform).Matrix = MapProjection.CreateTransformMatrix(
-tileOriginX, -tileOriginY, scale, scale, parentMap.Heading, viewCenterX, viewCenterY);
}

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -3,9 +3,7 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
#if WINDOWS_UWP
using Windows.Foundation;
#else
#if !WINDOWS_UWP
using System.Windows;
#endif

View file

@ -2,20 +2,13 @@
// © 2018 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
namespace MapControl
{
internal static class Extensions
{
public static Point Transform(this GeneralTransform transform, Point point)
{
return transform.TransformPoint(point);
}
public static void BeginAnimation(this DependencyObject obj, DependencyProperty property, Timeline animation)
{
if (animation != null)

View file

@ -3,7 +3,6 @@
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Input;

View file

@ -153,7 +153,8 @@
<Compile Include="MapPolygon.UWP.cs" />
<Compile Include="MapPolyline.UWP.cs" />
<Compile Include="MapShape.UWP.cs" />
<Compile Include="MatrixEx.UWP.cs" />
<Compile Include="Matrix.UWP.cs" />
<Compile Include="Point.UWP.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tile.UWP.cs" />
<Compile Include="TileImageLoader.UWP.cs" />

View file

@ -15,8 +15,6 @@ namespace MapControl
public partial class MapGraticule
{
private Path path;
private Location graticuleStart;
private Location graticuleEnd;
public MapGraticule()
{
@ -75,104 +73,97 @@ namespace MapControl
Math.Min(Math.Max(labelEnd.Latitude + lineDistance, -projection.MaxLatitude), projection.MaxLatitude),
labelEnd.Longitude + lineDistance);
if (!lineStart.Equals(graticuleStart) || !lineEnd.Equals(graticuleEnd))
var geometry = (PathGeometry)path.Data;
geometry.Figures.Clear();
for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance)
{
graticuleStart = lineStart;
graticuleEnd = lineEnd;
var geometry = (PathGeometry)path.Data;
geometry.Figures.Clear();
geometry.Transform = projection.ViewportTransform;
for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance)
var figure = new PathFigure
{
var figure = new PathFigure
{
StartPoint = projection.LocationToPoint(new Location(lat, lineStart.Longitude)),
IsClosed = false,
IsFilled = false
};
StartPoint = projection.LocationToViewportPoint(new Location(lat, lineStart.Longitude)),
IsClosed = false,
IsFilled = false
};
figure.Segments.Add(new LineSegment
{
Point = projection.LocationToPoint(new Location(lat, lineEnd.Longitude)),
});
figure.Segments.Add(new LineSegment
{
Point = projection.LocationToViewportPoint(new Location(lat, lineEnd.Longitude))
});
geometry.Figures.Add(figure);
}
geometry.Figures.Add(figure);
}
for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance)
{
var figure = new PathFigure
{
StartPoint = projection.LocationToViewportPoint(new Location(lineStart.Latitude, lon)),
IsClosed = false,
IsFilled = false
};
figure.Segments.Add(new LineSegment
{
Point = projection.LocationToViewportPoint(new Location(lineEnd.Latitude, lon))
});
geometry.Figures.Add(figure);
}
var labelFormat = GetLabelFormat(lineDistance);
var childIndex = 1; // 0 for Path
for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance)
{
for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance)
{
var figure = new PathFigure
TextBlock label;
if (childIndex < Children.Count)
{
StartPoint = projection.LocationToPoint(new Location(lineStart.Latitude, lon)),
IsClosed = false,
IsFilled = false
};
figure.Segments.Add(new LineSegment
{
Point = projection.LocationToPoint(new Location(lineEnd.Latitude, lon)),
});
geometry.Figures.Add(figure);
}
var labelFormat = GetLabelFormat(lineDistance);
var childIndex = 1; // 0 for Path
for (var lat = labelStart.Latitude; lat <= bounds.North; lat += lineDistance)
{
for (var lon = labelStart.Longitude; lon <= bounds.East; lon += lineDistance)
{
TextBlock label;
if (childIndex < Children.Count)
{
label = (TextBlock)Children[childIndex];
}
else
{
var renderTransform = new TransformGroup();
renderTransform.Children.Add(new TranslateTransform());
renderTransform.Children.Add(ParentMap.RotateTransform);
renderTransform.Children.Add(new TranslateTransform());
label = new TextBlock
{
RenderTransform = renderTransform
};
label.SetBinding(TextBlock.ForegroundProperty,
GetBindingExpression(ForegroundProperty)?.ParentBinding ??
new Binding
{
Source = this,
Path = new PropertyPath("Foreground")
});
Children.Add(label);
}
childIndex++;
if (FontFamily != null)
{
label.FontFamily = FontFamily;
}
label.FontSize = FontSize;
label.FontStyle = FontStyle;
label.FontStretch = FontStretch;
label.FontWeight = FontWeight;
label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW");
label.Tag = new Location(lat, lon);
label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0];
translateTransform.X = StrokeThickness / 2d + 2d;
translateTransform.Y = -label.DesiredSize.Height / 2d;
label = (TextBlock)Children[childIndex];
}
else
{
var renderTransform = new TransformGroup();
renderTransform.Children.Add(new TranslateTransform());
renderTransform.Children.Add(ParentMap.RotateTransform);
renderTransform.Children.Add(new TranslateTransform());
label = new TextBlock
{
RenderTransform = renderTransform
};
label.SetBinding(TextBlock.ForegroundProperty,
GetBindingExpression(ForegroundProperty)?.ParentBinding ??
new Binding
{
Source = this,
Path = new PropertyPath("Foreground")
});
Children.Add(label);
}
childIndex++;
if (FontFamily != null)
{
label.FontFamily = FontFamily;
}
label.FontSize = FontSize;
label.FontStyle = FontStyle;
label.FontStretch = FontStretch;
label.FontWeight = FontWeight;
label.Text = GetLabelText(lat, labelFormat, "NS") + "\n" + GetLabelText(Location.NormalizeLongitude(lon), labelFormat, "EW");
label.Tag = new Location(lat, lon);
label.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var translateTransform = (TranslateTransform)((TransformGroup)label.RenderTransform).Children[0];
translateTransform.X = StrokeThickness / 2d + 2d;
translateTransform.Y = -label.DesiredSize.Height / 2d;
}
while (Children.Count > childIndex)
@ -196,9 +187,6 @@ namespace MapControl
else if (path != null)
{
path = null;
graticuleStart = null;
graticuleEnd = null;
Children.Clear();
}

View file

@ -0,0 +1,101 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2018 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
namespace MapControl
{
public struct Matrix
{
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; }
public static implicit operator Windows.UI.Xaml.Media.Matrix(Matrix m)
{
return new Windows.UI.Xaml.Media.Matrix(m.M11, m.M12, m.M21, m.M22, m.OffsetX, m.OffsetY);
}
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;
}
public Point Transform(Point p)
{
return new Point(M11 * p.X + M12 * p.Y + OffsetX, M21 * p.X + M22 * p.Y + OffsetY);
}
public void Translate(double x, double y)
{
OffsetX += x;
OffsetY += y;
}
public void Scale(double scaleX, double scaleY)
{
if (M12 != 0d || M21 != 0d)
{
throw new NotSupportedException("Scale not supported for rotated Matrix");
}
SetMatrix(scaleX * M11, 0d, 0d, scaleY * M22, scaleX * OffsetX, scaleY * OffsetY);
}
public void Rotate(double angle)
{
angle = (angle % 360d) / 180d * Math.PI;
if (angle != 0d)
{
var cos = Math.Cos(angle);
var sin = Math.Sin(angle);
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))
{
throw new InvalidOperationException("Matrix is not invertible");
}
SetMatrix(
invDet * M22,
invDet * -M12,
invDet * -M21,
invDet * M11,
invDet * (M21 * OffsetY - M22 * OffsetX),
invDet * (M12 * OffsetX - M11 * OffsetY));
}
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;
}
}
}

View file

@ -1,87 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2018 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System;
using Windows.UI.Xaml.Media;
namespace MapControl
{
internal static class MatrixEx
{
/// <summary>
/// Used in MapProjection and MapTileLayer.
/// </summary>
public static Matrix TranslateScaleRotateTranslate(
double translation1X, double translation1Y,
double scaleX, double scaleY, double rotationAngle,
double translation2X, double translation2Y)
{
var matrix = new Matrix(
scaleX, 0d, 0d, scaleY,
scaleX * translation1X,
scaleY * translation1Y);
if (rotationAngle != 0d)
{
rotationAngle = (rotationAngle % 360d) / 180d * Math.PI;
var cos = Math.Cos(rotationAngle);
var sin = Math.Sin(rotationAngle);
matrix = new Matrix(
matrix.M11 * cos - matrix.M12 * sin,
matrix.M11 * sin + matrix.M12 * cos,
matrix.M21 * cos - matrix.M22 * sin,
matrix.M21 * sin + matrix.M22 * cos,
cos * matrix.OffsetX - sin * matrix.OffsetY,
sin * matrix.OffsetX + cos * matrix.OffsetY);
}
matrix.OffsetX += translation2X;
matrix.OffsetY += translation2Y;
return matrix;
}
public static Matrix TranslateScaleRotateTranslate_(
double translation1X, double translation1Y,
double scaleX, double scaleY, double rotationAngle,
double translation2X, double translation2Y)
{
var m11 = scaleX;
var m12 = 0d;
var m21 = 0d;
var m22 = scaleY;
var offsetX = scaleX * translation1X;
var offsetY = scaleY * translation1Y;
if (rotationAngle != 0d)
{
rotationAngle = (rotationAngle % 360d) / 180d * Math.PI;
var cos = Math.Cos(rotationAngle);
var sin = Math.Sin(rotationAngle);
var _m11 = m11;
var _m12 = m12;
var _m21 = m21;
var _m22 = m22;
var _offsetX = offsetX;
var _offsetY = offsetY;
m11 = _m11 * cos - _m12 * sin;
m12 = _m11 * sin + _m12 * cos;
m21 = _m21 * cos - _m22 * sin;
m22 = _m21 * sin + _m22 * cos;
offsetX = cos * _offsetX - sin * _offsetY;
offsetY = sin * _offsetX + cos * _offsetY;
}
offsetX += translation2X;
offsetY += translation2Y;
return new Matrix(m11, m12, m21, m22, offsetX, offsetY);
}
}
}

View file

@ -0,0 +1,48 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2018 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
namespace MapControl
{
public struct Point
{
public double X { get; set; }
public double Y { get; set; }
public Point(double x, double y)
{
X = x;
Y = y;
}
public static implicit operator Point(Windows.Foundation.Point p)
{
return new Point(p.X, p.Y);
}
public static implicit operator Windows.Foundation.Point(Point p)
{
return new Windows.Foundation.Point(p.X, p.Y);
}
public static bool operator ==(Point p1, Point p2)
{
return p1.X == p2.X && p1.Y == p2.Y;
}
public static bool operator !=(Point p1, Point p2)
{
return !(p1 == p2);
}
public override bool Equals(object o)
{
return o is Point && this == (Point)o;
}
public override int GetHashCode()
{
return X.GetHashCode() ^ Y.GetHashCode();
}
}
}

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -177,7 +177,6 @@
<Compile Include="TileImageLoader.WPF.cs" />
<Compile Include="ImageLoader.WPF.cs" />
<Compile Include="TypeConverters.WPF.cs" />
<Compile Include="MatrixEx.WPF.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>

View file

@ -1,26 +0,0 @@
// XAML Map Control - https://github.com/ClemensFischer/XAML-Map-Control
// © 2018 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System.Windows.Media;
namespace MapControl
{
internal static class MatrixEx
{
/// <summary>
/// Used in MapProjection and MapTileLayer.
/// </summary>
public static Matrix TranslateScaleRotateTranslate(
double translation1X, double translation1Y,
double scaleX, double scaleY, double rotationAngle,
double translation2X, double translation2Y)
{
var matrix = new Matrix(1d, 0d, 0d, 1d, translation1X, translation1Y);
matrix.Scale(scaleX, scaleY);
matrix.Rotate(rotationAngle);
matrix.Translate(translation2X, translation2Y);
return matrix;
}
}
}

View file

@ -8,8 +8,8 @@ using System.Windows;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.5.0")]
[assembly: AssemblyFileVersion("4.5.0")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

View file

@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("4.4.1")]
[assembly: AssemblyFileVersion("4.4.1")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: ComVisible(false)]

View file

@ -11,8 +11,8 @@
<AssemblyName>UniversalApp</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10586.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
@ -70,7 +70,7 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
<UseDotNetNativeToolchain>false</UseDotNetNativeToolchain>
<EnableGatekeeperAnalysis>false</EnableGatekeeperAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
@ -156,7 +156,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.0.1</Version>
<Version>6.0.7</Version>
</PackageReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2018 Clemens Fischer")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("4.4.1")]
[assembly: AssemblyFileVersion("4.4.1")]
[assembly: AssemblyVersion("4.6.0")]
[assembly: AssemblyFileVersion("4.6.0")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]