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);
        }
Ejemplo n.º 3
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);
            }
        }
    }
Ejemplo n.º 4
0
        public Circle(List <Point> ps)
        {
            Circle c = SmallestEnclosingCircle.MakeCircle(ps);

            this.c = c.c;
            this.r = c.r;
        }
Ejemplo n.º 5
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;
                }
            }
        }
Ejemplo n.º 6
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);
            }
        }
    }
Ejemplo n.º 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);
        }
Ejemplo n.º 8
0
    // Returns the smallest enclosing circle in O(n^4) time using the naive algorithm.
    private static Circle SmallestEnclosingCircleNaive(IList <Point> points)
    {
        // Degenerate cases
        if (points.Count == 0)
        {
            return(new Circle(new Point(0, 0), -1));
        }
        else if (points.Count == 1)
        {
            return(new Circle(points[0], 0));
        }

        // Try all unique pairs
        Circle result = new Circle(new Point(0, 0), -1);

        for (int i = 0; i < points.Count; i++)
        {
            for (int j = i + 1; j < points.Count; j++)
            {
                Circle c = SmallestEnclosingCircle.MakeDiameter(points[i], points[j]);
                if ((result.r < 0 || c.r < result.r) && c.Contains(points))
                {
                    result = c;
                }
            }
        }
        if (result.r >= 0)
        {
            return(result);             // This optimization is not mathematically proven
        }
        // Try all unique triples
        for (int i = 0; i < points.Count; i++)
        {
            for (int j = i + 1; j < points.Count; j++)
            {
                for (int k = j + 1; k < points.Count; k++)
                {
                    Circle c = SmallestEnclosingCircle.MakeCircumcircle(points[i], points[j], points[k]);
                    if (c.r >= 0 && (result.r < 0 || c.r < result.r) && c.Contains(points))
                    {
                        result = c;
                    }
                }
            }
        }
        if (result.r < 0)
        {
            throw new SystemException("Assertion error");
        }
        return(result);
    }
Ejemplo n.º 9
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));
        }
Ejemplo n.º 10
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);
        }
    }
        public void MakeCircle_Get()
        {
            var points = new List <Point>()
            {
                new Point(0, 0),
                new Point(6, 0),
                new Point(3, 6),
                new Point(9, 6),
            };

            var circle = SmallestEnclosingCircle.GetCircle(points);

            Assert.AreEqual(4.5, circle.center.x);
            Assert.AreEqual(3, circle.center.y);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Processes the farm mechanics.
        /// </summary>
        private void ProcessFarmMechanics()
        {
            if (Orbwalker.Mode == OrbwalkingMode.Combo || !WSpell.Ready)
            {
                return;
            }

            var zoneCircle = Geometry.GetNewCircleAtPoint(new Point(LocalHero.Position.X, 0, LocalHero.Position.Z),
                                                          LocalHeroTrueRange * 3);

            var enemyHeroesCountTask = Task <int> .Factory.StartNew(() => GetEnemyHeroesCountInZone(ref zoneCircle));

            if (enemyHeroesCountTask.Result > 0)
            {
                return;
            }

            var minionPointSet = new PointSet();

            foreach (var enemyMinion in GameObjects.EnemyMinions)
            {
                if (enemyMinion.Team != GameObjectTeam.Chaos || !IsValidTargetLocked(enemyMinion, WSpell.Range))
                {
                    continue;
                }

                minionPointSet.Add(new Point(enemyMinion.Position.X, enemyMinion.Position.Z, 0));
            }

            if (minionPointSet.Count < 2)
            {
                return;
            }

            var smallestEnclosingCircle = new SmallestEnclosingCircle(minionPointSet);
            var computedCircle          = smallestEnclosingCircle.ComputeCircle();

            CastSpellW(new Vector2((float)computedCircle.Center.X, (float)computedCircle.Center.Y),
                       SpellPriority.Farm);
        }
Ejemplo n.º 14
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);
        }
