예제 #1
0
        public void It_Returns_A_Curve_Where_Degree_Is_Reduced_From_5_To_4()
        {
            // Arrange
            // Followed example Under C1 constrain condition https://www.hindawi.com/journals/mpe/2016/8140427/tab1/
            List <Point3> pts = new List <Point3>
            {
                new Point3(-5.0, 0.0, 0.0),
                new Point3(-7.0, 2.0, 0.0),
                new Point3(-3.0, 5.0, 0.0),
                new Point3(2.0, 6.0, 0.0),
                new Point3(5.0, 3.0, 0.0),
                new Point3(3.0, 0.0, 0.0)
            };
            int        degree     = 5;
            double     tolerance  = 10e-2;
            NurbsCurve curve      = new NurbsCurve(pts, degree);
            Point3     ptOnCurve0 = curve.PointAt(0.5);
            Point3     ptOnCurve1 = curve.PointAt(0.25);

            // Act
            NurbsBase reducedCurve            = curve.ReduceDegree(tolerance);
            Point3    ptOnReducedDegreeCurve0 = reducedCurve.PointAt(0.5);
            Point3    ptOnReducedDegreeCurve1 = reducedCurve.PointAt(0.25);

            // Assert
            reducedCurve.Degree.Should().Be(degree - 1);

            ptOnCurve0.DistanceTo(ptOnReducedDegreeCurve0).Should().BeLessThan(GSharkMath.MinTolerance);
            ptOnCurve1.DistanceTo(ptOnReducedDegreeCurve1).Should().BeLessThan(tolerance);
        }
예제 #2
0
        /// <summary>
        /// Computes the intersection between a plane and a circle.<br/>
        /// If the intersection is computed the result points can be 1 or 2 depending on whether the plane touches the circle tangentially or cuts through it.<br/>
        /// The intersection result false if the plane is parallel to the circle or misses the circle entirely.
        /// </summary>
        /// <param name="pl">The plane for intersection.</param>
        /// <param name="cl">The circle for intersection.</param>
        /// <param name="pts">Output the intersection points.</param>
        /// <returns>True if intersection is computed.</returns>
        public static bool PlaneCircle(Plane pl, Circle cl, out Point3[] pts)
        {
            pts = new Point3[] { };
            Point3 clPt = cl.Center;

            Vector3 cCross = Vector3.CrossProduct(pl.Origin, clPt);

            if (Math.Abs(cCross.Length) < GSharkMath.Epsilon)
            {
                return(false);
            }

            _ = PlanePlane(pl, cl.Plane, out Line intersectionLine);
            Point3 closestPt = intersectionLine.ClosestPoint(clPt);
            double distance  = clPt.DistanceTo(intersectionLine);

            if (Math.Abs(distance) < GSharkMath.Epsilon)
            {
                Point3 pt = cl.ClosestPoint(closestPt);
                pts = new[] { pt };
                return(true);
            }

            return(LineCircle(cl, intersectionLine, out pts));
        }
예제 #3
0
        public void Returns_The_Closest_Point_On_The_Surface(double[] expectedPt, double[] testPt)
        {
            // Arrange
            NurbsSurface surface           = NurbsSurfaceCollection.SurfaceFromPoints();
            Point3       pt                = new Point3(testPt[0], testPt[1], testPt[2]);
            Point3       expectedClosestPt = new Point3(expectedPt[0], expectedPt[1], expectedPt[2]);

            // Act
            Point3 closestPt = surface.ClosestPoint(pt);

            // Assert
            closestPt.DistanceTo(expectedClosestPt).Should().BeLessThan(GSharkMath.MaxTolerance);
        }
예제 #4
0
        public void It_Returns_The_Distance_Between_A_Point_And_A_Line()
        {
            // Arrange
            var    line             = new Line(new Point3(0, 0, 0), new Point3(30, 45, 0));
            var    pt               = new Point3(10, 20, 0);
            double distanceExpected = 2.7735009811261464;

            // Act
            double distance = pt.DistanceTo(line);

            // Assert
            distance.Should().Be(distanceExpected);
        }
예제 #5
0
        public void It_Creates_A_Line()
        {
            // Arrange
            Point3 startPoint = new Point3(5, 0, 0);
            Point3 endPoint   = new Point3(10, 0, 0);

            // Act
            Line line = new Line(startPoint, endPoint);

            // Assert
            line.Should().NotBeNull();
            line.StartPoint.Equals(startPoint).Should().BeTrue();
            line.EndPoint.Equals(endPoint).Should().BeTrue();
            line.Length.Equals(startPoint.DistanceTo(endPoint));
        }
예제 #6
0
        public void It_Returns_The_Distance_Between_Two_Points()
        {
            //Arrange
            var p1   = new Point3(15, 3, 6);
            var p2   = new Point3(-5, -8, 5);
            var p2p1 = p2 - p1;
            //Same as measuring the lenght of a vector between the two points.
            var expectedDistance = p2p1.Length;

            //Act
            var distance = p1.DistanceTo(p2);

            //Assert
            distance.Should().Be(expectedDistance);
        }
예제 #7
0
        public void Returns_The_Surface_Isocurve_At_V_Direction()
        {
            // Arrange
            NurbsSurface surface      = NurbsSurfaceCollection.SurfaceFromPoints();
            Point3       expectedPt   = new Point3(5, 4.615385, 2.307692);
            Point3       expectedPtAt = new Point3(5, 3.913043, 1.695652);

            // Act
            NurbsBase Isocurve = surface.IsoCurve(0.3, SurfaceDirection.V);
            Point3    ptAt     = Isocurve.PointAt(0.5);

            // Assert
            Isocurve.ControlPointLocations[1].DistanceTo(expectedPt).Should().BeLessThan(GSharkMath.MinTolerance);
            ptAt.DistanceTo(expectedPtAt).Should().BeLessThan(GSharkMath.MinTolerance);
        }
예제 #8
0
        public void It_Returns_The_Centroid_By_Area()
        {
            // Arrange
            Polygon poly2D = new Polygon(Planar2D);
            Polygon poly3D = new Polygon(Planar3D);

            Point3 centroid2DExpected = new Point3(4.033333, 4.3, 0);
            Point3 centroid3DExpected = new Point3(87.620479, 29.285305, -0.129984);

            // Act
            Point3 poly2DCentroid = poly2D.CentroidByArea;
            Point3 poly3DCentroid = poly3D.CentroidByArea;

            // Assert
            poly2DCentroid.DistanceTo(centroid2DExpected).Should().BeLessThan(GSharkMath.MaxTolerance);
            poly3DCentroid.DistanceTo(centroid3DExpected).Should().BeLessThan(GSharkMath.MaxTolerance);
        }
예제 #9
0
        private static List <Vector3> GetLargeDiagonals(List <Point3> boundingVertices, double dimensionLength)
        {
            List <Vector3> diagonals = new List <Vector3>();

            for (int i = 0; i != boundingVertices.Count; i++)
            {
                Point3 point1 = boundingVertices[i];
                for (int j = i; j != boundingVertices.Count; j++)
                {
                    Point3 point2 = boundingVertices[j];
                    if (point1.DistanceTo(point2) >= dimensionLength)
                    {
                        diagonals.Add(new Vector3(point2.X - point1.X, point2.Y - point1.Y, point2.Z - point1.Z));
                    }
                }
            }
            return(diagonals);
        }
예제 #10
0
        public void It_Returns_A_Curve_Where_Degree_Is_Elevated_From_1_To_Elevated_Degree_Value(int finalDegree)
        {
            // Arrange
            List <Point3> pts = new List <Point3>
            {
                new Point3(0.0, 0.0, 1.0),
                new Point3(7.0, 3.0, -10),
                new Point3(5.2, 5.2, -5),
            };
            int        degree    = 1;
            NurbsCurve curve     = new NurbsCurve(pts, degree);
            Point3     ptOnCurve = curve.PointAt(0.5);

            // Act
            NurbsBase elevatedDegreeCurve     = curve.ElevateDegree(finalDegree);
            Point3    ptOnElevatedDegreeCurve = elevatedDegreeCurve.PointAt(0.5);

            // Assert
            elevatedDegreeCurve.Degree.Should().Be(finalDegree);
            ptOnElevatedDegreeCurve.DistanceTo(ptOnCurve).Should().BeLessThan(GSharkMath.MinTolerance);
        }
예제 #11
0
        public void It_Returns_The_Surface_Split_At_The_Given_Parameter_At_U_Direction()
        {
            // Arrange
            NurbsSurface          surface       = NurbsSurfaceCollection.SurfaceFromPoints();
            List <List <Point3> > surfacePtsTop = new List <List <Point3> >
            {
                new List <Point3> {
                    new Point3(0.0, 0.0, 0.0), new Point3(0.0, 10.0, 4.0)
                },
                new List <Point3> {
                    new Point3(2.5, 0.0, 0.0), new Point3(3.333333, 10.0, 4.666666)
                },
                new List <Point3> {
                    new Point3(5.0, 0.0, 0.0), new Point3(5.0, 10.0, 4.333333)
                }
            };

            List <List <Point3> > surfacePtsBottom = new List <List <Point3> >
            {
                new List <Point3> {
                    new Point3(5.0, 0.0, 0.0), new Point3(5.0, 10.0, 4.333333)
                },
                new List <Point3> {
                    new Point3(7.5, 0.0, 0.0), new Point3(6.666666, 10.0, 4.0)
                },
                new List <Point3> {
                    new Point3(10.0, 0.0, 0.0), new Point3(10.0, 10.0, 2.0)
                }
            };

            List <List <double> > weightsTop = new List <List <double> >
            {
                new List <double> {
                    1, 1
                },
                new List <double> {
                    1, 1.5
                },
                new List <double> {
                    1, 1.5
                }
            };

            List <List <double> > weightsBottom = new List <List <double> >
            {
                new List <double> {
                    1, 1.5
                },
                new List <double> {
                    1, 1.5
                },
                new List <double> {
                    1, 1
                }
            };

            Point3 expectedPtTop    = new Point3(2.894737, 5.789474, 2.578947);
            Point3 expectedPtBottom = new Point3(7.105263, 5.789474, 2.157895);

            // Act
            NurbsSurface[] surfaces         = surface.SplitAt(0.5, SplitDirection.U);
            Point3         evaluatePtTop    = surfaces[0].PointAt(0.5, 0.5);
            Point3         evaluatePtBottom = surfaces[1].PointAt(0.5, 0.5);

            // Assert
            evaluatePtTop.DistanceTo(expectedPtTop).Should().BeLessThan(GSharkMath.MinTolerance);
            evaluatePtBottom.DistanceTo(expectedPtBottom).Should().BeLessThan(GSharkMath.MinTolerance);

            surfaces[0].Weights.Should().BeEquivalentTo(weightsTop);
            surfaces[1].Weights.Should().BeEquivalentTo(weightsBottom);

            _ = surfaces[0].ControlPointLocations.Select((pts, i) => pts.Select((pt, j) =>
                                                                                pt.EpsilonEquals(surfacePtsTop[i][j], GSharkMath.MinTolerance).Should().BeTrue()));
            _ = surfaces[1].ControlPointLocations.Select((pts, i) => pts.Select((pt, j) =>
                                                                                pt.EpsilonEquals(surfacePtsBottom[i][j], GSharkMath.MinTolerance).Should().BeTrue()));
        }
예제 #12
0
        public void It_Returns_The_Surface_Split_At_The_Given_Parameter_At_V_Direction()
        {
            // Arrange
            NurbsSurface          surface        = NurbsSurfaceCollection.SurfaceFromPoints();
            List <List <Point3> > surfacePtsLeft = new List <List <Point3> >
            {
                new List <Point3> {
                    new Point3(0.0, 0.0, 0.0), new Point3(0.0, 5.0, 2.0)
                },
                new List <Point3> {
                    new Point3(5.0, 0.0, 0.0), new Point3(5.0, 6.666666, 3.333333)
                },
                new List <Point3> {
                    new Point3(10.0, 0.0, 0.0), new Point3(10.0, 5.0, 1.0)
                }
            };

            List <List <Point3> > surfacePtsRight = new List <List <Point3> >
            {
                new List <Point3> {
                    new Point3(0.0, 5.0, 2.0), new Point3(0.0, 10.0, 4.0)
                },
                new List <Point3> {
                    new Point3(5.0, 6.666666, 3.333333), new Point3(5.0, 10.0, 5.0)
                },
                new List <Point3> {
                    new Point3(10.0, 5.0, 1.0), new Point3(10.0, 10.0, 2.0)
                }
            };

            List <List <double> > weightsLeft = new List <List <double> >
            {
                new List <double> {
                    1, 1
                },
                new List <double> {
                    1, 1.5
                },
                new List <double> {
                    1, 1
                }
            };

            List <List <double> > weightsRight = new List <List <double> >
            {
                new List <double> {
                    1, 1
                },
                new List <double> {
                    1.5, 2
                },
                new List <double> {
                    1, 1
                }
            };

            Point3 expectedPtLeft  = new Point3(5.0, 3.333333, 1.444444);
            Point3 expectedPtRight = new Point3(5.0, 8.181818, 3.545455);

            // Act
            NurbsSurface[] surfaces        = surface.SplitAt(0.5, SplitDirection.V);
            Point3         evaluatePtLeft  = surfaces[0].PointAt(0.5, 0.5);
            Point3         evaluatePtRight = surfaces[1].PointAt(0.5, 0.5);

            // Assert
            evaluatePtLeft.DistanceTo(expectedPtLeft).Should().BeLessThan(GSharkMath.MinTolerance);
            evaluatePtRight.DistanceTo(expectedPtRight).Should().BeLessThan(GSharkMath.MinTolerance);

            surfaces[0].Weights.Should().BeEquivalentTo(weightsLeft);
            surfaces[1].Weights.Should().BeEquivalentTo(weightsRight);

            _ = surfaces[0].ControlPointLocations.Select((pts, i) => pts.Select((pt, j) =>
                                                                                pt.EpsilonEquals(surfacePtsLeft[i][j], GSharkMath.MinTolerance).Should().BeTrue()));
            _ = surfaces[1].ControlPointLocations.Select((pts, i) => pts.Select((pt, j) =>
                                                                                pt.EpsilonEquals(surfacePtsRight[i][j], GSharkMath.MinTolerance).Should().BeTrue()));
        }