示例#1
0
        public Circle(List <Point> ps)
        {
            Circle c = SmallestEnclosingCircle.MakeCircle(ps);

            this.c = c.c;
            this.r = c.r;
        }
        public void OnExecute()
        {
            IList <Point> points = null;

            DateTime start = DateTime.Now;

            if (JsonPointsPath == null)
            {
                points = GenerateRandomPoints(NumberOfPoints == 0 ? 2 : NumberOfPoints);
            }
            else
            {
                // deserialize JSON directly from a file
                using (StreamReader file = File.OpenText(JsonPointsPath))
                {
                    JsonSerializer serializer = new JsonSerializer();
                    points = (Point[])serializer.Deserialize(file, typeof(Point[]));
                }
            }
            DateTime end = DateTime.Now;

            Console.WriteLine(end - start);

            start = end;
            Circle result = SmallestEnclosingCircle.MakeCircle(points);

            Console.WriteLine(JsonConvert.SerializeObject(result));
            end = DateTime.Now;
            Console.WriteLine(end - start);
        }
        private Matrix4X4 GetCenteringTransformExpandedToRadius(IEnumerable <IObject3D> items, double radius)
        {
            IEnumerable <Vector2> GetTranslatedXY()
            {
                foreach (var item in items)
                {
                    foreach (var mesh in item.VisibleMeshes())
                    {
                        var worldMatrix = mesh.WorldMatrix(this);
                        foreach (var vertex in mesh.Mesh.Vertices)
                        {
                            yield return(new Vector2(vertex.Transform(worldMatrix)));
                        }
                    }
                }
            }

            var circle = SmallestEnclosingCircle.MakeCircle(GetTranslatedXY());

            // move the circle center to the origin
            var centering = Matrix4X4.CreateTranslation(-circle.Center.X, -circle.Center.Y, 0);
            // scale to the fit size in x y
            double scale    = radius / circle.Radius;
            var    scalling = Matrix4X4.CreateScale(scale, scale, 1);

            return(centering * scalling);
        }
示例#4
0
    private static void TestScaling()
    {
        int TRIALS = 100;
        int CHECKS = 10;

        for (int i = 0; i < TRIALS; i++)
        {
            IList <Point> points    = MakeRandomPoints(rand.Next(300) + 1);
            Circle        reference = SmallestEnclosingCircle.MakeCircle(points);

            for (int j = 0; j < CHECKS; j++)
            {
                double        scale     = NextGaussian();
                IList <Point> newPoints = new List <Point>();
                foreach (Point p in points)
                {
                    newPoints.Add(new Point(p.x * scale, p.y * scale));
                }

                Circle scaled = SmallestEnclosingCircle.MakeCircle(newPoints);
                AssertApproxEqual(reference.c.x * scale, scaled.c.x, EPSILON);
                AssertApproxEqual(reference.c.y * scale, scaled.c.y, EPSILON);
                AssertApproxEqual(reference.r * Math.Abs(scale), scaled.r, EPSILON);
            }
        }
    }
示例#5
0
    private static void TestTranslation()
    {
        int TRIALS = 100;
        int CHECKS = 10;

        for (int i = 0; i < TRIALS; i++)
        {
            IList <Point> points    = MakeRandomPoints(rand.Next(300) + 1);
            Circle        reference = SmallestEnclosingCircle.MakeCircle(points);

            for (int j = 0; j < CHECKS; j++)
            {
                double        dx        = NextGaussian();
                double        dy        = NextGaussian();
                IList <Point> newPoints = new List <Point>();
                foreach (Point p in points)
                {
                    newPoints.Add(new Point(p.x + dx, p.y + dy));
                }

                Circle translated = SmallestEnclosingCircle.MakeCircle(newPoints);
                AssertApproxEqual(reference.c.x + dx, translated.c.x, EPSILON);
                AssertApproxEqual(reference.c.y + dy, translated.c.y, EPSILON);
                AssertApproxEqual(reference.r, translated.r, EPSILON);
            }
        }
    }
示例#6
0
        /// <summary>
        /// Calculate a marina's location based on the locations that its spots have, if it has any.
        /// </summary>
        /// <remarks>
        /// Uses a algorithm in order to determine the smallest enclosing circle of a number of points.
        /// </remarks>
        /// <param name="marina"></param>
        public static void CalculateMarinaLocation(Marina marina)
        {
            if (marina is not null)
            {
                if (MarinaSpotsHaveLocations(marina))
                {
                    var locations = new List <Point>();

                    // Verify for spots with locations once again
                    // (When the method gets called it is made sure that the spots inside have a valid location, but let's verify again)
                    marina.Spots
                    .FindAll(spot => spot.LocationId.IsValidId())
                    .ForEach(spot => locations.Add(new Point(spot.Location.Latitude, spot.Location.Longitude)));

                    Circle circle = SmallestEnclosingCircle.MakeCircle(locations);

                    if (circle.r * 8000 < 10000)
                    {
                        circle.r = 10;
                    }

                    Location marinaLocation = new Location
                    {
                        Latitude  = circle.c.x,
                        Longitude = circle.c.y,
                        Radius    = circle.r,
                    };

                    marina.Location = marinaLocation;
                }
            }
        }
