Skip to content

Commit

Permalink
Merge pull request #360 from GSharker/dev/mibi/circle-inheritance-nur…
Browse files Browse the repository at this point in the history
…bsbase

``Circle`` inheritance ``NurbsBase``
  • Loading branch information
sonomirco committed Sep 11, 2021
2 parents 746d9fa + 22b116d commit 415a381
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 108 deletions.
4 changes: 2 additions & 2 deletions src/GShark.Test.XUnit/Geometry/ArcTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void It_Is_A_Curve_Representation_Of_The_Arc_From_0_To_90_Deg()
};

// Act
NurbsBase arc = new Arc(Plane.PlaneYZ, 20, new Interval(0.0, 1.8)).ToNurbs();
NurbsBase arc = new Arc(Plane.PlaneYZ, 20, new Interval(0.0, 1.8));

// Assert
arc.ControlPointLocations.Count.Should().Be(5);
Expand Down Expand Up @@ -162,7 +162,7 @@ public void It_Is_A_Curve_Representation_Of_ExampleArc3D()
};

// Act
NurbsBase arc = _exampleArc3D.ToNurbs();
NurbsBase arc = _exampleArc3D;

// Assert
arc.ControlPointLocations.Count.Should().Be(7);
Expand Down
2 changes: 1 addition & 1 deletion src/GShark.Test.XUnit/Geometry/CircleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void It_Returns_A_Circle3D_With_Its_Nurbs_Representation()
};

// Act
NurbsBase circleNurbs = _circle3D.ToNurbs();
NurbsBase circleNurbs = _circle3D;

// Assert
circleNurbs.Knots.GetDomain(circleNurbs.Degree).Length.Should().Be(1.0);
Expand Down
4 changes: 2 additions & 2 deletions src/GShark.Test.XUnit/Geometry/NurbsCurveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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, arc.ToNurbs(), curve };
NurbsBase[] curves = { ln, arc, curve };

Point3 expectedPt1 = new Point3(5, 3.042501, 4.519036);
Point3 expectedPt2 = new Point3(5, 5, -1.230175);
Expand Down Expand Up @@ -407,7 +407,7 @@ public void Returns_A_Curve_Joining_Polylines_And_Arc()
});

Arc arc = Arc.ByStartEndDirection(new Point3(5, 5, -2.5), new Point3(10, 5, -5), new Vector3(0, 0, -1));
NurbsBase[] curves = { poly, arc.ToNurbs() };
NurbsBase[] curves = { poly, arc };

Point3 expectedPt1 = new Point3(5, 0, 2.928932);
Point3 expectedPt2 = new Point3(5, 4.428932, 5);
Expand Down
2 changes: 2 additions & 0 deletions src/GShark/Geometry/Arc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public Arc(Plane plane, double radius, Interval angleDomainRadians) : base(plane
AngularDiff(angleDomainRadians.T1, Math.PI * 2.0))
: angleDomainRadians;
_length = Math.Abs(Angle * Radius);
ToNurbs();
}

/// <summary>
Expand Down Expand Up @@ -64,6 +65,7 @@ public Arc(Point3 pt1, Point3 pt2, Point3 pt3) : base(pt1, pt2, pt3)

_domain = new Interval(0.0, angle);
_length = Math.Abs(Angle * Radius);
ToNurbs();
}

/// <summary>
Expand Down
55 changes: 39 additions & 16 deletions src/GShark/Geometry/Circle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using GShark.Interfaces;
using GShark.Intersection;
using System;
using System.ComponentModel;
using System.Linq;

namespace GShark.Geometry
Expand All @@ -13,7 +14,7 @@ namespace GShark.Geometry
/// <example>
/// [!code-csharp[Example](../../src/GShark.Test.XUnit/Geometry/CircleTests.cs?name=example)]
/// </example>
public class Circle : ICurve, IEquatable<Circle>, ITransformable<Circle>
public class Circle : NurbsBase, IEquatable<Circle>, ITransformable<Circle>
{
internal Interval _domain = new Interval(0.0, 2.0 * Math.PI);
internal double _length;
Expand All @@ -28,6 +29,7 @@ public Circle(Plane plane, double radius)
Plane = plane;
Radius = Math.Abs(radius);
_length = Math.Abs(2.0 * Math.PI * radius);
ToNurbs();
}

/// <summary>
Expand Down Expand Up @@ -69,6 +71,7 @@ public Circle(Point3 pt1, Point3 pt2, Point3 pt3)
Plane = new Plane(center, xDir, yDir);
Radius = xDir.Length;
_length = Math.Abs(2.0 * Math.PI * Radius);
ToNurbs();
}

