Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Refactor Plane. Add validity check. #195

Merged
merged 1 commit into from
Jul 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/GShark.Test.XUnit/Core/TrigonometryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void It_Returns_True_If_Three_Points_Are_Collinear()
Point3 pt3 = new Point3( 51.299, 37.950, 0.0);

// Assert
Trigonometry.AreThreePointsCollinear(pt1, pt2, pt3, GeoSharkMath.MinTolerance).Should().BeTrue();
Trigonometry.ArePointsCollinear(pt1, pt2, pt3, GeoSharkMath.MinTolerance).Should().BeTrue();
}

[Fact]
Expand All @@ -44,7 +44,7 @@ public void It_Returns_False_If_Three_Points_Are_Not_Collinear()
Point3 pt3 = new Point3( 51.299, 37.950, 0.0);

// Assert
Trigonometry.AreThreePointsCollinear(pt1, pt2, pt3, GeoSharkMath.MinTolerance).Should().BeFalse();
Trigonometry.ArePointsCollinear(pt1, pt2, pt3, GeoSharkMath.MinTolerance).Should().BeFalse();
}

[Theory]
Expand Down
17 changes: 15 additions & 2 deletions src/GShark.Test.XUnit/Geometry/PlaneTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,19 @@ public void It_Initializes_A_Plane()
plane.Origin.Equals(origin).Should().BeTrue();
}

[Fact]
public void It_Checks_If_Plane_Is_Valid()
{
//Arrange
var validPlane = new Plane(new Point3(5, 5, 5), new Vector3(10, 0, 0), new Vector3(0, 5, 0));
var invalidPlane = new Plane(validPlane);
invalidPlane.XAxis = new Vector3(5,5,5);

//Assert
validPlane.IsValid.Should().BeTrue();
invalidPlane.IsValid.Should().BeFalse();
}

[Fact]
public void It_Trows_An_Exception_If_The_Three_Point_Are_Collinear()
{
Expand All @@ -54,7 +67,7 @@ public void It_Trows_An_Exception_If_The_Three_Point_Are_Collinear()
}

[Fact]
public void It_Creates_A_Plane_By_Tree_Points()
public void It_Creates_A_Plane_By_Three_Points()
{
// Arrange
var pt1 = new Point3(20, 20, 0);
Expand Down Expand Up @@ -92,7 +105,7 @@ public void It_Returns_A_Flipped_Plane()
{
// Arrange
var plane = Plane.PlaneXY;
var expectedPlane = new Plane(Plane.PlaneXY.Origin, -plane.XAxis, plane.YAxis);
var expectedPlane = new Plane(Plane.PlaneXY.Origin, plane.YAxis, plane.XAxis);

// Act
Plane flippedPlane = plane.Flip();
Expand Down
2 changes: 1 addition & 1 deletion src/GShark.Test.XUnit/Operation/FittingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void Returns_A_Sets_Of_Interpolated_Beziers_From_A_Collection_Of_Points()
crvs.Count.Should().Be(4);
for (int i = 0; i < crvs.Count - 1; i++)
{
bool areCollinear = Trigonometry.AreThreePointsCollinear(crvs[i].LocationPoints[2], crvs[i].LocationPoints[3],
bool areCollinear = Trigonometry.ArePointsCollinear(crvs[i].LocationPoints[2], crvs[i].LocationPoints[3],
crvs[i + 1].LocationPoints[1]);
areCollinear.Should().BeTrue();
}
Expand Down
2 changes: 1 addition & 1 deletion src/GShark/Core/Trigonometry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public static bool ArePointsCoplanar(IList<Point3> points)
/// <param name="pt3">Third point.</param>
/// <param name="tol">Tolerance ser per default as 1e-6</param>
/// <returns>True if the three points are collinear.</returns>
public static bool AreThreePointsCollinear(Point3 pt1, Point3 pt2, Point3 pt3, double tol = 1e-6)
public static bool ArePointsCollinear(Point3 pt1, Point3 pt2, Point3 pt3, double tol = GeoSharkMath.MaxTolerance)
{
// Find the area of the triangle without using square root and multiply it for 0.5
// http://www.stumblingrobot.com/2016/05/01/use-cross-product-compute-area-triangles-given-vertices/
Expand Down
64 changes: 50 additions & 14 deletions src/GShark/Geometry/Plane.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public class Plane : IEquatable<Plane>, ITransformable<Plane>
/// <param name="direction">The vector representing the normal of the plane.</param>
public Plane(Point3 origin, Vector3 direction)
{
ZAxis = direction.Unitize();
XAxis = Vector3.XAxis.PerpendicularTo(ZAxis).Unitize();
YAxis = Vector3.CrossProduct(ZAxis, XAxis).Unitize();
var normal = direction.Unitize();
XAxis = Vector3.XAxis.PerpendicularTo(normal).Unitize();
YAxis = Vector3.CrossProduct(normal, XAxis).Unitize();
Origin = origin;
}

Expand All @@ -33,7 +33,7 @@ public Plane(Point3 origin, Vector3 direction)
/// <param name="pt3">Third point representing the y direction.</param>
public Plane(Point3 pt1, Point3 pt2, Point3 pt3)
{
if(LinearAlgebra.Orientation(pt1, pt2, pt3) == 0)
if(Trigonometry.ArePointsCollinear(pt1, pt2, pt3))
{
throw new Exception("Plane cannot be created, the tree points must not be collinear");
}
Expand All @@ -45,7 +45,6 @@ public Plane(Point3 pt1, Point3 pt2, Point3 pt3)
Origin = pt1;
XAxis = dir1.Unitize();
YAxis = Vector3.CrossProduct(normal, dir1).Unitize();
ZAxis = normal.Unitize();
}

/// <summary>
Expand All @@ -59,7 +58,19 @@ public Plane(Point3 origin, Vector3 xDirection, Vector3 yDirection)
Origin = origin;
XAxis = xDirection.IsUnitVector ? xDirection : xDirection.Unitize();
YAxis = yDirection.IsUnitVector ? yDirection : yDirection.Unitize();
ZAxis = Vector3.CrossProduct(XAxis, YAxis);

}

/// <summary>
/// Constructs a plane from another plane.
/// </summary>
/// <param name="plane">Input plane.</param>
public Plane(Plane plane)
{
Origin = plane.Origin;
XAxis = plane.XAxis;
YAxis = plane.YAxis;

}

/// <summary>
Expand All @@ -78,29 +89,53 @@ public Plane(Point3 origin, Vector3 xDirection, Vector3 yDirection)
public static Plane PlaneZX => new Plane(Point3.Origin, Vector3.ZAxis, Vector3.XAxis);

/// <summary>
/// Gets the normal of the plan.
/// Gets a plane whose components are Unset.
/// </summary>
public static Plane Unset => new Plane(Point3.Unset, Vector3.Unset, Vector3.Unset);

/// <summary>
/// Gets the normal of the plane.
/// </summary>
public Vector3 Normal => ZAxis;

/// <summary>
/// Gets the origin of the plane.
/// </summary>
public Point3 Origin { get; }
public Point3 Origin { get; set; }

/// <summary>
/// Gets the XAxis of the plane.
/// </summary>
public Vector3 XAxis { get; }
public Vector3 XAxis { get; set; }

/// <summary>
/// Gets the YAxis of the plane.
/// </summary>
public Vector3 YAxis { get; }
public Vector3 YAxis { get; set; }

/// <summary>
/// Gets the ZAxis of the plane.
/// </summary>
public Vector3 ZAxis { get; }
public Vector3 ZAxis => Vector3.CrossProduct(XAxis, YAxis).Unitize();

/// <summary>
/// Returns true if origin and axis vectors are valid and orthogonal.
/// </summary>
public bool IsValid
{
get
{
//check all axes and origin are valid
var areAxesValid = Origin.IsValid && XAxis.IsValid && YAxis.IsValid && ZAxis.IsValid;

//check that vectors are orthogonal
var areAxesOrthogonal = Vector3.DotProduct(XAxis, YAxis) == 0 && Vector3.DotProduct(YAxis, ZAxis) == 0;

if (areAxesValid && areAxesOrthogonal) return true;

return false;
}
}

/// <summary>
/// Finds the closest point on a plane.
Expand Down Expand Up @@ -160,13 +195,14 @@ public Point3 PointAt(double u, double v)
}

/// <summary>
/// Swapping out the X and Y axes and inverting the Z axis.
/// Flip plane by swapping X and Y axes.
/// </summary>
/// <returns>The flipped plane.</returns>
public Plane Flip()
{
//ToDo flip by reversing X, Y, or swapping X and Y.
return new Plane(Origin, -XAxis, YAxis);
var xAxis = YAxis;
var yAxis = XAxis;
return new Plane(Origin, xAxis, yAxis);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/GShark/Operation/Tessellation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static (List<double> tValues, List<Point3> pts) CurveAdaptiveSampleRange(
Vector3 diff2 = pt1 - pt2;

if ((Vector3.DotProduct(diff, diff) < setTolerance && Vector3.DotProduct(diff2, diff2) > setTolerance)
|| !Trigonometry.AreThreePointsCollinear(pt1, pt2, pt3, setTolerance))
|| !Trigonometry.ArePointsCollinear(pt1, pt2, pt3, setTolerance))
{
// Get the exact middle value or a random value start + (end - start) * (0.45 + 0.1 * random.NextDouble());
double tMiddle = start + (end - start) * 0.5;
Expand Down