From 5de158664549d48884c8e3ddc2650a7ebf1eae33 Mon Sep 17 00:00:00 2001 From: Mirco Bianchini Date: Sat, 11 Sep 2021 10:57:58 +1000 Subject: [PATCH] Line inheritance NurbsBase. --- .../Data/NurbsSurfaceCollection.cs | 2 +- src/GShark.Test.XUnit/Geometry/LineTests.cs | 17 +++---- .../Geometry/NurbsCurveTests.cs | 4 +- src/GShark.Test.XUnit/Sampling/CurveTests.cs | 2 +- src/GShark/Geometry/Line.cs | 48 +++++++++++-------- src/GShark/Geometry/NurbsBase.cs | 37 +++++++++----- src/GShark/Geometry/NurbsCurve.cs | 13 +---- src/GShark/Geometry/PolyCurve.cs | 2 +- src/GShark/Intersection/Intersect.cs | 2 +- 9 files changed, 65 insertions(+), 62 deletions(-) diff --git a/src/GShark.Test.XUnit/Data/NurbsSurfaceCollection.cs b/src/GShark.Test.XUnit/Data/NurbsSurfaceCollection.cs index d2e7c19b..220789ec 100644 --- a/src/GShark.Test.XUnit/Data/NurbsSurfaceCollection.cs +++ b/src/GShark.Test.XUnit/Data/NurbsSurfaceCollection.cs @@ -85,7 +85,7 @@ public static NurbsSurface Loft() PolyLine poly = new PolyLine(pts1); NurbsCurve crv1 = new NurbsCurve(pts2, 2); NurbsCurve crv2 = new NurbsCurve(pts3, 3); - List crvs = new List { ln.ToNurbs(), crv0, poly.ToNurbs(), crv1, crv2 }; + List crvs = new List { ln, crv0, poly.ToNurbs(), crv1, crv2 }; return NurbsSurface.CreateLoftedSurface(crvs); } diff --git a/src/GShark.Test.XUnit/Geometry/LineTests.cs b/src/GShark.Test.XUnit/Geometry/LineTests.cs index f711ceaf..f49d8581 100644 --- a/src/GShark.Test.XUnit/Geometry/LineTests.cs +++ b/src/GShark.Test.XUnit/Geometry/LineTests.cs @@ -227,7 +227,7 @@ public void It_Returns_The_Parameter_On_The_Line_Closest_To_The_Point(double exp public void It_Returns_A_Flipped_Line() { // Act - Line flippedLine = _exampleLine.Flip(); + Line flippedLine = _exampleLine.Reverse(); // Assert flippedLine.StartPoint.Equals(_exampleLine.EndPoint).Should().BeTrue(); @@ -263,8 +263,8 @@ public void Returns_The_Offset_Of_A_Line() public void It_Checks_If_Two_Lines_Are_Equals() { // Act - Line lineFlip = _exampleLine.Flip(); - Line lineFlippedBack = lineFlip.Flip(); + Line lineFlip = _exampleLine.Reverse(); + Line lineFlippedBack = lineFlip.Reverse(); // Assert lineFlip.Equals(lineFlippedBack).Should().BeFalse(); @@ -286,18 +286,15 @@ public void It_Translates_A_Line() } [Fact] - public void It_Returns_A_NurbsBase_Form_Of_A_Line() + public void It_Returns_True_If_The_NurbsBase_Form_Of_A_Line_Is_Correct() { - // Arrange - var line = _exampleLine; - //Act - var nurbsLine = line.ToNurbs(); + NurbsBase nurbsLine = _exampleLine; // Assert nurbsLine.ControlPointLocations.Count.Should().Be(2); - nurbsLine.ControlPointLocations[0].Equals(line.StartPoint).Should().BeTrue(); - nurbsLine.ControlPointLocations[1].Equals(line.EndPoint).Should().BeTrue(); + nurbsLine.ControlPointLocations[0].Equals(_exampleLine.StartPoint).Should().BeTrue(); + nurbsLine.ControlPointLocations[1].Equals(_exampleLine.EndPoint).Should().BeTrue(); nurbsLine.Degree.Should().Be(1); } } diff --git a/src/GShark.Test.XUnit/Geometry/NurbsCurveTests.cs b/src/GShark.Test.XUnit/Geometry/NurbsCurveTests.cs index 48832de8..8062bf76 100644 --- a/src/GShark.Test.XUnit/Geometry/NurbsCurveTests.cs +++ b/src/GShark.Test.XUnit/Geometry/NurbsCurveTests.cs @@ -332,7 +332,7 @@ public void Returns_A_Curve_Joining_Different_Types_Of_Curves() NurbsCurve curve = new NurbsCurve(pts, degree); Line ln = 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)); - NurbsBase[] curves = { ln.ToNurbs(), arc.ToNurbs(), curve }; + NurbsBase[] curves = { ln, arc.ToNurbs(), curve }; Point3 expectedPt1 = new Point3(5, 3.042501, 4.519036); Point3 expectedPt2 = new Point3(5, 5, -1.230175); @@ -377,7 +377,7 @@ public void Returns_A_Curve_Joining_Polylines_And_Lines() double expectedLength = 43.932474; // Act - NurbsBase joinedCurve = NurbsBase.Join(new List { poly.ToNurbs(), ln0.ToNurbs(), ln1.ToNurbs() }); + NurbsBase joinedCurve = NurbsBase.Join(new List { poly.ToNurbs(), ln0, ln1 }); Point3 pt1 = joinedCurve.PointAtLength(15); Point3 pt2 = joinedCurve.PointAtLength(21.5); Point3 pt3 = joinedCurve.PointAtLength(27.5); diff --git a/src/GShark.Test.XUnit/Sampling/CurveTests.cs b/src/GShark.Test.XUnit/Sampling/CurveTests.cs index 8140a125..187a723c 100644 --- a/src/GShark.Test.XUnit/Sampling/CurveTests.cs +++ b/src/GShark.Test.XUnit/Sampling/CurveTests.cs @@ -350,7 +350,7 @@ public void Return_Adaptive_Sample_Subdivision_Of_A_Line() // Act - var (tValues, pts) = Curve.AdaptiveSample(ln.ToNurbs()); + var (tValues, pts) = Curve.AdaptiveSample(ln); // Arrange pts.Count.Should().Be(tValues.Count).And.Be(2); diff --git a/src/GShark/Geometry/Line.cs b/src/GShark/Geometry/Line.cs index 4e0f29bf..0936b451 100644 --- a/src/GShark/Geometry/Line.cs +++ b/src/GShark/Geometry/Line.cs @@ -11,7 +11,7 @@ namespace GShark.Geometry /// /// [!code-csharp[Example](../../src/GShark.Test.XUnit/Geometry/LineTests.cs?name=example)] /// - public class Line : ICurve, IEquatable, ITransformable + public class Line : NurbsBase, IEquatable, ITransformable { /// /// Initializes a line by start point and end point. @@ -29,6 +29,7 @@ public Line(Point3 startPoint, Point3 endPoint) EndPoint = endPoint; Length = StartPoint.DistanceTo(EndPoint); Direction = (EndPoint - StartPoint).Unitize(); + ToNurbs(); } /// @@ -48,27 +49,28 @@ public Line(Point3 startPoint, Vector3 direction, double length) EndPoint = startPoint + direction.Amplify(length); Length = Math.Abs(length); Direction = (EndPoint - StartPoint).Unitize(); + ToNurbs(); } /// /// Gets the start point of the line. /// - public Point3 StartPoint { get; } + public override Point3 StartPoint { get; } /// /// Gets the middle point of the line. /// - public Point3 MidPoint => StartPoint + (EndPoint - StartPoint) / 2; + public override Point3 MidPoint => StartPoint + (EndPoint - StartPoint) / 2; /// /// Gets the end point of the line. /// - public Point3 EndPoint { get; } + public override Point3 EndPoint { get; } /// /// Length of the line. /// - public double Length { get; } + public override double Length { get; } /// /// Unit vector representing direction of the line. @@ -78,7 +80,7 @@ public Line(Point3 startPoint, Vector3 direction, double length) /// /// Gets the bounding box in ascending fashion. /// - public BoundingBox GetBoundingBox() + public override BoundingBox GetBoundingBox() { BoundingBox bBox = new BoundingBox(StartPoint, EndPoint); BoundingBox validBBox = bBox.MakeItValid(); @@ -88,12 +90,12 @@ public BoundingBox GetBoundingBox() /// /// Gets the closest point on the line to the test point. /// - /// The closest point to find. + /// The closest point to find. /// The point on the line closest to the test point. - public Point3 ClosestPoint(Point3 pt) + public override Point3 ClosestPoint(Point3 point) { Vector3 dir = Direction; - Vector3 v = pt - StartPoint; + Vector3 v = point - StartPoint; double d = Vector3.DotProduct(v, dir); d = Math.Min(Length, d); @@ -105,16 +107,16 @@ public Point3 ClosestPoint(Point3 pt) /// /// Computes the parameter on the line that is closest to a test point. /// - /// The test point. + /// The test point. /// The parameter on the line closest to the test point. - public double ClosestParameter(Point3 pt) + public override double ClosestParameter(Point3 point) { Vector3 dir = EndPoint - StartPoint; double dirLength = dir.SquareLength; if (!(dirLength > 0.0)) return 0.0; - Vector3 ptToStart = pt - StartPoint; - Vector3 ptToEnd = pt - EndPoint; + Vector3 ptToStart = point - StartPoint; + Vector3 ptToEnd = point - EndPoint; if (ptToStart.SquareLength <= ptToEnd.SquareLength) { @@ -129,7 +131,7 @@ public double ClosestParameter(Point3 pt) /// /// Parameter to evaluate the line. Parameter should be between 0.0 and 1.0. /// The point at the specific parameter. - public Point3 PointAt(double t) + public override Point3 PointAt(double t) { if (t <= 0.0) { @@ -149,7 +151,7 @@ public Point3 PointAt(double t) /// /// Length, between 0.0 and the length of the curve. /// The point at the given length. - public Point3 PointAtLength(double length) + public override Point3 PointAtLength(double length) { if (length <= 0) { @@ -169,7 +171,7 @@ public Point3 PointAtLength(double length) /// /// Parameter, between 0.0 and 1.0. /// The curve length at parameter. - public double LengthAt(double t) + public override double LengthAt(double t) { if (t <= 0) { @@ -188,7 +190,7 @@ public double LengthAt(double t) /// Flip the endpoint of the line. /// /// The line flipped. - public Line Flip() + public new Line Reverse() { return new Line(EndPoint, StartPoint); } @@ -199,7 +201,7 @@ public Line Flip() /// The distance of the offset. If negative the offset will be in the opposite side. /// The plane for the offset operation. /// The offset line. - public Line Offset(double distance, Plane pln) + public new Line Offset(double distance, Plane pln) { if (distance == 0.0) { @@ -238,9 +240,13 @@ public Line Extend(double startLength, double endLength) /// Gets the NURBS form of the curve. /// /// A NURBS curve. - public NurbsBase ToNurbs() + private void ToNurbs() { - return new NurbsCurve(new List { StartPoint, EndPoint }, 1); + Weights = new List {1.0, 1.0}; + Degree = 1; + Knots = new KnotVector{0.0, 0.0, 1.0, 1.0}; + ControlPointLocations = new List { StartPoint, EndPoint }; + ControlPoints = new List { StartPoint, EndPoint }; } /// @@ -248,7 +254,7 @@ public NurbsBase ToNurbs() /// /// Transformation matrix to apply. /// A line transformed. - public Line Transform(Transform transform) + public new Line Transform(Transform transform) { Point3 pt1 = StartPoint.Transform(transform); Point3 pt2 = EndPoint.Transform(transform); diff --git a/src/GShark/Geometry/NurbsBase.cs b/src/GShark/Geometry/NurbsBase.cs index 429ec513..ec98949c 100644 --- a/src/GShark/Geometry/NurbsBase.cs +++ b/src/GShark/Geometry/NurbsBase.cs @@ -84,15 +84,15 @@ protected NurbsBase(int degree, KnotVector knots, List controlPoints) /// public KnotVector Knots { get; protected set; } - public double Length => Analyze.Curve.Length(this); + public virtual double Length => Analyze.Curve.Length(this); - public Point3 StartPoint => PointAt(0.0); + public virtual Point3 StartPoint => PointAt(0.0); - public Point3 MidPoint => PointAt(0.5); + public virtual Point3 MidPoint => PointAt(0.5); - public Point3 EndPoint => PointAt(1.0); + public virtual Point3 EndPoint => PointAt(1.0); - public BoundingBox GetBoundingBox() + public virtual BoundingBox GetBoundingBox() { NurbsBase curve = this; @@ -167,7 +167,7 @@ public NurbsBase Close() /// /// /// - public Point3 PointAt(double t) + public virtual Point3 PointAt(double t) { if (t <= 0.0) { @@ -184,7 +184,7 @@ public Point3 PointAt(double t) /// /// /// - public Point3 PointAtLength(double length) + public virtual Point3 PointAtLength(double length) { double parameter = Analyze.Curve.ParameterAtLength(this, length); return Evaluate.Curve.PointAt(this, parameter); @@ -195,7 +195,7 @@ public Point3 PointAtLength(double length) /// /// The length factor is normalized between 0.0 and 1.0. /// The point at the length. - public Point3 PointAtNormalizedLength(double normalizedLength) + public virtual Point3 PointAtNormalizedLength(double normalizedLength) { double length = GSharkMath.RemapValue(normalizedLength, new Interval(0.0, 1.0), new Interval(0.0, Length)); return PointAtLength(length); @@ -307,7 +307,7 @@ public Plane PerpendicularFrameAt(double t) /// Reverses the parametrization of the curve. /// /// A reversed curve. - public NurbsBase Reverse() + public virtual NurbsBase Reverse() { List controlPts = new List(ControlPoints); controlPts.Reverse(); @@ -320,7 +320,7 @@ public NurbsBase Reverse() /// /// /// - public Point3 ClosestPoint(Point3 point) + public virtual Point3 ClosestPoint(Point3 point) { double t = Analyze.Curve.ClosestParameter(this, point); Point3 pointAt = Evaluate.Curve.PointAt(this, t); @@ -330,7 +330,7 @@ public Point3 ClosestPoint(Point3 point) /// /// /// - public double ClosestParameter(Point3 pt) + public virtual double ClosestParameter(Point3 pt) { return Analyze.Curve.ClosestParameter(this, pt); } @@ -358,7 +358,7 @@ public double ParameterAtLength(double segmentLength) /// /// /// - public double LengthAt(double t) + public virtual double LengthAt(double t) { if (t <= 0.0) { @@ -403,7 +403,7 @@ public NurbsBase ClampEnds() /// The distance of the offset. If negative the offset will be in the opposite side. /// The plane for the offset operation. /// The offset curve. - public NurbsBase Offset(double distance, Plane pln) + public virtual NurbsBase Offset(double distance, Plane pln) { if (distance == 0.0) { @@ -493,6 +493,17 @@ public NurbsBase ReduceDegree(double tolerance = 10e-4) return Modify.Curve.ReduceDegree(this, tolerance); } + /// + /// Transforms a curve with the given transformation matrix. + /// + /// The transformation matrix. + /// A new NURBS curve transformed. + public virtual NurbsBase Transform(Transform transformation) + { + List pts = ControlPoints.Select(pt => pt.Transform(transformation)).ToList(); + return new NurbsCurve(Degree, Knots, pts); + } + /// /// Divides a curve for a given number of time, including the end points.
/// The result is not split curves but a collection of t values and lengths that can be used for splitting.
diff --git a/src/GShark/Geometry/NurbsCurve.cs b/src/GShark/Geometry/NurbsCurve.cs index 63a1a35c..1bb4af14 100644 --- a/src/GShark/Geometry/NurbsCurve.cs +++ b/src/GShark/Geometry/NurbsCurve.cs @@ -12,7 +12,7 @@ namespace GShark.Geometry /// /// [!code-csharp[Example](../../src/GShark.Test.XUnit/Data/NurbsBaseCollection.cs?name=example)] /// - public class NurbsCurve : NurbsBase, ITransformable + public class NurbsCurve : NurbsBase { /// /// Internal constructor, creates a NURBS curve. @@ -42,16 +42,5 @@ public NurbsCurve(List? points, List weights, int degree) : this(degree, new KnotVector(degree, points!.Count), points.Select((p, i) => new Point4(p, weights[i])).ToList()) { } - - /// - /// Transforms a curve with the given transformation matrix. - /// - /// The transformation matrix. - /// A new NURBS curve transformed. - public NurbsCurve Transform(Transform transformation) - { - List pts = ControlPoints.Select(pt => pt.Transform(transformation)).ToList(); - return new NurbsCurve(Degree, Knots, pts); - } } } diff --git a/src/GShark/Geometry/PolyCurve.cs b/src/GShark/Geometry/PolyCurve.cs index 8f66efee..27dff33b 100644 --- a/src/GShark/Geometry/PolyCurve.cs +++ b/src/GShark/Geometry/PolyCurve.cs @@ -35,7 +35,7 @@ public void Append(Line line) { HealthChecks(line); _segments.Add(line); - _segmentsNurbs.Add(line.ToNurbs()); + _segmentsNurbs.Add(line); ToNurbsForm(); } diff --git a/src/GShark/Intersection/Intersect.cs b/src/GShark/Intersection/Intersect.cs index 36caed11..0539934b 100644 --- a/src/GShark/Intersection/Intersect.cs +++ b/src/GShark/Intersection/Intersect.cs @@ -310,7 +310,7 @@ public static bool PlaneCircle(Plane pl, Circle cl, out Point3[] pts) /// A collection of . public static List CurveLine(NurbsBase crv, Line ln) { - return CurveCurve(crv, ln.ToNurbs()); + return CurveCurve(crv, ln); } ///