4

I have many points . What is the best way to find the center and the radius of the minimum radius circle that contains all the points given.

I guess that after i find the proper center the radius will be equal to the distance of the more far away point but how can i find the center?

Any algorithm/ pseudo code would be really useful.

weakwire
  • 9,284
  • 8
  • 53
  • 78
  • Not sure if this will work, but if you can do a transformation of the problem onto a set of linear equations, you can then use the standard least-squares regression algorithms. – Mysticial Sep 16 '11 at 00:15
  • Your title and text don't seem quite clear whether you want the circle to encircle all the points or to have all the points as lying on the circumference - could you clarify? – Aesin Sep 16 '11 at 00:18
  • 4
    See also [Smallest circle problem](http://en.wikipedia.org/wiki/Smallest_circle_problem). – trashgod Sep 16 '11 at 00:23
  • @Aesin i have X points that are not necessarily at the "edge" of the circle. So i just want the circle to cover all the points but with the most distanced point to be at the circle's "edge" (Minimum circle) – weakwire Sep 16 '11 at 00:23
  • @Mysticial i don't think that is the optimal way. Also a nice working algorithm can be produced without .. you know all that math stuff:P – weakwire Sep 16 '11 at 00:27
  • 1
    Related: http://stackoverflow.com/questions/1768197/bounding-ellipse – finnw Sep 18 '11 at 17:20
  • Finding the exact bounding circle is possible ([example](http://lab.polygonal.de/2007/02/17/bounding-circle-computation/), though this is not the most efficient implementation). The math behind the bounding *ellipse* problem is a lot more complicated, and finding an exact solution is not possible; it's more of an optimisation thing. – Jean-François Corbett Sep 22 '11 at 09:03

4 Answers4

3

CGAL provides such an algorithm. See here, but this is in C++. If you need it in java, you can write a simple wrapper using SWIG for example.

sloriot
  • 6,070
  • 18
  • 27
0

You can reduce the problem to finding the "widest" axis of your cloud of points. This will be a diameter of your smallest circle. Any smaller circle couldn't possibly enclose the extremal points that define this diameter.

An inefficient algorithm to accomplish this begins by looping over angles ɵ from 0 to 45 degrees. For each angle ɵ, transform the coordinates of every point by rotating the coordinate system by ɵ. Then simply find max(x)-min(x) and max(y)-min(y) to find the maximum extent for this rotation. Continue to find the maximum extent for all rotations.

Here is a C program which implements this simple algorithm, returning the length of the minimum diameter:

To adapt this code to your particular problem, add this code at the end:

 /* parameters of smallest circle enclosing the points */
 double center_x = (x[max_i]+x[min_i])/2;
 double center_y = (y[max_i]+y[min_i])/2;
 double radius = sqrt( (x[max_i]-x[min_i])*(x[max_i]-x[min_i]) +
                       (y[max_i]-y[min_i])*(y[max_i]-y[min_i])))/2;

There is doubtlessly a more efficient approach (for instance: first find the convex hull, and then consider only those points defining the hull), but this might suffice if the number of points is not astronomical.

nibot
  • 14,428
  • 8
  • 54
  • 58
-1

Just take the mean of each component of each point vector as your centre, so the vector to your centre is (average_of_all_the_x, average_of_all_the_y), then, as you say, set the circumference as going through the most distant point.

Aesin
  • 341
  • 2
  • 7
  • What about determining the most distant object? Is there any way to know that when i figure out the center? I don't want to circle to all the points again to find the most distanced one after i find the center – weakwire Sep 16 '11 at 00:21
  • 2
    I don't think this will work. Allow me to introduce a counter example. Let X1=(0,-1), X2=(0,1), x3=(0.1,sqrt(0.99)). Then the average would be (0,sqrt(0.99)/3) or about (0,0.331662479). The radius would have to be 1+sqrt(0.99) to include X1 - the farthest point. However a circle centered at (0,0) with radius 1 would include all points. – emory Sep 16 '11 at 00:28
  • You're quite right, this isn't a good algorithm - I should have thought about it more, sorry. The link @trashgod gave to the main question gives a good algorithm though, and there's some more discussion and some pseudocode here: http://www.sunshine2k.de/stuff/Java/Welzl/Welzl.html – Aesin Sep 16 '11 at 00:33
-1

Ty for the answers the way i did it was like that.

float minX = Float.MAX_VALUE;
            float maxX = Float.MIN_VALUE;
            float minY = Float.MAX_VALUE;
            float maxY = Float.MIN_VALUE;

            for (int i = 0; i < item.slaves.size(); i++) {
                OverlayItemExtended slaveItem = item.slaves.get(i);
                GeoPoint slavePoint = slaveItem.getPoint();
                Point slavePtScreenCoord = new Point();

                mapView.getProjection()
                    .toPixels(slavePoint, slavePtScreenCoord);

                float x = slavePtScreenCoord.x;
                float y = slavePtScreenCoord.y;

                maxX = Math.max(x, maxX);
                minX = Math.min(x, minX);
                maxY = Math.max(y, maxY);
                minY = Math.min(y, minY);

            }
            float centerX = (maxX + minX) / 2;
            float centerY = (maxY + minY) / 2;
            double distance = findDistance(minX, minY, maxX, maxY);         
            Paint linePaint = new Paint();
            linePaint.setColor(android.graphics.Color.RED);
            linePaint.setStyle(Paint.Style.FILL);
            linePaint.setAlpha(35);

            canvas.drawCircle(centerX, centerY, (float) (distance / 2) + 10,
                    linePaint);
}
weakwire
  • 9,284
  • 8
  • 53
  • 78
  • 1
    I don't understand this algorithm. As far as I can tell maxX, maxY, minx, and minY have no relation with the i in the for loop. Thus centerX and centerY have no relation with the input points. So the code will always produce the same circle - regardless of the input points, unless I am missing something. – emory Sep 16 '11 at 21:14
  • @emory You are correct. Just posted the correct code slavePtScreenCoordXY comes from the projection to the map of some points (in the for loop) – weakwire Sep 16 '11 at 21:42
  • I think it is wrong. Let X1=(-1,0); X2=(0,1); and X3=(1,0). Clearly the unit circle (centered at (0,0) with radius 1) would cover these circle. But this method would produce a circle centered at (0,0.5). Such a circle would need a radius of at least sqrt(1.25) to cover X1, X2, and X3. My suggestion is to use the algorithm that trashgod suggested. – emory Sep 16 '11 at 23:27