예제 #1
0
        public void It_Returns_False_If_Three_Points_Are_Not_Collinear()
        {
            // Arrange
            Point3 pt1 = new Point3(25.923, 27.057, 0.0);
            Point3 pt2 = new Point3(35.964, 20.451, 0.0);
            Point3 pt3 = new Point3(51.299, 37.950, 0.0);

            // Assert
            Trigonometry.ArePointsCollinear(pt1, pt2, pt3).Should().BeFalse();
        }
예제 #2
0
        /// <summary>
        /// Constructs a plane from three non-collinear points.
        /// </summary>
        /// <param name="pt1">Firs point representing the origin.</param>
        /// <param name="pt2">Second point representing the x direction.</param>
        /// <param name="pt3">Third point representing the y direction.</param>
        public Plane(Point3 pt1, Point3 pt2, Point3 pt3)
        {
            if (Trigonometry.ArePointsCollinear(pt1, pt2, pt3))
            {
                throw new Exception("Plane cannot be created, the tree points must not be collinear");
            }

            Vector3 dir1   = pt2 - pt1;
            Vector3 dir2   = pt3 - pt1;
            Vector3 normal = Vector3.CrossProduct(dir1, dir2);

            Origin = pt1;
            XAxis  = dir1.Unitize();
            YAxis  = Vector3.CrossProduct(normal, dir1).Unitize();
        }
예제 #3
0
        /// <summary>
        ///   Find four points in the point cloud that are not coplanar for the
        ///   seed hull
        /// </summary>
        private void FindInitialHullIndices(List <Point3> points, out int b0, out int b1, out int b2, out int b3)
        {
            int count = points.Count;

            for (int i0 = 0; i0 < count - 3; i0++)
            {
                for (int i1 = i0 + 1; i1 < count - 2; i1++)
                {
                    Vector3 p0 = points[i0];
                    Vector3 p1 = points[i1];

                    if (p0.EpsilonEquals(p1, GSharkMath.MinTolerance))
                    {
                        continue;
                    }

                    for (int i2 = i1 + 1; i2 < count - 1; i2++)
                    {
                        Vector3 p2 = points[i2];

                        if (Trigonometry.ArePointsCollinear(p0, p1, p2))
                        {
                            continue;
                        }

                        for (int i3 = i2 + 1; i3 < count - 0; i3++)
                        {
                            Vector3 p3 = points[i3];

                            if (Trigonometry.ArePointsCoplanar(new List <Point3> {
                                p0, p1, p2, p3
                            }))
                            {
                                continue;
                            }

                            b0 = i0;
                            b1 = i1;
                            b2 = i2;
                            b3 = i3;
                            return;
                        }
                    }
                }
            }

            throw new System.ArgumentException("Can't generate hull, points are coplanar");
        }
예제 #4
0
        /// <summary>
        /// Samples a curve in an adaptive way. <br/>
        /// <em>Corresponds to this algorithm http://ariel.chronotext.org/dd/defigueiredo93adaptive.pdf <br/>
        /// https://www.modelical.com/en/grasshopper-scripting-107/ </em>
        /// </summary>
        /// <param name="curve">The curve to sampling.</param>
        /// <param name="start">The start parameter for sampling.</param>
        /// <param name="end">The end parameter for sampling.</param>
        /// <param name="tolerance">Tolerance for the adaptive scheme. The default tolerance is set as (1e-6).</param>
        /// <returns>A tuple with the set of points and the t parameter where the point was evaluated.</returns>
        public static (List <double> tValues, List <Point3> pts) AdaptiveSampleRange(NurbsBase curve, double start, double end, double tolerance = GSharkMath.MinTolerance)
        {
            // Sample curve at three pts.
            Random random = new Random();
            double t      = 0.5 + 0.2 * random.NextDouble();
            double mid    = start + (end - start) * t;

            Point3 pt1 = Point4.PointDehomogenizer(Evaluate.Curve.PointAt(curve, start));
            Point3 pt2 = Point4.PointDehomogenizer(Evaluate.Curve.PointAt(curve, mid));
            Point3 pt3 = Point4.PointDehomogenizer(Evaluate.Curve.PointAt(curve, end));

            Vector3 diff  = pt1 - pt3;
            Vector3 diff2 = pt1 - pt2;

            if ((Vector3.DotProduct(diff, diff) < tolerance && Vector3.DotProduct(diff2, diff2) > tolerance) ||
                !Trigonometry.ArePointsCollinear(pt1, pt2, pt3, tolerance))
            {
                // 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;

                // Recurse the two halves.
                (List <double> tValues, List <Point3> pts)leftHalves  = AdaptiveSampleRange(curve, start, tMiddle, tolerance);
                (List <double> tValues, List <Point3> pts)rightHalves = AdaptiveSampleRange(curve, tMiddle, end, tolerance);

                leftHalves.tValues.RemoveAt(leftHalves.tValues.Count - 1);
                List <double> tMerged = leftHalves.tValues.Concat(rightHalves.tValues).ToList();
                leftHalves.pts.RemoveAt(leftHalves.pts.Count - 1);
                List <Point3> ptsMerged = leftHalves.pts.Concat(rightHalves.pts).ToList();

                return(tMerged, ptsMerged);
            }

            return(new List <double> {
                start, end
            }, new List <Point3> {
                pt1, pt3
            });
        }