Ejemplo n.º 15
0
        private AlgorithmManager()
        {
            // Color c = Colors.

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Graham Scan modified", "Rod Stephens", "Slowest but simple and great for comparison.",
                                                  OxyPlot.OxyColors.DarkKhaki,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();
                var result    = RodStephens.Geometry.MakeConvexHull(points);
                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }
                return(result.ToArray());
            }));

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Monotone chain", "A. M. Andrew, David Piepgrass (Qwerties)", "Very slow. Got on the web.",
                                                  OxyPlot.OxyColors.Chocolate,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();
                var result    = MonotoneChainImplementation.ComputeConvexHull(points);
                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }
                return(result.ToArray());
            }));

            AlgoIndexMonotoneChain = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Heap", "?, Pat Morin", "Very slow. Got on the web.", OxyPlot.OxyColors.Thistle,
                                                  (points, algorithmStat) =>
            {
                ConvexHullHeapAndChanWrapper wrapper = new ConvexHullHeapAndChanWrapper(points);
                wrapper.HeapHull();
                var result = wrapper.HullPoints;

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = wrapper.TimeSpan;
                }

                return(result);
            }));

            AlgoIndexHeap = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "MI ConvexHUll (Delaunay/Voronoi)", "Delaunay and Voronoi, davecz",
                                                  "Slow. From CodePlex. Could do 3D.", OxyPlot.OxyColors.Indigo,
                                                  (points, algorithmStat) =>
            {
                var vertices = new Vertex[points.Length];
                int i        = 0;
                foreach (var point in points)
                {
                    vertices[i] = new Vertex(point.X, point.Y);
                    i++;
                }

                var stopwatch  = Stopwatch.StartNew();
                var convexHull = MIConvexHull.ConvexHull.Create(vertices);
                stopwatch.Stop();

                var hullPoints = new Point[convexHull.Points.Count()];
                i = 0;

                if (hullPoints.Length > 0)
                {
                    var firstFace = convexHull.Faces.First();
                    var face      = firstFace;
                    do
                    {
                        hullPoints[i++] = new Point(face.Vertices[0].Position[0], face.Vertices[0].Position[1]);

                        face = face.Adjacency[0];
                    } while (face != firstFace);
                }

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = stopwatch.Elapsed;
                }

                return(hullPoints);
            }));

            AlgoIndexMiConvexHull = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Chan", "Chan, Pat Morin", "C code. Has a little bug (happen rarely). Got on the web.",
                                                  OxyPlot.OxyColors.Red,
                                                  (points, algorithmStat) =>
            {
                Point[] result = null;
                try
                {
                    ConvexHullHeapAndChanWrapper wrapper = new ConvexHullHeapAndChanWrapper(points);
                    wrapper.ChanHull();
                    result = wrapper.HullPoints;

                    if (algorithmStat != null)
                    {
                        algorithmStat.TimeSpanOriginal = wrapper.TimeSpan;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    Debugger.Break();
                }

                return(result);
            }));

            AlgoIndexChan = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "LiuAndChen", "Liu and Chen, Eric Ouellet", "The same as Ouellet without my optimization",
                                                  OxyPlot.OxyColors.LightSkyBlue,
                                                  (points, algorithmStat) =>
            {
                LiuAndChen.ConvexHull convexHull = new LiuAndChen.ConvexHull(points);
                convexHull.CalcConvexHull(LiuAndChen.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexLiuAndChen = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST", "Eric Ouellet, Eric Ouellet", "Highly tested.", OxyPlot.OxyColors.Green,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThread = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array copy)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.Purple,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull = new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.ArrayCopy, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArray = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array C memcpy)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.HotPink,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull =
                    new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.UnsafeCMemCopy, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayMemCpy = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array copy immu)", "Eric Ouellet, Eric Ouellet", "Array instead of a List.",
                                                  OxyPlot.OxyColors.Olive,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArray.ConvexHull convexHull =
                    new OuelletConvexHullArray.ConvexHull(OuelletConvexHullArray.PointArrayManipulationType.ArrayCopyImmutable, points);
                convexHull.CalcConvexHull(OuelletConvexHullArray.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayImmu = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# ST (array memcpy no indirect)", "Eric Ouellet, Eric Ouellet",
                                                  "Array instead of a List.", OxyPlot.OxyColors.Gold,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullArrayNoIndirect.ConvexHull convexHull =
                    new OuelletConvexHullArrayNoIndirect.ConvexHull(OuelletConvexHullArrayNoIndirect.PointArrayManipulationType.ArrayCopyImmutable, points);
                convexHull.CalcConvexHull(OuelletConvexHullArrayNoIndirect.ConvexHullThreadUsage.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullSingleThreadArrayMemCpyNoIndirect = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl", "Eric Ouellet, Eric Ouellet",
                                                  "Same as ST but with Avl Tree instead of List.", OxyPlot.OxyColors.Orange,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl.ConvexHullAvl convexHull = new OuelletConvexHullAvl.ConvexHullAvl(points);
                convexHull.CalcConvexHull(OuelletConvexHullAvl.ConvexHullThreadUsageAvl.OnlyOne);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v2", "Eric Ouellet, Eric Ouellet", "Same as AVL with some optimisation.",
                                                  OxyPlot.OxyColors.Blue,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl2.ConvexHullAvl convexHull = new OuelletConvexHullAvl2.ConvexHullAvl(points);
                convexHull.CalcConvexHull();
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2 = _algorithms.Count - 1;

            // Color c = Colors.
            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v3 (standard/batch)",
                                                  "Eric Ouellet, Eric Ouellet", "Based on Avl v2 with little modifications and additional online methods.", OxyPlot.OxyColors.DarkCyan,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl3.ConvexHull convexHull = new OuelletConvexHullAvl3.ConvexHull();
                convexHull.CalcConvexHull(points);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2Online = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# Avl v3 (one by one in a loop)", "Eric Ouellet, Eric Ouellet",
                                                  "Based on Avl v2 with little modifications and additional online methods.", OxyPlot.OxyColors.DarkOrchid,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHullAvl3.ConvexHull convexHull = new OuelletConvexHullAvl3.ConvexHull();

                // TEST to ensure that IsHullPoint and DynamicallyAddAnotherPointToConvexHullIfAppropriate appears to be coherent and works fine.
                //foreach (Point pt in points)
                //{
                //	Point[] ptsBefore = convexHullOnline.GetResultsAsArrayOfPoint();
                //	int countBefore = convexHullOnline.Count;
                //	int t = convexHullOnline.IsHullPoint(pt);
                //	int r = convexHullOnline.DynamicallyAddAnotherPointToConvexHullIfAppropriate(pt);
                //	Point[] ptsAfter = convexHullOnline.GetResultsAsArrayOfPoint();

                //	Debug.Assert(t == r);

                //	DifferencesInPath diffs = ConvexHullUtil.GetPathDifferences("", points, ptsAfter, ptsBefore);
                //	if (r == 1)
                //	{
                //		Debug.Assert(diffs.HasErrors);
                //	}
                //	else
                //	{
                //		Debug.Assert(! diffs.HasErrors);
                //	}
                //}

                foreach (Point pt in points)
                {
                    convexHull.TryAddOnePoint(pt);
                }

                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2OnlineWithOnlineUse = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# 4T", "Eric Ouellet, Eric Ouellet", "1 thread per quadrant for part 2",
                                                  OxyPlot.OxyColors.SlateBlue,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.FixedFour);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHull4Threads = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet C# MT", "Eric Ouellet, Eric Ouellet",
                                                  "All thread part 1, 4 threads part 2, 1 thread part 3", OxyPlot.OxyColors.SaddleBrown,
                                                  (points, algorithmStat) =>
            {
                OuelletConvexHull.ConvexHull convexHull = new OuelletConvexHull.ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.All);
                return(convexHull.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullMultiThreads = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.ConvexHull, "Ouellet CPP ST", "Eric Ouellet, Eric Ouellet", " thread, highly optimized, very ugly code",
                                                  OxyPlot.OxyColors.YellowGreen,
                                                  (points, algorithmStat) =>
            {
                double elapsedTime = 0;

                OuelletConvexHullCpp convexHull = new OuelletConvexHullCpp();
                var result = convexHull.OuelletHullManagedWithElapsedTime(points, true, ref elapsedTime);

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanOriginal = TimeSpanHelper.MoreAccurateTimeSpanFromSeconds(elapsedTime);
                }

                return(result);
            }));

            AlgoIndexOuelletConvexHullCpp = _algorithms.Count - 1;

            // Color r = Colors.CornflowerBlue;
            _algorithms.Add(new AlgorithmOnline(AlgorithmType.ConvexHullOnline, "Ouellet C# Avl v3 (** Only for Online performance test)", "Eric Ouellet, Eric Ouellet",
                                                "Add point one by one for 'merging' performance test only.", OxyPlot.OxyColors.CornflowerBlue, () =>
            {
                return(new OuelletConvexHullAvl3.ConvexHull());
            },

                                                (Object obj, Point pt, AlgorithmStat stat) =>
            {
                var convexHullOnline = obj as OuelletConvexHullAvl3.ConvexHull;
                if (convexHullOnline == null)
                {
                    throw new ArgumentException($"argument obj: '{obj}' is invalid.");
                }

                Stopwatch stopwatch        = Stopwatch.StartNew();
                EnumConvexHullPoint result = convexHullOnline.TryAddOnePoint(pt);
                stopwatch.Stop();

                stat.TimeSpanCSharp = stat.TimeSpanCSharp.Add(stopwatch.Elapsed);

                return(result == EnumConvexHullPoint.ConvexHullPoint);
            },

                                                (Object obj) =>
            {
                var ch = obj as OuelletConvexHullAvl3.ConvexHull;
                if (ch == null)
                {
                    throw new ArgumentException($"argument obj: '{obj}' is invalid.");
                }
                return(ch.GetResultsAsArrayOfPoint());
            }));

            AlgoIndexOuelletConvexHullAvl2OnlineWithOnlineInterface = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.SmallestEnclosingCircle, "Smallest Enclosing Circle", "Rod Stephens, Rod Stephens",
                                                  "Slow Slow Slow. Select max 500 pts.", OxyPlot.OxyColors.Red,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();

                Point center  = new Point(0, 0);
                double radius = 0;
                SmallestEnclosingCircle.FindMinimalBoundingCircle(points, out center, out radius);

                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanCSharp = stopwatch.Elapsed;
                }

                Point[] result = CircleHelper.CreateCircleWithPoints(center, radius, 200);                         // 200 seems ok :-)

                return(result);
            }));

            AlgoIndexSmallestEnclosingCircle = _algorithms.Count - 1;

            _algorithms.Add(new AlgorithmStandard(AlgorithmType.SmallestEnclosingCircle, "Smallest Enclosing Circle from ConvexHull (Ouellet ST)",
                                                  "Rod Stephens, Rod Stephens", "Same algo as previous but points are first filtered by the Convex Hull algo", OxyPlot.OxyColors.Blue,
                                                  (points, algorithmStat) =>
            {
                var stopwatch = Stopwatch.StartNew();


                ConvexHull convexHull = new ConvexHull(points);
                convexHull.CalcConvexHull(ConvexHullThreadUsage.OnlyOne);
                Point[] hullPoints = convexHull.GetResultsAsArrayOfPoint();


                Point center  = new Point(0, 0);
                double radius = 0;
                SmallestEnclosingCircle.FindMinimalBoundingCircle(hullPoints, out center, out radius);

                stopwatch.Stop();

                if (algorithmStat != null)
                {
                    algorithmStat.TimeSpanCSharp = stopwatch.Elapsed;
                }

                Point[] result = CircleHelper.CreateCircleWithPoints(center, radius, 200);                         // 200 seems ok :-)

                return(result);
            }));

            AlgoIndexSmallestEnclosingCircle = _algorithms.Count - 1;
        }
