mirror of https://github.com/SixLabors/ImageSharp
8 changed files with 266 additions and 120 deletions
@ -0,0 +1,40 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
|
||||
|
namespace SixLabors |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Provides common mathematical methods.
|
||||
|
/// </summary>
|
||||
|
internal static class MathFExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Converts a degree (360-periodic) angle to a radian (2*Pi-periodic) angle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="degree">The angle in degrees.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="float"/> representing the degree as radians.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static float DegreeToRadian(float degree) |
||||
|
{ |
||||
|
return degree * (MathF.PI / 180F); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Converts a radian (2*Pi-periodic) angle to a degree (360-periodic) angle.
|
||||
|
/// </summary>
|
||||
|
/// <param name="radian">The angle in radians.</param>
|
||||
|
/// <returns>
|
||||
|
/// The <see cref="float"/> representing the degree as radians.
|
||||
|
/// </returns>
|
||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
|
public static float RadianToDegree(float radian) |
||||
|
{ |
||||
|
return radian / (MathF.PI / 180F); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
namespace SixLabors.Tests.Helpers |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Allows the comparison of single-precision floating point values by precision.
|
||||
|
/// </summary>
|
||||
|
public struct FloatRoundingComparer : IEqualityComparer<float>, IEqualityComparer<Vector4> |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="FloatRoundingComparer"/> struct.
|
||||
|
/// </summary>
|
||||
|
/// <param name="precision">The number of decimal places (valid values: 0-7)</param>
|
||||
|
public FloatRoundingComparer(int precision) |
||||
|
{ |
||||
|
Guard.MustBeBetweenOrEqualTo(precision, 0, 7, nameof(precision)); |
||||
|
this.Precision = precision; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the number of decimal places (valid values: 0-7)
|
||||
|
/// </summary>
|
||||
|
public int Precision { get; } |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public bool Equals(float x, float y) |
||||
|
{ |
||||
|
float xp = (float)Math.Round(x, this.Precision, MidpointRounding.AwayFromZero); |
||||
|
float yp = (float)Math.Round(y, this.Precision, MidpointRounding.AwayFromZero); |
||||
|
|
||||
|
return Comparer<float>.Default.Compare(xp, yp) == 0; |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public bool Equals(Vector4 x, Vector4 y) |
||||
|
{ |
||||
|
return this.Equals(x.X, y.X) && this.Equals(x.Y, y.Y) && this.Equals(x.Z, y.Z) && this.Equals(x.W, y.W); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public int GetHashCode(float obj) |
||||
|
{ |
||||
|
unchecked |
||||
|
{ |
||||
|
int hashCode = obj.GetHashCode(); |
||||
|
hashCode = (hashCode * 397) ^ this.Precision.GetHashCode(); |
||||
|
return hashCode; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc />
|
||||
|
public int GetHashCode(Vector4 obj) => HashHelpers.Combine(obj.GetHashCode(), this.Precision.GetHashCode()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,107 @@ |
|||||
|
// Copyright (c) Six Labors and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using System; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace SixLabors.Tests.Helpers |
||||
|
{ |
||||
|
public class MathFTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void MathF_PI_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.PI, (float)Math.PI); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Ceililng_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Ceiling(0.3333F), (float)Math.Ceiling(0.3333F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Cos_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Cos(0.3333F), (float)Math.Cos(0.3333F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Abs_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Abs(-0.3333F), (float)Math.Abs(-0.3333F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Atan2_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Atan2(1.2345F, 1.2345F), (float)Math.Atan2(1.2345F, 1.2345F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Exp_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Exp(1.2345F), (float)Math.Exp(1.2345F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Floor_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Floor(1.2345F), (float)Math.Floor(1.2345F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Min_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Min(1.2345F, 5.4321F), (float)Math.Min(1.2345F, 5.4321F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Max_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Max(1.2345F, 5.4321F), (float)Math.Max(1.2345F, 5.4321F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Pow_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Pow(1.2345F, 5.4321F), (float)Math.Pow(1.2345F, 5.4321F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Round_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Round(1.2345F), (float)Math.Round(1.2345F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Round_With_Midpoint_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Round(1.2345F, MidpointRounding.AwayFromZero), (float)Math.Round(1.2345F, MidpointRounding.AwayFromZero)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Sin_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Sin(1.2345F), (float)Math.Sin(1.2345F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MathF_Sqrt_Is_Equal() |
||||
|
{ |
||||
|
Assert.Equal(MathF.Sqrt(2F), (float)Math.Sqrt(2F)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Convert_Degree_To_Radian() |
||||
|
{ |
||||
|
Assert.Equal((float)(Math.PI / 2D), MathFExtensions.DegreeToRadian(90F), new FloatRoundingComparer(6)); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Convert_Radian_To_Degree() |
||||
|
{ |
||||
|
Assert.Equal(60F, MathFExtensions.RadianToDegree((float)(Math.PI / 3D)), new FloatRoundingComparer(5)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue