Skip to content

Commit

Permalink
feat(geometry): Point3 distances
Browse files Browse the repository at this point in the history
EuclideanDistance
ManhattanDistance
ChebyshevDistance
MinkowskiDistance
  • Loading branch information
jirikostiha committed Jun 4, 2023
1 parent 2672d04 commit fda0ca1
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 0 deletions.
140 changes: 140 additions & 0 deletions src/code/SMath/Geometry3D/Point3.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using System.Numerics;
using System.Runtime.CompilerServices;

namespace SMath.GeometryD2
{
/// <summary>
/// Point in three dimensions.
/// </summary>
public static class Point3
{
/// <summary>
/// Euclidean distance of the point and origin.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Euclidean_distance">Wikipedia</a>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static N Distance<N>((N X, N Y, N Z) point)
where N : IRootFunctions<N>
=> PT.Hypotenuse(point);

/// <summary>
/// Euclidean distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Euclidean_distance">Wikipedia</a>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static N Distance<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2)
where N : IRootFunctions<N>
=> PT.Hypotenuse(point2.X - point1.X, point2.Y - point1.Y, point2.Z - point1.Z);

/// <summary>
/// Manhattan or taxicab distance of point and origin.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Minkowski_distance">Wikipedia</a>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static N ManhattanDistance<N>((N X, N Y, N Z) point)
where N : INumberBase<N>
=> N.Abs(point.X + point.Y + point.Z);

/// <summary>
/// Manhattan or taxicab distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Minkowski_distance">Wikipedia</a>
/// </remarks>
public static N ManhattanDistance<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2)
where N : INumberBase<N>
=> N.Abs(point1.X - point2.X) + N.Abs(point1.Y - point2.Y) + N.Abs(point1.Z - point2.Z);

/// <summary>
/// Chebyshev distance of point and origin
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Chebyshev_distance">Wikipedia</a>
/// </remarks>
public static N ChebyshevDistance<N>((N X, N Y, N Z) point)
where N : INumber<N>
=> N.Max(N.Max(N.Abs(point.X), N.Abs(point.Y)), N.Abs(point.Z));

/// <summary>
/// Chebyshev distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Chebyshev_distance">Wikipedia</a>
/// </remarks>
public static N ChebyshevDistance<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2)
where N : INumber<N>
=> N.Max(N.Max(N.Abs(point1.X - point2.X), N.Abs(point1.Y - point2.Y)), N.Abs(point1.Z - point2.Z));

/// <summary>
/// Minkowski distance of point and origin.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Minkowski_distance">Wikipedia</a>
/// </remarks>
public static N MinkowskiDistance<N>((N X, N Y, N Z) point, N r)
where N : IPowerFunctions<N>
=> N.Pow(N.Pow(N.Abs(point.X), r) + N.Pow(N.Abs(point.Y), r) + N.Pow(N.Abs(point.Z), r), N.One / r);

/// <summary>
/// Minkowski distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Minkowski_distance">Wikipedia</a>
/// </remarks>
public static N MinkowskiDistance<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2, N r)
where N : IPowerFunctions<N>
=> N.Pow(
N.Pow(N.Abs(point1.X - point2.X), r)
+ N.Pow(N.Abs(point1.Y - point2.Y), r)
+ N.Pow(N.Abs(point1.Z - point2.Z), r),
N.One / r);

/// <summary>
/// Canberra distance of point and origin.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Canberra_distance">Wikipedia</a>
/// </remarks>
//public static N CanberraDistance<N>((N X, N Y, N Z) point)
// where N : INumberBase<N>
// => N.Abs(point.X) / N.Abs(point.X); //todo

/// <summary>
/// Canberra distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Canberra_distance">Wikipedia</a>
/// </remarks>
public static N CanberraDistance<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2)
where N : INumberBase<N>
=> N.Abs(point1.X - point2.X) / (N.Abs(point1.X) + N.Abs(point2.X))
+ N.Abs(point1.Y - point2.Y) / (N.Abs(point1.Y) + N.Abs(point2.Y))
+ N.Abs(point1.Z - point2.Z) / (N.Abs(point1.Z) + N.Abs(point2.Z));