Ejemplo n.º 16
0
        public static void ComputeMinEnclosingCircle(ObjectId[] idArray, CoordinateSystem actualCS)
        {
            Editor        editor          = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
            Database      workingDatabase = HostApplicationServices.WorkingDatabase;
            ProgressMeter progressMeter   = new ProgressMeter();
            MessageFilter value           = new MessageFilter();

            System.Windows.Forms.Application.AddMessageFilter(value);
            try
            {
                using (Transaction transaction = workingDatabase.TransactionManager.StartTransaction())
                {
                    progressMeter.SetLimit(idArray.Length);
                    if ((double)idArray.Length > 10000.0)
                    {
                        progressMeter.Start("Computing min. enclosing circle...");
                    }
                    CoordinateTransformator coordinateTransformator = new CoordinateTransformator(CoordinateSystem.Global(), actualCS);
                    CoordinateTransformator inverseTransformation   = coordinateTransformator.GetInverseTransformation();
                    BlockTable       blockTable       = (BlockTable)transaction.GetObject(workingDatabase.BlockTableId, (OpenMode)1);
                    BlockTableRecord blockTableRecord = (BlockTableRecord)transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], (OpenMode)1);
                    ObjectId         layerId          = DBManager.CurrentLayerId();
                    DBManager.CurrentLayerName();
                    PointSet pointSet = new PointSet();
                    for (int i = 0; i < idArray.Length; i++)
                    {
                        progressMeter.MeterProgress();
                        DBPoint dBPoint = (DBPoint)transaction.GetObject(idArray[i], (OpenMode)0, true);
                        Point   point   = new Point(dBPoint.Position.X, dBPoint.Position.Y, dBPoint.Position.Z);
                        coordinateTransformator.Transform(point);
                        pointSet.Add(point);
                    }
                    ConvexHull2d convexHull2d = new ConvexHull2d();
                    convexHull2d.InitialPoints = pointSet;
                    convexHull2d.ComputeHull();
                    PointSet vertices = convexHull2d.Vertices;
                    double   z        = vertices[0].Z;
                    for (int j = 0; j < vertices.Count; j++)
                    {
                        vertices[j].Z = z;
                    }
                    SmallestEnclosingCircle         smallestEnclosingCircle = new SmallestEnclosingCircle(vertices);
                    ngeometry.VectorGeometry.Circle circle = smallestEnclosingCircle.ComputeCircle();
                    Point center = circle.Center;
                    Point point2 = circle.NormalVector.ToPoint();
                    inverseTransformation.Transform(center);
                    inverseTransformation.Transform(point2);
                    Autodesk.AutoCAD.DatabaseServices.Circle circle2 = new Autodesk.AutoCAD.DatabaseServices.Circle(new Autodesk.AutoCAD.Geometry.Point3d(center.X, center.Y, center.Z), new Autodesk.AutoCAD.Geometry.Vector3d(point2.X, point2.Y, point2.Z), circle.Radius);
                    circle2.LayerId = (layerId);
                    blockTableRecord.AppendEntity(circle2);
                    transaction.AddNewlyCreatedDBObject(circle2, true);
                    editor.WriteMessage("\nMinimum enclosing circle properties:");
                    editor.WriteMessage("\n------------------------------------");
                    editor.WriteMessage("\nRadius          : " + circle.Radius.ToString(DBManager.GetFormatFromLUPREC()));
                    editor.WriteMessage("\nArea            : " + circle.Area.ToString(DBManager.GetFormatFromLUPREC()));
                    editor.WriteMessage("\nPerimeter length: " + circle.Circumference.ToString(DBManager.GetFormatFromLUPREC()));
                    transaction.Commit();
                }
                progressMeter.Stop();
            }
            catch (System.Exception ex)
            {
                progressMeter.Stop();
                throw;
            }
        }