/// <summary>
Expand All @@ -94,27 +97,27 @@ public Circle(Point3 pt1, Point3 pt2, Point3 pt3)
/// <summary>
/// Gets the circumference of the circular curve.
/// </summary>
public double Length => _length;
public override double Length => _length;

/// <summary>
/// Gets the start point of the circular curve.
/// </summary>
public Point3 StartPoint => PointAt(0.0);
public override Point3 StartPoint => PointAt(0.0);

/// <summary>
/// Gets the mid-point of the circular curve.
/// </summary>
public Point3 MidPoint => PointAt(_domain.Mid);
public override Point3 MidPoint => PointAt(_domain.Mid);

/// <summary>
/// Gets the end point of the circular curve.
/// </summary>
public Point3 EndPoint => PointAt(_domain.T1);
public override Point3 EndPoint => PointAt(_domain.T1);

/// <summary>
/// Gets the bounding box of this circular curve.
/// </summary>
public virtual BoundingBox GetBoundingBox()
public override BoundingBox GetBoundingBox()
{
double val1 = Radius * SelectionLength(Plane.ZAxis[1], Plane.ZAxis[2]);
double val2 = Radius * SelectionLength(Plane.ZAxis[2], Plane.ZAxis[0]);
Expand All @@ -138,7 +141,7 @@ public virtual BoundingBox GetBoundingBox()
/// <param name="t">Parameter to evaluate derivative. A parameter between 0.0 and angle domain in radians.</param>
/// <param name="derivative">Which order of derivative is wanted. Valid values are 0,1,2,3.</param>
/// <returns>The derivative of the circle at the given parameter.</returns>
public Vector3 DerivativeAt(double t, int derivative = 0)
public new Vector3 DerivativeAt(double t, int derivative = 0)
{
if (t < 0.0)
{
Expand Down Expand Up @@ -180,7 +183,7 @@ public Vector3 DerivativeAt(double t, int derivative = 0)
/// </summary>
/// <param name="t">A parameter between 0.0 and angle domain in radians.></param>
/// <returns>Point on the circular curve.</returns>
public Point3 PointAt(double t)
public override Point3 PointAt(double t)
{
if (t < 0.0)
{
Expand All @@ -200,7 +203,7 @@ public Point3 PointAt(double t)
/// </summary>
/// <param name="length">The length where to evaluate the point.</param>
/// <returns>The point at the length.</returns>
public Point3 PointAtLength(double length)
public override Point3 PointAtLength(double length)
{
if (length <= 0.0)
{
Expand All @@ -225,7 +228,7 @@ public Point3 PointAtLength(double length)
/// </summary>
/// <param name="normalizedLength">The length factor is normalized between 0.0 and 1.0.</param>
/// <returns>The point at the length.</returns>
public Point3 PointAtNormalizedLength(double normalizedLength)
public override Point3 PointAtNormalizedLength(double normalizedLength)
{
double theta = _domain.T0 + (_domain.T1 - _domain.T0) * normalizedLength;
return PointAt(theta);
Expand All @@ -236,7 +239,7 @@ public Point3 PointAtNormalizedLength(double normalizedLength)
/// </summary>
/// <param name="t">A parameter between 0.0 and angle domain in radians.</param>
/// <returns>Unitized tangent vector at the parameter.</returns>
public Vector3 TangentAt(double t)
public override Vector3 TangentAt(double t)
{
if (t <= 0.0)
{
Expand Down Expand Up @@ -270,7 +273,7 @@ public Vector3 TangentAtLength(double length)
/// </summary>
/// <param name="t">A parameter between 0.0 and angle domain in radians.</param>
/// <returns>The curve length at t.</returns>
public double LengthAt(double t)
public override double LengthAt(double t)
{
if (t <= 0)
{
Expand All @@ -290,7 +293,7 @@ public double LengthAt(double t)
/// </summary>
/// <param name="pt">The test point to project onto the circular curve.</param>
/// <returns>The point on the circular curve that is close to the test point.</returns>
public Point3 ClosestPoint(Point3 pt)
public override Point3 ClosestPoint(Point3 pt)
{
(double u, double v) = Plane.ClosestParameters(pt);
if (Math.Abs(u) < GSharkMath.MinTolerance && Math.Abs(v) < GSharkMath.MinTolerance)
Expand All @@ -308,7 +311,7 @@ public Point3 ClosestPoint(Point3 pt)
/// </summary>
/// <param name="pt">The test point to project onto the circular curve.</param>
/// <returns>The parameter on the circular curve that is close to the test point.</returns>
public double ClosestParameter(Point3 pt)
public override double ClosestParameter(Point3 pt)
{
(double u, double v) = Plane.ClosestParameters(pt);
if (Math.Abs(u) < GSharkMath.MinTolerance && Math.Abs(v) < GSharkMath.MinTolerance)
Expand Down Expand Up @@ -339,35 +342,45 @@ public Circle Offset(double distance)
/// <em>Implementation of Algorithm A7.1 from The NURBS Book by Piegl and Tiller.</em>
/// </summary>
/// <returns>A nurbs curve shaped like this arc.</returns>
public NurbsCurve ToNurbs()
internal void ToNurbs()
{
Vector3 axisX = Plane.XAxis;
Vector3 axisY = Plane.YAxis;
double curveAngle = _domain.Length;
int numberOfArc;
Point3[] pts;
Point4[] ctrPts;
double[] weights;

// Number of arcs.
double piNum = 0.5 * Math.PI;
if ((curveAngle - piNum) <= GSharkMath.Epsilon)
{
numberOfArc = 1;
pts = new Point3[3];
ctrPts = new Point4[3];
weights = new double[3];
}
else if ((curveAngle - piNum * 2) <= GSharkMath.Epsilon)
{
numberOfArc = 2;
pts = new Point3[5];
ctrPts = new Point4[5];
weights = new double[5];
}
else if ((curveAngle - piNum * 3) <= GSharkMath.Epsilon)
{
numberOfArc = 3;
pts = new Point3[7];
ctrPts = new Point4[7];
weights = new double[7];
}
else
{
numberOfArc = 4;
pts = new Point3[9];
ctrPts = new Point4[9];
weights = new double[9];
}

double detTheta = curveAngle / numberOfArc;
Expand All @@ -379,14 +392,18 @@ public NurbsCurve ToNurbs()
int index = 0;
double angle = _domain.T0;

pts[0] = p0;
ctrPts[0] = new Point4(p0);
weights[0] = weight;

for (int i = 1; i < numberOfArc + 1; i++)
{
angle += detTheta;
Point3 p2 = Center + (axisX * (Radius * Math.Cos(angle)) + axisY * (Radius * Math.Sin(angle)));

ctrPts[index + 2] = new Point4(p2);
pts[index + 2] = p2;
weights[index + 2] = 1.0;

Vector3 t2 = (axisY * Math.Cos(angle)) - (axisX * Math.Sin(angle));
Line ln0 = new Line(p0, t0.Unitize() + p0);
Expand All @@ -395,6 +412,8 @@ public NurbsCurve ToNurbs()
Point3 p1 = p0 + (t0 * u0);

ctrPts[index + 1] = new Point4(p1, weight);
pts[index + 1] = p1;
weights[index + 1] = weight;
index += 2;

if (i >= numberOfArc)
Expand Down Expand Up @@ -429,7 +448,11 @@ public NurbsCurve ToNurbs()
break;
}

return new NurbsCurve(2, knots, ctrPts.ToList());
Weights = weights.ToList();
Degree = 2;
Knots = knots;
ControlPoints = ctrPts.ToList();
ControlPointLocations = pts.ToList();
}

/// <summary>
Expand Down
5 changes: 2 additions & 3 deletions src/GShark/Geometry/NurbsBase.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#nullable enable
using GShark.Core;
using GShark.ExtendedMethods;
using GShark.Interfaces;
using GShark.Operation.Utilities;
using System;
using System.Collections.Generic;
Expand All @@ -14,7 +13,7 @@ namespace GShark.Geometry
/// <summary>
/// This class represents a base class that is common to most curve types.
/// </summary>
public abstract class NurbsBase : ICurve, IEquatable<NurbsBase>
public abstract class NurbsBase : IEquatable<NurbsBase>
{
protected NurbsBase()
{
Expand Down Expand Up @@ -215,7 +214,7 @@ public virtual Point3 PointAtNormalizedLength(double normalizedLength)
/// </summary>
/// <param name="t">The parameter to sample the curve. Parameter should be between 0.0 and 1.0.</param>
/// <returns>The unitized tangent vector at the given parameter.</returns>
public Vector3 TangentAt(double t)
public virtual Vector3 TangentAt(double t)
{
if (t <= 0.0)
{
Expand Down
Loading

0 comments on commit 415a381

Please sign in to comment.