Skip to content

Commit

Permalink
Merge pull request #364 from GSharker/dev/peli/Segment-At-Length
Browse files Browse the repository at this point in the history
Dev/peli/segment at length
  • Loading branch information
cesarecaoduro authored Sep 27, 2021
2 parents 453a332 + 684073e commit f4fff12
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 21 deletions.
22 changes: 18 additions & 4 deletions src/GShark.Test.XUnit/Geometry/PolyCurveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ public PolyCurveTests(ITestOutputHelper testOutput)
Line line = new Line(new Point3(5, 5, 0), new Point3(5, 5, -2.5));
Arc arc = Arc.ByStartEndDirection(new Point3(5, 5, -2.5), new Point3(10, 5, -5), new Vector3(0, 0, -1));

_polycurve = new PolyCurve();
_polycurve.Append(curve);
_polycurve.Append(line);
_polycurve.Append(arc);
List<NurbsBase> curves = new List<NurbsBase>{ curve, line, arc};
_polycurve = new PolyCurve(curves);
#endregion
}

Expand Down Expand Up @@ -81,5 +79,21 @@ public void It_Returns_The_Length_At_Parameter(double t, double expectedLength)
// Assert
length.Should().BeApproximately(expectedLength, GSharkMath.MinTolerance);
}

[Theory]
[InlineData(23.769824635278, 2)]
[InlineData(21.269824635278, 1)]
[InlineData(20, 0)]
public void It_Returns_The_Segment_At_Length(double length, int segmentIndex)
{
//Arrange
NurbsBase expectedSegment = _polycurve.Segments[segmentIndex];

//Act
NurbsBase segmentResult = _polycurve.SegmentAtLength(length);

//Assert
segmentResult.Should().BeSameAs(expectedSegment);
}
}
}
3 changes: 1 addition & 2 deletions src/GShark/Geometry/NurbsBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,7 @@ public static PolyCurve Join(IList<NurbsBase> curves)
}
}

PolyCurve polyCurve = new PolyCurve();
polyCurve.Append(sortedCurves);
PolyCurve polyCurve = new PolyCurve(sortedCurves);

return polyCurve;
}
Expand Down
64 changes: 49 additions & 15 deletions src/GShark/Geometry/PolyCurve.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using GShark.Core;
using GShark.ExtendedMethods;
using GShark.Interfaces;
using GShark.Operation;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -19,10 +17,19 @@ public class PolyCurve : NurbsBase
private readonly List<NurbsBase> _segments = new List<NurbsBase>();

/// <summary>
/// Initializes a new empty polyCurve.
/// Initializes a new polyCurve with a list of curves
/// </summary>
public PolyCurve()
{ }
/// <param name="curves">a list of curves</param>
public PolyCurve(IList<NurbsBase> curves)
{
_segments.Add(curves[0]);
for (int i = 1; i < curves.Count; i++)
{
HealthChecks(curves[i - 1], curves[i]);
_segments.Add(curves[i]);
}
ToNurbsForm();
}

/// <summary>
/// Appends and matches the start of the arc to the end of polycurve.
Expand All @@ -31,7 +38,7 @@ public PolyCurve()
/// <param name="line">The line to append.</param>
public void Append(Line line)
{
HealthChecks(line);
HealthChecks(this, line);
_segments.Add(line);
ToNurbsForm();
}
Expand All @@ -43,7 +50,7 @@ public void Append(Line line)
/// <param name="arc">The arc to append.</param>
public void Append(Arc arc)
{
HealthChecks(arc);
HealthChecks(this, arc);
_segments.Add(arc);
ToNurbsForm();
}
Expand All @@ -59,7 +66,7 @@ public void Append(NurbsCurve curve)
{
throw new InvalidOperationException("The curve is closed.");
}
HealthChecks(curve);
HealthChecks(this, curve);
_segments.Add(curve);
ToNurbsForm();
}
Expand All @@ -75,7 +82,7 @@ public void Append(PolyCurve polyCurve)
{
throw new InvalidOperationException("The polycurve is closed.");
}
HealthChecks(polyCurve);
HealthChecks(this, polyCurve);
_segments.Add(polyCurve);
ToNurbsForm();
}
Expand All @@ -85,7 +92,7 @@ public void Append(PolyCurve polyCurve)
/// No health checks are made, you are responsible of the collection of curve you are passing.
/// </summary>
/// <param name="curves"></param>
internal void Append(List<NurbsBase> curves)
internal void Append(IEnumerable<NurbsBase> curves)
{
_segments.AddRange(curves);
ToNurbsForm();
Expand All @@ -96,6 +103,33 @@ internal void Append(List<NurbsBase> curves)
/// </summary>
public List<NurbsBase> Segments => _segments;

/// <summary>
/// Find Curve Segment At a given Length.
/// When there is no curve segments in the PolyCurve, return null;
/// If the provided length is greater than the PolyCurve Length, then it return the last segment in PolyCurve;
/// </summary>
/// <param name="length">Segment Length</param>
public NurbsBase SegmentAtLength(double length)
{
NurbsBase segment = null;
if (length > Length) return _segments.Last();
if (_segments.Count == 1) return _segments.First();

double temp = 0;
foreach (NurbsBase curve in _segments)
{
double cumulativeLength = curve.Length + temp;
if (length >= temp && length < cumulativeLength)
{
segment = curve;
break;
}
temp = cumulativeLength;
}

return segment;
}

/// <summary>
/// Defines the NURBS form of the polyline.
/// </summary>
Expand Down Expand Up @@ -141,18 +175,18 @@ private void ToNurbsForm()
}

/// <summary>
/// Checks to define if the curve can be appended to the polycurve.
/// Checks to define if the curve can be appended.
/// </summary>
private void HealthChecks(NurbsBase curve)
private void HealthChecks(NurbsBase curve, NurbsBase curveToAppend)
{
if (_segments.Count <= 0) return;

if (IsClosed)
if (curve.IsClosed)
{
throw new InvalidOperationException($"The polyCurve is closed can not be possible to connect the {curve.GetType()}.");
throw new InvalidOperationException($"The polyCurve is closed can not be possible to connect the {curveToAppend.GetType()}.");
}

if (EndPoint.DistanceTo(curve.StartPoint) > GSharkMath.Epsilon)
if (curve.EndPoint.DistanceTo(curveToAppend.StartPoint) > GSharkMath.Epsilon)
{
throw new InvalidOperationException("The two curves can not be connected.");
}
Expand Down

0 comments on commit f4fff12

Please sign in to comment.