确定点阵列是否大致形成一个圆圈

时间:2018-05-04 12:07:01

标签: java geometry

我和我的朋友花了一两个小时在java中创建代码,以查找由x[]x坐标)和y[]表示的点数组(对于{ {1}}坐标)大致形成一个圆圈。

我们已经做了很多研究,但每次我们最终都在3个变量中求解非常大的联立方程。

我们在想的是先取3个阵列并找到这3个点的中心(环绕中心),然后我们可以找到这3个点所形成的圆的半径,如果其他点也满足距离形成中心大致等于半径然后我们有一个圆圈。

我们怎么做?

3 个答案:

答案 0 :(得分:2)

  

"我们怎么做?"

基本上,通过做一些数学。

假设你有P点 1 到P n

  1. 选择一对P 1 和P 2
  2. 找到点P 1 和P 2 之间的线L 1 的中点M 1
  3. 构造另一条线R 1 ,与L 1 成直角,通过M 1
  4. 对点P 2 和P 3 重复步骤1到3,为您提供第二行R 2
  5. 找到R 1 和R 2 的交点。那是圆圈的候选中心C.
  6. 对于每个点P i ,计算从C到P i 的距离。
  7. 如果你的分数是"大致"在一个圆圈中,从每个点到中心的距离将大致为"同样的。

    步骤1到6可以转换为具有一些简单代数的分析公式。计算出公式,然后将它们变成代码。

答案 1 :(得分:0)

这是一个潜在的O(n)解决方案,我认为有效。它使用简单的2D圆方程:x^2 + y^2 = r^2。我实际上没有对它进行过测试,所以请加上一粒盐。

此外,您还没有在问题中列出所有假设。 xy之间的关系是一对一的吗?元素的顺序怎么样?它们的长度是一样的吗? 大致意味着什么?

假设xy是具有有序一对一映射的相同长度的整数数组,您可以遍历xy并创建一个新的具有x^2 + y^2值的数组。我们称这个新数组为r2

现在是我必须定义“粗略”的时间。假设r2的所有值都等于delta = 10的可接受偏移量,我们有一个圆圈。您可以为delta选择任意值以适合您对粗略圆圈的定义。

在伪代码中,它看起来像这样:

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)

如果你愿意,你可以使用贪婪的方法组合两个循环。

祝你好运!

答案 2 :(得分:0)

所以我在Python中玩游戏(因为我最简单的方法是快速对解决方案进行原型设计)并提出了这个问题:

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

假设:

  1. 最好计算所有点的中心,而不仅仅是前3个。如果输入的第一个点位于几何中心,则不是最优的,而是处理大小写。
  2. 椭圆和省略号不是一个大致的圆圈&#39;
  3. 如何&#39;粗糙&#39;可以使用置信度参数[0,1)
  4. 设置圆圈

    算法:

    1. 计算所有点的平均值(中心)
    2. 计算所有点的中心距离
    3. 将距离标准化为范围[0,1]
    4. 规范化向量中的所有值是否大于0.9?
    5. 如果是这样,这组点是一个置信度为0.1的圆圈。