示例#7
0
        private static Affine GetCenteringTransformExpandedToRadius(IVertexSource vertexSource, double radius)
        {
            var circle = SmallestEnclosingCircle.MakeCircle(vertexSource.Vertices().Select((v) => new Vector2(v.position.X, v.position.Y)));

            // move the circle center to the origin
            var centering = Affine.NewTranslation(-circle.Center);
            // scale to the fit size in x y
            double scale    = radius / circle.Radius;
            var    scalling = Affine.NewScaling(scale);

            return(centering * scalling);
        }
示例#8
0
        public CylinderParams GetBoundingCylinder(IBody2 body, double[] dir)
        {
            double[] xAxis = new double[] { 1, 0, 0 };
            double[] yAxis = new double[] { 0, 1, 0 };
            double[] zAxis = new double[] { 0, 0, 1 };

            bool           isAligned      = m_MathHelper.ArrayEqual(dir, yAxis);
            IMathTransform alignTransform = null;

            if (!isAligned)
            {
                alignTransform = m_MathHelper.GetTransformBetweenVectorsAroundPoint(
                    dir, yAxis, new double[] { 0, 0, 0 });

                IBody2 bodyCopy = body.ICopy();

                bodyCopy.ApplyTransform(alignTransform as MathTransform);

                body = bodyCopy;
            }

            double[] rootPt;
            double[] endPt;
            GetExtremePoints(body, yAxis, out rootPt, out endPt);

            double height = Math.Abs(endPt[1] - rootPt[1]);

            dir = new double[] { 0, endPt[1] - rootPt[1], 0 };

            List <double[]> perPoints = GetPerimeterPoints(body, xAxis, zAxis);
            List <Point>    points    = new List <Point>();

            foreach (double[] pt in perPoints)
            {
                points.Add(new Point(pt[0], pt[2]));
            }

            Circle cir = SmallestEnclosingCircle.MakeCircle(points);

            double[] circCenter = new double[] { cir.c.x, rootPt[1], cir.c.y };

            if (!isAligned)
            {
                circCenter = m_MathHelper.TransformPoint(circCenter, alignTransform.IInverse());
                dir        = m_MathHelper.TransformVector(dir, alignTransform.IInverse());
            }

            double radius = cir.r;

            return(new CylinderParams(height, circCenter, dir, radius));
        }
示例#9
0
    /*---- Test suite functions ----*/

    private static void TestMatchingNaiveAlgorithm()
    {
        int TRIALS = 1000;

        for (int i = 0; i < TRIALS; i++)
        {
            IList <Point> points    = MakeRandomPoints(rand.Next(30) + 1);
            Circle        reference = SmallestEnclosingCircleNaive(points);
            Circle        actual    = SmallestEnclosingCircle.MakeCircle(points);
            AssertApproxEqual(reference.c.x, actual.c.x, EPSILON);
            AssertApproxEqual(reference.c.y, actual.c.y, EPSILON);
            AssertApproxEqual(reference.r, actual.r, EPSILON);
        }
    }
示例#10
0
        public static Circle GetSmallestEnclosingCircleAlongZ(this IObject3D object3D)
        {
            var visibleMeshes = object3D.VisibleMeshes().Select(vm => (source: vm, convexHull: vm.Mesh.GetConvexHull(false))).ToList();

            IEnumerable <Vector2> GetVertices()
            {
                foreach (var visibleMesh in visibleMeshes)
                {
                    var matrix = visibleMesh.source.WorldMatrix(object3D);
                    foreach (var positon in visibleMesh.convexHull.Vertices)
                    {
                        var transformed = positon.Transform(matrix);
                        yield return(new Vector2(transformed.X, transformed.Y));
                    }
                }
            }

            var circle = SmallestEnclosingCircle.MakeCircle(GetVertices());

            return(circle);
        }
示例#11
0
        private Polygon GetBoundingCircle(Polygons basePolygons)
        {
            IntPoint center;
            double   radius;

            if (Centering == CenteringTypes.Bounds)
            {
                IEnumerable <Vector2> GetVertices()
                {
                    foreach (var polygon in basePolygons)
                    {
                        foreach (var positon in polygon)
                        {
                            yield return(new Vector2(positon.X, positon.Y));
                        }
                    }
                }

                var circle = SmallestEnclosingCircle.MakeCircle(GetVertices());

                center = new IntPoint(circle.Center.X, circle.Center.Y);
                radius = (long)circle.Radius;
            }
            else
            {
                var outsidePolygons = new List <List <IntPoint> >();
                // remove all holes from the polygons so we only center the major outlines
                var polygons = VertexSource.CreatePolygons();

                foreach (var polygon in polygons)
                {
                    if (polygon.GetWindingDirection() == 1)
                    {
                        outsidePolygons.Add(polygon);
                    }
                }

                IVertexSource outsideSource = outsidePolygons.CreateVertexStorage();

                var polyCenter = outsideSource.GetWeightedCenter();

                center = new IntPoint(polyCenter.X * 1000, polyCenter.Y * 1000);
                radius = 0;

                foreach (Polygon polygon in basePolygons)
                {
                    foreach (IntPoint point in polygon)
                    {
                        long length = (point - center).Length();
                        if (length > radius)
                        {
                            radius = length;
                        }
                    }
                }
            }

            var boundingCircle = new Polygon();
            int numPoints      = 100;

            for (int i = 0; i < numPoints; i++)
            {
                double   angle            = i / 100.0 * Math.PI * 2.0;
                IntPoint newPointOnCircle = new IntPoint(Math.Cos(angle) * radius, Math.Sin(angle) * radius) + center;
                boundingCircle.Add(newPointOnCircle);
            }

            return(boundingCircle);
        }