change fields to autoproperties + add equality comparators
parent
3ac5eb48f7
commit
f957e8c3f4
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using MoonTools.Core.Curve.Extensions;
|
using MoonTools.Core.Curve.Extensions;
|
||||||
|
|
||||||
|
@ -6,45 +7,48 @@ namespace MoonTools.Core.Curve
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A 2-dimensional Bezier curve defined by 4 points.
|
/// A 2-dimensional Bezier curve defined by 4 points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct CubicBezierCurve2D
|
public struct CubicBezierCurve2D : IEquatable<CubicBezierCurve2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start point.
|
/// The start point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p0;
|
public Vector2 P0 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The first control point.
|
/// The first control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p1;
|
public Vector2 P1 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The second control point.
|
/// The second control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p2;
|
public Vector2 P2 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The end point.
|
/// The end point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p3;
|
public Vector2 P3 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A representation of a 2D cubic Bezier curve.
|
||||||
|
/// </summary>
|
||||||
/// <param name="p0">The start point.</param>
|
/// <param name="p0">The start point.</param>
|
||||||
/// <param name="p1">The first control point.</param>
|
/// <param name="p1">The first control point.</param>
|
||||||
/// <param name="p2">The second control point.</param>
|
/// <param name="p2">The second control point.</param>
|
||||||
/// <param name="p3">The end point.</param>
|
/// <param name="p3">The end point.</param>
|
||||||
public CubicBezierCurve2D(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
|
public CubicBezierCurve2D(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
|
||||||
{
|
{
|
||||||
this.p0 = p0;
|
P0 = p0;
|
||||||
this.p1 = p1;
|
P1 = p1;
|
||||||
this.p2 = p2;
|
P2 = p2;
|
||||||
this.p3 = p3;
|
P3 = p3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by t.
|
/// Returns the curve coordinate given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector2 Point(float t) => Point(p0, p1, p2, p3, t);
|
public Vector2 Point(float t) => Point(P0, P1, P2, P3, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by a normalized time value.
|
/// Returns the curve coordinate given by a normalized time value.
|
||||||
|
@ -52,13 +56,13 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A value between startTime and endTime.</param>
|
/// <param name="t">A value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector2 Point(float t, float startTime, float endTime) => Point(p0, p1, p2, p3, t, startTime, endTime);
|
public Vector2 Point(float t, float startTime, float endTime) => Point(P0, P1, P2, P3, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by t.
|
/// Returns the instantaneous velocity on the curve given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector2 Velocity(float t) => Velocity(p0, p1, p2, p3, t);
|
public Vector2 Velocity(float t) => Velocity(P0, P1, P2, P3, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
||||||
|
@ -66,7 +70,7 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A value between startTime and endTime.</param>
|
/// <param name="t">A value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector2 Velocity(float t, float startTime, float endTime) => Velocity(p0, p1, p2, p3, TimeHelper.Normalized(t, startTime, endTime));
|
public Vector2 Velocity(float t, float startTime, float endTime) => Velocity(P0, P1, P2, P3, TimeHelper.Normalized(t, startTime, endTime));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by 4 points and a time value.
|
/// Returns the curve coordinate given by 4 points and a time value.
|
||||||
|
@ -128,12 +132,40 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="p1">The first control point.</param>
|
/// <param name="p1">The first control point.</param>
|
||||||
/// <param name="p2">The second control point.</param>
|
/// <param name="p2">The second control point.</param>
|
||||||
/// <param name="p3">The end point.</param>
|
/// <param name="p3">The end point.</param>
|
||||||
/// <param name="t">A value between startTime and endTime.</param>
|
/// <param name="t">A value between minT and maxT.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="minT">The starting time value.</param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="maxT">The ending time value.</param>
|
||||||
public static Vector2 Velocity(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t, float minT, float maxT)
|
public static Vector2 Velocity(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float t, float minT, float maxT)
|
||||||
{
|
{
|
||||||
return Velocity(p0, p1, p2, p3, TimeHelper.Normalized(t, minT, maxT));
|
return Velocity(p0, p1, p2, p3, TimeHelper.Normalized(t, minT, maxT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is CubicBezierCurve2D d && Equals(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(CubicBezierCurve2D other)
|
||||||
|
{
|
||||||
|
return P0.Equals(other.P0) &&
|
||||||
|
P1.Equals(other.P1) &&
|
||||||
|
P2.Equals(other.P2) &&
|
||||||
|
P3.Equals(other.P3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(P0, P1, P2, P3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(CubicBezierCurve2D left, CubicBezierCurve2D right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(CubicBezierCurve2D left, CubicBezierCurve2D right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace MoonTools.Core.Curve
|
namespace MoonTools.Core.Curve
|
||||||
|
@ -5,45 +6,48 @@ namespace MoonTools.Core.Curve
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A 3-dimensional Bezier curve defined by 4 points.
|
/// A 3-dimensional Bezier curve defined by 4 points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct CubicBezierCurve3D
|
public struct CubicBezierCurve3D : IEquatable<CubicBezierCurve3D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start point.
|
/// The start point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p0;
|
public Vector3 P0 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The first control point.
|
/// The first control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p1;
|
public Vector3 P1 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The second control point.
|
/// The second control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p2;
|
public Vector3 P2 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The end point.
|
/// The end point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p3;
|
public Vector3 P3 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A representation of a 3D cubic Bezier curve.
|
||||||
|
/// </summary>
|
||||||
/// <param name="p0">The start point.</param>
|
/// <param name="p0">The start point.</param>
|
||||||
/// <param name="p1">The first control point.</param>
|
/// <param name="p1">The first control point.</param>
|
||||||
/// <param name="p2">The second control point.</param>
|
/// <param name="p2">The second control point.</param>
|
||||||
/// <param name="p3">The end point.</param>
|
/// <param name="p3">The end point.</param>
|
||||||
public CubicBezierCurve3D(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
|
public CubicBezierCurve3D(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
|
||||||
{
|
{
|
||||||
this.p0 = p0;
|
P0 = p0;
|
||||||
this.p1 = p1;
|
P1 = p1;
|
||||||
this.p2 = p2;
|
P2 = p2;
|
||||||
this.p3 = p3;
|
P3 = p3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by t.
|
/// Returns the curve coordinate given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector3 Point(float t) => Point(p0, p1, p2, p3, t);
|
public Vector3 Point(float t) => Point(P0, P1, P2, P3, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by a normalized time value.
|
/// Returns the curve coordinate given by a normalized time value.
|
||||||
|
@ -51,13 +55,13 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t"></param>
|
/// <param name="t"></param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector3 Point(float t, float startTime, float endTime) => Point(p0, p1, p2, p3, t, startTime, endTime);
|
public Vector3 Point(float t, float startTime, float endTime) => Point(P0, P1, P2, P3, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by t.
|
/// Returns the instantaneous velocity on the curve given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector3 Velocity(float t) => Velocity(p0, p1, p2, p3, t);
|
public Vector3 Velocity(float t) => Velocity(P0, P1, P2, P3, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
||||||
|
@ -65,7 +69,7 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector3 Velocity(float t, float startTime, float endTime) => Velocity(p0, p1, p2, p3, t, startTime, endTime);
|
public Vector3 Velocity(float t, float startTime, float endTime) => Velocity(P0, P1, P2, P3, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by 4 points and a time value.
|
/// Returns the curve coordinate given by 4 points and a time value.
|
||||||
|
@ -79,10 +83,10 @@ namespace MoonTools.Core.Curve
|
||||||
{
|
{
|
||||||
ArgumentChecker.CheckT(t);
|
ArgumentChecker.CheckT(t);
|
||||||
|
|
||||||
return (1f - t) * (1f - t) * (1f - t) * p0 +
|
return ((1f - t) * (1f - t) * (1f - t) * p0) +
|
||||||
3f * (1f - t) * (1f - t) * t * p1 +
|
(3f * (1f - t) * (1f - t) * t * p1) +
|
||||||
3f * (1f - t) * t * t * p2 +
|
(3f * (1f - t) * t * t * p2) +
|
||||||
t * t * t * p3;
|
(t * t * t * p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -113,9 +117,9 @@ namespace MoonTools.Core.Curve
|
||||||
{
|
{
|
||||||
ArgumentChecker.CheckT(t);
|
ArgumentChecker.CheckT(t);
|
||||||
|
|
||||||
return 3f * (1f - t) * (1f - t) * (p1 - p0) +
|
return (3f * (1f - t) * (1f - t) * (p1 - p0)) +
|
||||||
6f * (1f - t) * t * (p2 - p1) +
|
(6f * (1f - t) * t * (p2 - p1)) +
|
||||||
3f * t * t * (p3 - p2);
|
(3f * t * t * (p3 - p2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -128,11 +132,38 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A value between startTime and endTime.</param>
|
/// <param name="t">A value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
/// <returns></returns>
|
|
||||||
public static Vector3 Velocity(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t, float startTime, float endTime)
|
public static Vector3 Velocity(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t, float startTime, float endTime)
|
||||||
{
|
{
|
||||||
ArgumentChecker.CheckT(t, startTime, endTime);
|
ArgumentChecker.CheckT(t, startTime, endTime);
|
||||||
return Velocity(p0, p1, p2, p3, TimeHelper.Normalized(t, startTime, endTime));
|
return Velocity(p0, p1, p2, p3, TimeHelper.Normalized(t, startTime, endTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is CubicBezierCurve3D d && Equals(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(CubicBezierCurve3D other)
|
||||||
|
{
|
||||||
|
return P0.Equals(other.P0) &&
|
||||||
|
P1.Equals(other.P1) &&
|
||||||
|
P2.Equals(other.P2) &&
|
||||||
|
P3.Equals(other.P3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(P0, P1, P2, P3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(CubicBezierCurve3D left, CubicBezierCurve3D right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(CubicBezierCurve3D left, CubicBezierCurve3D right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.1</Version>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netstandard2.1</TargetFramework>
|
||||||
|
@ -14,4 +14,10 @@
|
||||||
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>LGPL-3.0-only</PackageLicenseExpression>
|
||||||
<PackageProjectUrl>https://github.com/MoonsideGames/MoonTools.Core.Curve</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/MoonsideGames/MoonTools.Core.Curve</PackageProjectUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,43 +1,47 @@
|
||||||
using System.Numerics;
|
|
||||||
using MoonTools.Core.Curve.Extensions;
|
using MoonTools.Core.Curve.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
namespace MoonTools.Core.Curve
|
namespace MoonTools.Core.Curve
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A 2-dimensional Bezier curve defined by 3 points.
|
/// A 2-dimensional Bezier curve defined by 3 points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct QuadraticBezierCurve2D
|
public struct QuadraticBezierCurve2D : IEquatable<QuadraticBezierCurve2D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start point.
|
/// The start point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p0;
|
public Vector2 P0 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control point.
|
/// The control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p1;
|
public Vector2 P1 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The end point.
|
/// The end point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector2 p2;
|
public Vector2 P2 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A representation of a 2D quadratic Bezier curve.
|
||||||
|
/// </summary>
|
||||||
/// <param name="p0">The start point.</param>
|
/// <param name="p0">The start point.</param>
|
||||||
/// <param name="p1">The control point.</param>
|
/// <param name="p1">The control point.</param>
|
||||||
/// <param name="p2">The end point.</param>
|
/// <param name="p2">The end point.</param>
|
||||||
public QuadraticBezierCurve2D(Vector2 p0, Vector2 p1, Vector2 p2)
|
public QuadraticBezierCurve2D(Vector2 p0, Vector2 p1, Vector2 p2)
|
||||||
{
|
{
|
||||||
this.p0 = p0;
|
P0 = p0;
|
||||||
this.p1 = p1;
|
P1 = p1;
|
||||||
this.p2 = p2;
|
P2 = p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by t.
|
/// Returns the curve coordinate given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector2 Point(float t) => Point(p0, p1, p2, t);
|
public Vector2 Point(float t) => Point(P0, P1, P2, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by a normalized time value.
|
/// Returns the curve coordinate given by a normalized time value.
|
||||||
|
@ -45,13 +49,13 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A time value between startTime and endTime.</param>
|
/// <param name="t">A time value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector2 Point(float t, float startTime, float endTime) => Point(p0, p1, p2, t, startTime, endTime);
|
public Vector2 Point(float t, float startTime, float endTime) => Point(P0, P1, P2, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by t.
|
/// Returns the instantaneous velocity on the curve given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector2 Velocity(float t) => Velocity(p0, p1, p2, t);
|
public Vector2 Velocity(float t) => Velocity(P0, P1, P2, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
||||||
|
@ -59,14 +63,14 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A value between startTime and endTime.</param>
|
/// <param name="t">A value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector2 Velocity(float t, float startTime, float endTime) => Velocity(p0, p1, p2, t, startTime, endTime);
|
public Vector2 Velocity(float t, float startTime, float endTime) => Velocity(P0, P1, P2, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs degree elevation on the curve to turn it into a Cubic Bezier curve.
|
/// Performs degree elevation on the curve to turn it into a Cubic Bezier curve.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CubicBezierCurve2D AsCubic()
|
public CubicBezierCurve2D AsCubic()
|
||||||
{
|
{
|
||||||
var (p0, p1, p2, p3) = AsCubic(this.p0, this.p1, this.p2);
|
var (p0, p1, p2, p3) = AsCubic(this.P0, this.P1, this.P2);
|
||||||
return new CubicBezierCurve2D(p0, p1, p2, p3);
|
return new CubicBezierCurve2D(p0, p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,5 +148,32 @@ namespace MoonTools.Core.Curve
|
||||||
{
|
{
|
||||||
return Velocity(p0, p1, p2, TimeHelper.Normalized(t, startTime, endTime));
|
return Velocity(p0, p1, p2, TimeHelper.Normalized(t, startTime, endTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is QuadraticBezierCurve2D d && Equals(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(QuadraticBezierCurve2D other)
|
||||||
|
{
|
||||||
|
return P0.Equals(other.P0) &&
|
||||||
|
P1.Equals(other.P1) &&
|
||||||
|
P2.Equals(other.P2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(P0, P1, P2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(QuadraticBezierCurve2D left, QuadraticBezierCurve2D right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(QuadraticBezierCurve2D left, QuadraticBezierCurve2D right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
using System;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
|
||||||
namespace MoonTools.Core.Curve
|
namespace MoonTools.Core.Curve
|
||||||
|
@ -5,38 +6,41 @@ namespace MoonTools.Core.Curve
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A 3-dimensional Bezier curve defined by 3 points.
|
/// A 3-dimensional Bezier curve defined by 3 points.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct QuadraticBezierCurve3D
|
public struct QuadraticBezierCurve3D : IEquatable<QuadraticBezierCurve3D>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start point.
|
/// The start point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p0;
|
public Vector3 P0 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The control point.
|
/// The control point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p1;
|
public Vector3 P1 { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The end point.
|
/// The end point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Vector3 p2;
|
public Vector3 P2 { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A representation of a 3D quadratic Bezier curve.
|
||||||
|
/// </summary>
|
||||||
/// <param name="p0">The start point.</param>
|
/// <param name="p0">The start point.</param>
|
||||||
/// <param name="p1">The control point.</param>
|
/// <param name="p1">The control point.</param>
|
||||||
/// <param name="p2">The end point.</param>
|
/// <param name="p2">The end point.</param>
|
||||||
public QuadraticBezierCurve3D(Vector3 p0, Vector3 p1, Vector3 p2)
|
public QuadraticBezierCurve3D(Vector3 p0, Vector3 p1, Vector3 p2)
|
||||||
{
|
{
|
||||||
this.p0 = p0;
|
this.P0 = p0;
|
||||||
this.p1 = p1;
|
this.P1 = p1;
|
||||||
this.p2 = p2;
|
this.P2 = p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by t.
|
/// Returns the curve coordinate given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector3 Point(float t) => Point(p0, p1, p2, t);
|
public Vector3 Point(float t) => Point(P0, P1, P2, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the curve coordinate given by a normalized time value.
|
/// Returns the curve coordinate given by a normalized time value.
|
||||||
|
@ -44,13 +48,13 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">A time value between startTime and endTime.</param>
|
/// <param name="t">A time value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector3 Point(float t, float startTime, float endTime) => Point(p0, p1, p2, t, startTime, endTime);
|
public Vector3 Point(float t, float startTime, float endTime) => Point(P0, P1, P2, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by t.
|
/// Returns the instantaneous velocity on the curve given by t.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="t">A value between 0 and 1.</param>
|
/// <param name="t">A value between 0 and 1.</param>
|
||||||
public Vector3 Velocity(float t) => Velocity(p0, p1, p2, t);
|
public Vector3 Velocity(float t) => Velocity(P0, P1, P2, t);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
/// Returns the instantaneous velocity on the curve given by a normalized time value.
|
||||||
|
@ -58,7 +62,7 @@ namespace MoonTools.Core.Curve
|
||||||
/// <param name="t">An arbitrary value between startTime and endTime.</param>
|
/// <param name="t">An arbitrary value between startTime and endTime.</param>
|
||||||
/// <param name="startTime"></param>
|
/// <param name="startTime"></param>
|
||||||
/// <param name="endTime"></param>
|
/// <param name="endTime"></param>
|
||||||
public Vector3 Velocity(float t, float startTime, float endTime) => Velocity(p0, p1, p2, t, startTime, endTime);
|
public Vector3 Velocity(float t, float startTime, float endTime) => Velocity(P0, P1, P2, t, startTime, endTime);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs degree elevation on the curve to turn it into a Cubic Bezier curve.
|
/// Performs degree elevation on the curve to turn it into a Cubic Bezier curve.
|
||||||
|
@ -66,7 +70,7 @@ namespace MoonTools.Core.Curve
|
||||||
/// <returns>The same curve expressed as a cubic curve.</returns>
|
/// <returns>The same curve expressed as a cubic curve.</returns>
|
||||||
public CubicBezierCurve3D AsCubic()
|
public CubicBezierCurve3D AsCubic()
|
||||||
{
|
{
|
||||||
var (p0, p1, p2, p3) = AsCubic(this.p0, this.p1, this.p2);
|
var (p0, p1, p2, p3) = AsCubic(this.P0, this.P1, this.P2);
|
||||||
return new CubicBezierCurve3D(p0, p1, p2, p3);
|
return new CubicBezierCurve3D(p0, p1, p2, p3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,5 +142,32 @@ namespace MoonTools.Core.Curve
|
||||||
var (cubicP0, cubicP1, cubicP2, cubicP3) = AsCubic(p0, p1, p2);
|
var (cubicP0, cubicP1, cubicP2, cubicP3) = AsCubic(p0, p1, p2);
|
||||||
return CubicBezierCurve3D.Velocity(cubicP0, cubicP1, cubicP2, cubicP3, t, startTime, endTime);
|
return CubicBezierCurve3D.Velocity(cubicP0, cubicP1, cubicP2, cubicP3, t, startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return obj is QuadraticBezierCurve3D d && Equals(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(QuadraticBezierCurve3D other)
|
||||||
|
{
|
||||||
|
return P0.Equals(other.P0) &&
|
||||||
|
P1.Equals(other.P1) &&
|
||||||
|
P2.Equals(other.P2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return HashCode.Combine(P0, P1, P2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(QuadraticBezierCurve3D left, QuadraticBezierCurve3D right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(QuadraticBezierCurve3D left, QuadraticBezierCurve3D right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,6 @@ namespace MoonTools.Core.Curve
|
||||||
{
|
{
|
||||||
public static class TimeHelper
|
public static class TimeHelper
|
||||||
{
|
{
|
||||||
public static float Normalized(float t, float minT, float maxT) => ((t - minT)) / (maxT - minT);
|
public static float Normalized(float t, float minT, float maxT) => (t - minT) / (maxT - minT);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -144,5 +144,45 @@ namespace Tests
|
||||||
|
|
||||||
myCurve.Invoking(x => x.Velocity(15, 2, 5)).Should().Throw<ArgumentException>();
|
myCurve.Invoking(x => x.Velocity(15, 2, 5)).Should().Throw<ArgumentException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Equals()
|
||||||
|
{
|
||||||
|
var myCurve = new CubicBezierCurve2D(
|
||||||
|
new Vector2(-4, -4),
|
||||||
|
new Vector2(-2, 4),
|
||||||
|
new Vector2(2, -4),
|
||||||
|
new Vector2(4, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
var otherCurve = new CubicBezierCurve2D(
|
||||||
|
new Vector2(-4, -4),
|
||||||
|
new Vector2(-2, 4),
|
||||||
|
new Vector2(2, -4),
|
||||||
|
new Vector2(4, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
(myCurve == otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NotEquals()
|
||||||
|
{
|
||||||
|
var myCurve = new CubicBezierCurve2D(
|
||||||
|
new Vector2(-9, -4),
|
||||||
|
new Vector2(-2, 4),
|
||||||
|
new Vector2(2, -4),
|
||||||
|
new Vector2(4, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
var otherCurve = new CubicBezierCurve2D(
|
||||||
|
new Vector2(-4, -4),
|
||||||
|
new Vector2(-2, 4),
|
||||||
|
new Vector2(2, -4),
|
||||||
|
new Vector2(4, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
(myCurve != otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -91,11 +91,11 @@ namespace Tests
|
||||||
new Vector3(4, 4, 0)
|
new Vector3(4, 4, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
myCurve.Point(0f).Should().BeEquivalentTo(myCurve.p0);
|
myCurve.Point(0f).Should().BeEquivalentTo(myCurve.P0);
|
||||||
myCurve.Point(0.5f).Should().BeEquivalentTo(new Vector3(0, 0, 0.75f));
|
myCurve.Point(0.5f).Should().BeEquivalentTo(new Vector3(0, 0, 0.75f));
|
||||||
myCurve.Point(0.25f).Should().BeEquivalentTo(new Vector3(-2.1875f, -0.5f, -0.84375f));
|
myCurve.Point(0.25f).Should().BeEquivalentTo(new Vector3(-2.1875f, -0.5f, -0.84375f));
|
||||||
myCurve.Point(0.75f).Should().BeEquivalentTo(new Vector3(2.1875f, 0.5f, 1.21875f));
|
myCurve.Point(0.75f).Should().BeEquivalentTo(new Vector3(2.1875f, 0.5f, 1.21875f));
|
||||||
myCurve.Point(1f).Should().BeEquivalentTo(myCurve.p3);
|
myCurve.Point(1f).Should().BeEquivalentTo(myCurve.P3);
|
||||||
|
|
||||||
myCurve.Invoking(x => x.Point(1.5f)).Should().Throw<ArgumentException>();
|
myCurve.Invoking(x => x.Point(1.5f)).Should().Throw<ArgumentException>();
|
||||||
}
|
}
|
||||||
|
@ -110,11 +110,11 @@ namespace Tests
|
||||||
new Vector3(4, 4, 0)
|
new Vector3(4, 4, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
myCurve.Point(15, 15, 17).Should().BeEquivalentTo(myCurve.p0);
|
myCurve.Point(15, 15, 17).Should().BeEquivalentTo(myCurve.P0);
|
||||||
myCurve.Point(3, 2, 4).Should().BeEquivalentTo(new Vector3(0, 0, 0.75f));
|
myCurve.Point(3, 2, 4).Should().BeEquivalentTo(new Vector3(0, 0, 0.75f));
|
||||||
myCurve.Point(2, 1, 5).Should().BeEquivalentTo(new Vector3(-2.1875f, -0.5f, -0.84375f));
|
myCurve.Point(2, 1, 5).Should().BeEquivalentTo(new Vector3(-2.1875f, -0.5f, -0.84375f));
|
||||||
myCurve.Point(11, 2, 14).Should().BeEquivalentTo(new Vector3(2.1875f, 0.5f, 1.21875f));
|
myCurve.Point(11, 2, 14).Should().BeEquivalentTo(new Vector3(2.1875f, 0.5f, 1.21875f));
|
||||||
myCurve.Point(1, -8, 1).Should().BeEquivalentTo(myCurve.p3);
|
myCurve.Point(1, -8, 1).Should().BeEquivalentTo(myCurve.P3);
|
||||||
|
|
||||||
myCurve.Invoking(x => x.Point(15, 2, 5)).Should().Throw<ArgumentException>();
|
myCurve.Invoking(x => x.Point(15, 2, 5)).Should().Throw<ArgumentException>();
|
||||||
}
|
}
|
||||||
|
@ -152,5 +152,45 @@ namespace Tests
|
||||||
|
|
||||||
myCurve.Invoking(x => x.Velocity(15, 2, 5)).Should().Throw<ArgumentException>();
|
myCurve.Invoking(x => x.Velocity(15, 2, 5)).Should().Throw<ArgumentException>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Equals()
|
||||||
|
{
|
||||||
|
var myCurve = new CubicBezierCurve3D(
|
||||||
|
new Vector3(-4, -4, -3),
|
||||||
|
new Vector3(-2, 4, 0),
|
||||||
|
new Vector3(2, -4, 3),
|
||||||
|
new Vector3(4, 4, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
var otherCurve = new CubicBezierCurve3D(
|
||||||
|
new Vector3(-4, -4, -3),
|
||||||
|
new Vector3(-2, 4, 0),
|
||||||
|
new Vector3(2, -4, 3),
|
||||||
|
new Vector3(4, 4, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
(myCurve == otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NotEquals()
|
||||||
|
{
|
||||||
|
var myCurve = new CubicBezierCurve3D(
|
||||||
|
new Vector3(-1, -4, -3),
|
||||||
|
new Vector3(-2, 4, 0),
|
||||||
|
new Vector3(2, -4, 3),
|
||||||
|
new Vector3(4, 4, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
var otherCurve = new CubicBezierCurve3D(
|
||||||
|
new Vector3(-4, -4, -3),
|
||||||
|
new Vector3(-2, 4, 0),
|
||||||
|
new Vector3(2, -4, 3),
|
||||||
|
new Vector3(4, 4, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
(myCurve != otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -151,5 +151,33 @@ namespace Tests
|
||||||
myCurve.Point(0.75f).Should().BeEquivalentTo(myCubicCurve.Point(0.75f));
|
myCurve.Point(0.75f).Should().BeEquivalentTo(myCubicCurve.Point(0.75f));
|
||||||
myCurve.Point(1f).Should().BeEquivalentTo(myCubicCurve.Point(1f));
|
myCurve.Point(1f).Should().BeEquivalentTo(myCubicCurve.Point(1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Equals()
|
||||||
|
{
|
||||||
|
var p0 = new Vector2(-4, -4);
|
||||||
|
var p1 = new Vector2(2, -4);
|
||||||
|
var p2 = new Vector2(4, 4);
|
||||||
|
|
||||||
|
var myCurve = new QuadraticBezierCurve2D(p0, p1, p2);
|
||||||
|
|
||||||
|
var otherCurve = new QuadraticBezierCurve2D(p0, p1, p2);
|
||||||
|
|
||||||
|
(myCurve == otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NotEquals()
|
||||||
|
{
|
||||||
|
var p0 = new Vector2(-4, -4);
|
||||||
|
var p1 = new Vector2(2, -4);
|
||||||
|
var p2 = new Vector2(4, 4);
|
||||||
|
|
||||||
|
var myCurve = new QuadraticBezierCurve2D(p0, p1, p2);
|
||||||
|
|
||||||
|
var otherCurve = new QuadraticBezierCurve2D(new Vector2(0, 1), p1, p2);
|
||||||
|
|
||||||
|
(myCurve != otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -151,5 +151,31 @@ namespace Tests
|
||||||
myCurve.Point(0.75f).Should().BeEquivalentTo(myCubicCurve.Point(0.75f));
|
myCurve.Point(0.75f).Should().BeEquivalentTo(myCubicCurve.Point(0.75f));
|
||||||
myCurve.Point(1f).Should().BeEquivalentTo(myCubicCurve.Point(1f));
|
myCurve.Point(1f).Should().BeEquivalentTo(myCubicCurve.Point(1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Equals()
|
||||||
|
{
|
||||||
|
var p0 = new Vector3(-4, -4, -3);
|
||||||
|
var p1 = new Vector3(2, -4, 3);
|
||||||
|
var p2 = new Vector3(4, 4, 0);
|
||||||
|
|
||||||
|
var myCurve = new QuadraticBezierCurve3D(p0, p1, p2);
|
||||||
|
var otherCurve = new QuadraticBezierCurve3D(p0, p1, p2);
|
||||||
|
|
||||||
|
(myCurve == otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void NotEquals()
|
||||||
|
{
|
||||||
|
var p0 = new Vector3(-4, -4, -3);
|
||||||
|
var p1 = new Vector3(2, -4, 3);
|
||||||
|
var p2 = new Vector3(4, 4, 0);
|
||||||
|
|
||||||
|
var myCurve = new QuadraticBezierCurve3D(p0, p1, p2);
|
||||||
|
var otherCurve = new QuadraticBezierCurve3D(new Vector3(0, -4, -3), p1, p2);
|
||||||
|
|
||||||
|
(myCurve != otherCurve).Should().BeTrue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue