From 31895ea2c11d9bc0a76353ac441915338b2938e4 Mon Sep 17 00:00:00 2001 From: Guido Maciocci Date: Mon, 15 Nov 2021 23:52:27 +1100 Subject: [PATCH] Adds check for surface planarity. --- .../Geometry/NurbsSurfaceTests.cs | 27 +++++++++++++++++++ src/GShark/Core/Trigonometry.cs | 11 ++++---- src/GShark/Geometry/NurbsSurface.cs | 11 ++++++++ 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/GShark.Test.XUnit/Geometry/NurbsSurfaceTests.cs b/src/GShark.Test.XUnit/Geometry/NurbsSurfaceTests.cs index 19da6d7e..a85440d6 100644 --- a/src/GShark.Test.XUnit/Geometry/NurbsSurfaceTests.cs +++ b/src/GShark.Test.XUnit/Geometry/NurbsSurfaceTests.cs @@ -269,6 +269,33 @@ public void Returns_True_If_Surface_Is_Close() surface.IsClosed(SurfaceDirection.V).Should().BeTrue(); } + [Fact] + public void Returns_True_If_Surface_Is_Planar() + { + //Arrange + var planarSurface = NurbsSurface.FromCorners( + new Point3(0, 0, 0), + new Point3(10, 0, 0), + new Point3(10,5,0), + new Point3(0,5,0) + ); + + var nonPlanarSurface = NurbsSurface.FromCorners( + new Point3(0, 0, 0), + new Point3(10, 0, 5), + new Point3(10, 5, 0), + new Point3(0, 5, 5) + ); + + //Act + var isPlanarSurfacePlanar = planarSurface.IsPlanar(); + var isNonPlanarSurfacePlanar = nonPlanarSurface.IsPlanar(); + + //Assert + isPlanarSurfacePlanar.Should().BeTrue(); + isNonPlanarSurfacePlanar.Should().BeFalse(); + } + [Theory] [InlineData(0.1, 0.1, new double[] { 0.2655, 1, 2.442 })] [InlineData(0.5, 0.5, new double[] { 4.0625, 5, 4.0625 })] diff --git a/src/GShark/Core/Trigonometry.cs b/src/GShark/Core/Trigonometry.cs index d4bc0feb..89e86a72 100644 --- a/src/GShark/Core/Trigonometry.cs +++ b/src/GShark/Core/Trigonometry.cs @@ -11,14 +11,15 @@ namespace GShark.Core public class Trigonometry { /// - /// Determines if the provide points are on the same plane. + /// Determines if the provide points are on the same plane within specified tolerance. /// - /// Provided points. - /// Whether the point are coplanar. - public static bool ArePointsCoplanar(IList points) + /// Points to check. + /// Tolerance. + /// True if all points are coplanar. + public static bool ArePointsCoplanar(IList points, double tolerance = GSharkMath.Epsilon) { // https://en.wikipedia.org/wiki/Triple_product - if (points.Count < 3) + if (points.Count <= 3) { return true; } diff --git a/src/GShark/Geometry/NurbsSurface.cs b/src/GShark/Geometry/NurbsSurface.cs index 43cc1c14..2de0a7f7 100644 --- a/src/GShark/Geometry/NurbsSurface.cs +++ b/src/GShark/Geometry/NurbsSurface.cs @@ -108,6 +108,17 @@ public bool IsClosed(SurfaceDirection direction) return pts2d.All(pts => pts[0].DistanceTo(pts.Last()) < GSharkMath.Epsilon); } + + /// + /// Checks is surface is planar within specified tolerance. + /// + /// + /// + public bool IsPlanar(double tolerance = GSharkMath.Epsilon) + { + return Trigonometry.ArePointsCoplanar(ControlPointLocations.SelectMany(pt => pt).ToList(), tolerance); + } + /// /// Constructs a NURBS surface from four corners.
/// If the corners are ordered ccw the normal of the surface will point up otherwise, if corners ordered cw the normal will point down.