/// <summary>
/// Bray–Curtis dissimilarity or distance of point and origin.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Bray%E2%80%93Curtis_dissimilarity">Wikipedia</a>
/// </remarks>
//public static double BrayCurtisDissimilarity<N>((N X, N Y, N Z) point)
// where N : INumber<N>
// => default;

/// <summary>
/// Bray–Curtis dissimilarity or distance of two points.
/// </summary>
/// <remarks>
/// <a href="https://en.wikipedia.org/wiki/Bray%E2%80%93Curtis_dissimilarity">Wikipedia</a>
/// </remarks>
//public static N BrayCurtisDissimilarity<N>((N X, N Y, N Z) point1, (N X, N Y, N Z) point2)
// where N : INumberBase<N>
// => default;
}
}
6 changes: 6 additions & 0 deletions src/code/SMath/PythagorasTheorem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public static N Hypotenuse<N>(N leg1, N leg2, N leg3)
where N : IRootFunctions<N>
=> N.Sqrt((leg1 * leg1) + (leg2 * leg2) + (leg3 * leg3));

/// <summary> Calculate length of hypotenuse of a right-angled triangle like object. </summary>
public static N Hypotenuse<N>((N First, N Second, N Third) legs)
where N : IRootFunctions<N>
=> N.Sqrt((legs.First * legs.First) + (legs.Second * legs.Second) + (legs.Third * legs.Third));


public static N Leg<N>(N hypotenuse, N otherLeg1, N otherLeg2)
where N : IRootFunctions<N>
=> N.Sqrt((hypotenuse * hypotenuse) - (otherLeg1 * otherLeg1) - (otherLeg2 * otherLeg2));
Expand Down
52 changes: 52 additions & 0 deletions src/quality/SMath__Tests/Geometry3D/Point3Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using SMath.GeometryD2;
using Xunit;

namespace SMath.Geometry2D
{
public class Point3Tests
{
[Theory]
[InlineData(0, 0, 0, 1, 0, 0, 1)]
[InlineData(0, 0, 0, 1, 1, 1, 3)]
[InlineData(1, 1, 1, -1, -1, -1, 6)]
public void ManhattanDistance(double x1, double y1, double z1, double x2, double y2, double z2, double distance)
{
Assert.Equal(distance, Point3.ManhattanDistance((x1, y1, z1), (x2, y2, z2)));
Assert.Equal(distance, Point3.ManhattanDistance((x2 - x1, y2 - y1, z2 - z1)));
}

[Theory]
[InlineData(0, 0, 0, 1, 0, 0, 1)]
[InlineData(0, 0, 0, 1, 1, 1, 1)]
[InlineData(1, 1, 1, -1, -1, -1, 2)]
public void ChebyshevDistance(double x1, double y1, double z1, double x2, double y2, double z2, double distance)
{
Assert.Equal(distance, Point3.ChebyshevDistance((x1, y1, z1), (x2, y2, z2)));
Assert.Equal(distance, Point3.ChebyshevDistance((x2 - x1, y2 - y1, z2 - z1)));
}

[Theory]
[InlineData(0, 0, 0, 1, 0, 0, 1, 1)]
[InlineData(0, 0, 0, 1, 1, 1, 1, 3)]
[InlineData(1, 1, 1, -1, -1, -1, 1, 6)]
public void MinkowskiDistance(double x1, double y1, double z1, double x2, double y2, double z2, double r, double distance)
{
Assert.Equal(distance, Point3.MinkowskiDistance((x1, y1, z1), (x2, y2, z2), r));
Assert.Equal(distance, Point3.MinkowskiDistance((x2 - x1, y2 - y1, z2 - z1), r));
}

//[Theory]
//[InlineData(0, 0, 1, 0, 1)] //todo
//public void CanberraDistance(double x1, double y1, double x2, double y2, double distance)
//{
// Assert.Equal(distance, Point2.CanberraDistance((x1, y1), (x2, y2)));
//}

//[Theory]
//[InlineData(0, 0, 1, 0, 1)] //todo
//public void BrayCurtisDissimilarity(double x1, double y1, double x2, double y2, double distance)
//{
// Assert.Equal(distance, Point2.BrayCurtisDissimilarity((x1, y1), (x2, y2)));
//}
}
}

0 comments on commit fda0ca1

Please sign in to comment.