3

Me and my friend spent an hour or two in making a code in java to find whether an array of points represented by x[] (for x coordinates) and y[] (for y coordinates) roughly form a circle or not.

We have done a lot of research but every time we end up solving very large simultaneous equations in 3 variables.

What we were thinking is to take first 3 points of the array and find the center (circum centre) of these 3 points then we can find the radius of the circle made by these 3 points and if other points also satisfy the distance form the center is roughly equal to radius then we have a circle.

How can we do this?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
quadgen
  • 80
  • 8
  • Sorry for the english – quadgen May 04 '18 at 12:09
  • 1
    What you were thinking seems about right. What is your problem then? – Rafalon May 04 '18 at 12:10
  • I was unable to implement this in programming ending up in very weird equations. – quadgen May 04 '18 at 12:11
  • 2
    Its ok guys please come to main topic – quadgen May 04 '18 at 12:12
  • 2
    @quadgen so you say you were unable to implement this in programming. Why? What's the blocking point? Is it that you can't find the center of a circle going through 3 points? – Rafalon May 04 '18 at 12:13
  • I too think that the suggested algorithm is mostly right, but how do we define **roughly**? Do we ignore outliers? (eg. 1000 points in a perfect circle and one in the center - is it roughly a circle? What if the center point is the first in the array?) What about the area of confidence? Are ovals roughly circles? – Marcin Natanek May 04 '18 at 12:14
  • [This might help you](https://stackoverflow.com/a/9064745/7540393) – Arthur Attout May 04 '18 at 12:39

3 Answers3

2

"How can we do this?"

Basically, by doing a bit of maths.

Assume you have N points P1 through Pn.

  1. Pick a pair of points P1 and P2.
  2. Find the midpoint M1 of the line L1 between the points P1 and P2.
  3. Construct another line R1 at right-angles to L1 passing through M1.
  4. Repeat steps 1 through 3 for points P2 and P3 to give you a second line R2.
  5. Find the point of intersection of R1 and R2. That is the candidate center C of the circle.
  6. For each point Pi, calculate the distance from C to Pi.

If your points are "roughly" in a circle, then distances from each point to the center will be "roughly" the same.

Steps 1 through 6 can be turned into analytic formulae with some simple algebra. Work out the formulae, then turn them into code.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • This is absolutely brilliant! So Straight forward. Absolutely freaking genius! I love it. I'm just geeking out about the whole bit where a perpendicular line crossing through the midpoint of an arc will also pass through the center of the circle. The only problem is that you could get some false positives given that the data could be "nearly" circular, where R lines don't intersect or intersect on the wrong side. A high number of points and running an O(n^2) algorithm might increase certainty though. – TheCrzyMan May 04 '18 at 12:55
  • If you pick 3 points that are not close together, then they should intersect at the approximate centre. The last step tests the hypothesis that the points *are* in a circle ... roughly. – Stephen C May 04 '18 at 13:00
0

This is a potential O(n) solution that I believe works. It uses the simple 2D circle equation: x^2 + y^2 = r^2. I haven’t actually tested it, so take it with a grain of salt.

Also, you haven’t laid out all the assumptions in your problem. Is the relationship between x and y one-to-one? What about the order of elements? Are they of the same length? What does roughly mean?

Assuming that x and y are integer arrays of same length with ordered one-to-one mapping, you can loop through x and y and make a new array with x^2 + y^2 values. Let’s call this new array r2.

Now is the time I have to define “roughly”. Let’s suppose if all the values of r2 are equal with an acceptable offset of delta = 10, we have a circle. You can choose any arbitrary value for delta to fit your definition of a rough circle.

In pseudocode, it will look like this:

delta = 10;
r2 = [];
for i = 0 to length(x) {
    r2.append(x[i] * x[i] + y[i] * y[i]);
}

random_r2_value = r2(randomInt(0, length(r2));
upper_bound = random_r2_value + delta;
lower_bound = random_r2_value - delta;

isCircle = true;

for value in r2 {
    if value >= lower_bound && value <= upper_bound {
    // yay
    continue;
    } else {
        isCircle = false;
        break;
    }
}

print(isCircle)

And you can combine the two loops using a greedy method if you wanted to.

Good luck!

happy_sisyphus
  • 1,693
  • 1
  • 18
  • 27
0

So I played around in Python (just cause it is easiest for me to quickly prototype the solution) and came up with this:

from collections import namedtuple
from math import sqrt
from statistics import mean

Point = namedtuple('Point', ['x', 'y'])

def length_between_points(a: Point, b: Point):
    squared = (pow(a.x - b.x, 2) + pow(a.y - b.y, 2))
    return sqrt(squared)

def normalize(raw):
    return [float(i)/max(raw) for i in raw]

def is_roughly_circle(x, y, confidence=0.1):
    center = Point(x=mean(x), y=mean(y))
    points = [Point(x[i], y[i]) for i in range(len(x))]

    lengths_from_center = [length_between_points(p, center) for p in points]
    normalized = normalize(lengths_from_center)
    is_circle = all([length > 1 - confidence for length in normalized])
    return is_circle


x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
print(is_roughly_circle(x, y)) # False

x = [0, 1, 0, -1]
y = [1, 0, -1, 0]
print(is_roughly_circle(x, y)) # True

x = [0, 1.1, 0, -1]
y = [1, 0, -1, 0]
print(is_roughly_circle(x, y)) # True

x = [0, 1.2, 0, -1]
y = [1, 0, -1, 0]
print(is_roughly_circle(x, y)) # False

x = [0, 1.2, 0, -1]
y = [1, 0, -1, 0]
print(is_roughly_circle(x, y, confidence=0.2)) # True

Assumptions:

  1. It is better to calculate center of all points, not only the first 3. It is not the most optimal, but handles the case, if the first point from input is in the geometrical center.
  2. Ovals and ellipsis are not a 'roughly circle'
  3. How 'Rough' the circle can be could be set with confidence parameter [0,1)

Algorithm:

  1. Calculate the mean of all the points (center)
  2. Calculate distance from the center for all the points
  3. Normalize the distances to the range [0,1]
  4. Are all values in the normalized vector greater than 0.9?
  5. If so, the set of points is a circle with confidence of 0.1.
Marcin Natanek
  • 576
  • 3
  • 11