예제 #1
0
        void Start()
        {
            points = new Vector2f[100];
            FillWithRandom(points);

            convex = ConvexHull2.FindHull(points);
            convex.BuildIndices();
        }
예제 #2
0
    public void AlgorithmHullFaces()
    {
        var triangles = mConvexHull3.Triangles;
        var dataCloud = mConvexHull3.DataCloud;
        var points    = mConvexHull3.Vertices;

        if (triangles.Count < 4)
        {
            Debugger.Get.Log("Insufficient points to form a tetrahedron.", DebugOption.SBB3);
            return;
        }

        mVolume = float.MaxValue;
        foreach (Triangle triangle in triangles)
        {
            List <Vector3> localPoints = new List <Vector3>(triangles.Count * 3);

            float farthestDistance = -float.MaxValue;
            foreach (int point in points)
            {
                Vector3 dataCloudPoint = dataCloud[point];

                float distance = Mathf.Abs(triangle.CalculateDistance(dataCloudPoint));
                farthestDistance = Mathf.Max(farthestDistance, distance);

                localPoints.Add(triangle.ToLocal(dataCloudPoint));
            }

            ConvexHull2 ch2 = new ConvexHull2(localPoints);
            ch2.AlgorithmQuickhull();

            OBB2 obb2 = new OBB2(ch2);
            obb2.AlgorithmRotatingCalipers();

            float newVolume = obb2.Area * farthestDistance;
            if (newVolume < mVolume)
            {
                mVolume = newVolume;

                var worldRect = new {
                    BottomLeftCorner  = triangle.ToWorld(obb2.Rectangle.Corner),
                    BottomRightCorner = triangle.ToWorld(obb2.Rectangle.Corner + obb2.Rectangle.X * obb2.Rectangle.Extents.x),
                    TopLeftCorner     = triangle.ToWorld(obb2.Rectangle.Corner + obb2.Rectangle.Y * obb2.Rectangle.Extents.y)
                };

                mBox.Extents = new Vector3(obb2.Rectangle.Extents.x, obb2.Rectangle.Extents.y, farthestDistance);
                mBox.Corner  = worldRect.BottomLeftCorner;
                mBox.X       = (worldRect.BottomRightCorner - mBox.Corner).normalized;
                mBox.Y       = (worldRect.TopLeftCorner - mBox.Corner).normalized;
                mBox.Z       = -triangle.N; // Triangle normal always points outside convex hull.
            }
        }
    }
예제 #3
0
        public static void test_convex_hull_2()
        {
            Random r = new Random(31337);

            //LocalProfiler p = new LocalProfiler();
            //p.Start("Hulls");

            QueryNumberType[] modes = new QueryNumberType[] { QueryNumberType.QT_DOUBLE, QueryNumberType.QT_INT64 };

            foreach (var queryMode in modes)
            {
                for (int k = 0; k < 1000; ++k)
                {
                    int    N     = 2500;
                    double scale = (r.NextDouble() + 0.1) * 1024.0;

                    Vector2d[] pts = TestUtil.RandomPoints2(N, r, Vector2d.Zero, scale);

                    double eps = MathUtil.Epsilonf;

                    ConvexHull2 hull     = new ConvexHull2(pts, eps, queryMode);
                    Polygon2d   hullPoly = hull.GetHullPolygon();

                    foreach (Vector2d v in pts)
                    {
                        if (hullPoly.Contains(v))
                        {
                            continue;
                        }
                        double d = hullPoly.DistanceSquared(v);
                        if (d < eps)
                        {
                            continue;
                        }
                        System.Console.WriteLine("test_convex_hull: Point {0} not contained!", v);
                    }
                }
            }

            //p.StopAll();
            //System.Console.WriteLine(p.AllTimes());

            //SVGWriter writer = new SVGWriter();
            //foreach (Vector2d v in pts) {
            //    writer.AddCircle(new Circle2d(v, 3.0), SVGWriter.Style.Outline("black", 1.0f));
            //}
            //writer.AddPolygon(hullPoly, SVGWriter.Style.Outline("red", 2.0f));
            //writer.Write(TestUtil.GetTestOutputPath("test.svg"));
        }
예제 #4
0
        private static ConvexHull2 GetConvexHull(IReadOnlyCollection <Contour> contours)
        {
            List <Vector2d> points = new List <Vector2d>();

            foreach (Contour contour in contours)
            {
                foreach (var point in contour.Points)
                {
                    points.Add(new Vector2d(point.x, point.y));
                }
            }
            ConvexHull2 convexHull2 = new ConvexHull2(points, EquityTolerance, QueryNumberType.QT_DOUBLE);

            return(convexHull2);
        }
예제 #5
0
        private void Start()
        {
            lineMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
            vertices     = new List <Vertex2>();
            Random.InitState(seed);

            for (int i = 0; i < NumberOfVertices; i++)
            {
                float x = size * Random.Range(-1.0f, 1.0f);
                float y = size * Random.Range(-1.0f, 1.0f);
                vertices.Add(new Vertex2(x, y));
            }

            hull = new ConvexHull2();
            hull.Generate(vertices);
        }
예제 #6
0
        public void FindHull()
        {
            Vector2f[] points = new Vector2f[]
            {
                new Vector2f(0, 0),
                new Vector2f(10, 0),
                new Vector2f(10, 10),
                new Vector2f(6, 5),
                new Vector2f(4, 1)
            };

            Polygon2f convex = ConvexHull2.FindHull(points);

            Assert.AreEqual(3, convex.VerticesCount);
            Assert.AreEqual(points[0], convex.Positions[0]);
            Assert.AreEqual(points[1], convex.Positions[1]);
            Assert.AreEqual(points[2], convex.Positions[2]);
            Assert.IsTrue(ConvexHull2.IsStronglyConvex(convex.Positions, convex.IsCCW));
        }
 void LoadIfNecessary()
 {
     if (meshFilter == null)
     {
         meshFilter = GetComponent <MeshFilter>();
     }
     if (ch2 == null)
     {
         ch2 = new ConvexHull2(new List <Vector3>());
     }
     if (obb2 == null)
     {
         obb2 = new OBB2(ch2);
     }
     if (ch3 == null)
     {
         ch3 = new ConvexHull3(new List <Vector3>());
     }
     if (obb3 == null)
     {
         obb3 = new OBB3(ch3);
     }
 }
예제 #8
0
        // exports svg w/ different containments of point set (created by slicing mesh)
        public static void containment_demo_svg()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            MeshTransforms.Scale(mesh, 4);

            AxisAlignedBox3d meshBounds = mesh.CachedBounds;
            Vector3d         origin     = meshBounds.Center;

            origin -= 0.2 * meshBounds.Height * Vector3d.AxisY;
            Frame3f      plane = new Frame3f(origin, new Vector3d(1, 3, 0).Normalized);
            MeshPlaneCut cut   = new MeshPlaneCut(mesh, plane.Origin, plane.Z);

            cut.Cut();

            AxisAlignedBox2d polyBounds = AxisAlignedBox2d.Empty;
            List <Polygon2d> polys      = new List <Polygon2d>();

            foreach (EdgeLoop loop in cut.CutLoops)
            {
                Polygon2d poly = new Polygon2d();
                foreach (int vid in loop.Vertices)
                {
                    poly.AppendVertex(mesh.GetVertex(vid).xz);
                }
                poly.Rotate(new Matrix2d(90, true), Vector2d.Zero);
                polys.Add(poly);
                polyBounds.Contain(poly.Bounds);
            }

            SVGWriter svg       = new SVGWriter();
            var       polyStyle = SVGWriter.Style.Outline("red", 1.0f);
            var       contStyle = SVGWriter.Style.Outline("black", 1.0f);

            for (int k = 0; k < 3; ++k)
            {
                double          shift = (k == 2) ? 1.4f : 1.1f;
                Vector2d        tx    = (k - 1) * (polyBounds.Width * shift) * Vector2d.AxisX;
                List <Vector2d> pts   = new List <Vector2d>();
                foreach (Polygon2d poly in polys)
                {
                    var p2 = new Polygon2d(poly).Translate(tx);
                    pts.AddRange(p2.Vertices);
                    svg.AddPolygon(p2, polyStyle);
                }

                if (k == 0)
                {
                    ConvexHull2 hull = new ConvexHull2(pts, 0.001, QueryNumberType.QT_DOUBLE);
                    svg.AddPolygon(hull.GetHullPolygon(), contStyle);
                }
                else if (k == 1)
                {
                    ContMinBox2 contbox = new ContMinBox2(pts, 0.001, QueryNumberType.QT_DOUBLE, false);
                    svg.AddPolygon(new Polygon2d(contbox.MinBox.ComputeVertices()), contStyle);
                }
                else if (k == 2)
                {
                    ContMinCircle2 contcirc = new ContMinCircle2(pts);
                    svg.AddCircle(contcirc.Result, contStyle);
                }
            }


            svg.Write(TestUtil.GetTestOutputPath("contain_demos.svg"));
        }
예제 #9
0
        /// <summary>
        /// 获取点集合的凸包polygon2d
        /// </summary>
        /// <param name="vector2ds"></param>
        /// <returns></returns>
        public static Polygon2d ConvexHullPolygon2d(this IEnumerable <Vector2d> vector2ds)
        {
            ConvexHull2 convexHull2 = new ConvexHull2(vector2ds.ToList(), Precision_.Precison, QueryNumberType.QT_DOUBLE);

            return(convexHull2.GetHullPolygon());
        }
예제 #10
0
 public OBB2(ConvexHull2 convexHull2Data)
 {
     mConvexHull2 = convexHull2Data;
     mRectangle   = new Rectangle();
 }