【问题标题】:javascript algorithm: Check x/y-points to get if component is a circle or notjavascript算法:检查x / y点以获取组件是否为圆形
【发布时间】:2026-02-11 14:45:01
【问题描述】:

我有一个这样的矩阵,希望你能得到圆的轮廓:

编辑 1:轮廓呢?轮廓不包含空格(因此每个 y 值至少有 2 个 x 值)

编辑 2:什么是圆? 搜索更多或更少的“精确圆”,如下例所示! (每个点的半径几乎相同)

    00000000000000000000000000000000
    00000000000001111111100000000000
    00000000000100000000010000000000
    00000000010000000000000100000000
    00000000100000000000000010000000
    00000000100000000000000010000000
    00000001000000000000000001000000
    00000010000000000000000000100000
    00000010000000000000000000100000
    00000010000000000000000000100000
    00000100000000000000000000100000
    00000100000000000000000000100000
    00000100000000000000000000100000
    00000100000000000000000000100000
    00000100000000000000000000100000
    00000010000000000000000000100000
    00000010000000000000000000100000
    00000010000000000000000001000000
    00000001000000000000000010000000
    00000000100000000000000010000000
    00000000100000000000000100000000
    00000000010000000000001000000000
    00000000000111111111100000000000
    00000000000000000000000000000000
    00000000000000000000000000000000

我也有一个这样的数组,包括大纲的所有位置:

var coordinates = [
  [13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],
  [11,2],[21,2],
  [9,3],[23,3],
  [8,4],[24,4],
  [8,5],[24,5],
  [7,6],[25,6],
  [6,7],[26,7],
  [6,8],[26,8],
  [6,9],[26,9],
  [5,10],[26,10],
  [5,11],[26,11],
  [5,12],[26,12],
  [5,13],[26,13],
  [5,14],[26,14],
  [6,15],[26,15],
  [6,16],[26,16],
  [6,17],[25,17],
  [7,18],[24,18],
  [8,19],[24,19],
  [8,20],[23,20],
  [9,21],[22,21],
  [11,22],[12,22],[13,22],[14,22],[15,22],[16,22],[17,22],[18,22],[19,22],[20,22]]

检查坐标是否匹配为圆的好方法是什么?

我的第一个想法是使用这样的代码,但我确信有一种更有效和更有效的方法:

var circle = [[13,1],[14,1],[15,1],[16,1],[17,1],[18,1],[19,1],[20,1],[11,2],[21,2],[9,3],[23,3],[8,4],[24,4],[8,5],[24,5],[7,6],[25,6],[6,7],[26,7],[6,8],[26,8],[6,9],[26,9],[5,10],[26,10],[5,11],[26,11],[5,12],[26,12],[5,13],[26,13],[5,14],[26,14],[6,15],[26,15],[6,16],[26,16],[6,17],[25,17],[7,18],[24,18],[8,19],[24,19],[8,20],[23,20],[9,21],[22,21],[11,22],[12,22],[13,22],[14,22],[15,22],[16,22],[17,22],[18,22],[19,22],[20,22]]

var no_circle= [[13,1],[14,1],[25,4]]


Array.prototype.is_circle = function() {
var min = {
	'x': Infinity,
	'y': Infinity
};
var max = {
	'x': 0,
	'y': 0
};
var center = {
	'x': 0,
	'y': 0
};
var radius;
this.forEach(function(a) {
  a[0] = a[0]
  a[1] = a[1]
	if (a[0] > max.x) max.x = a[0];
	if (a[0] < min.x) min.x = a[0];
	if (a[1] > max.y) max.y = a[1];
	if (a[1] < min.y) min.y = a[1];
});
center.x = (max.x + min.x) / 2;
center.y = (max.y + min.y) / 2;
radius = []
radius[0] = max.x - center.x
radius[1] = center.x - min.x
radius[2] = center.y - min.y
radius[3] = max.y - center.y
    
r = (radius[0] + radius[1] + radius[2] + radius[3]) / 4;
    
if ((radius[0] > r-1 && radius[0] < r+1) && (radius[1] > r-1 && radius[1] < r+1) && (radius[2] > r-1 && radius[2] < r+1) && (radius[3] > r-1 && radius[3] < r+1)) return true;
    
   return false

}

var result1 = circle.is_circle();
console.log(result1)


var result2 = no_circle.is_circle();
console.log(result2)

【问题讨论】:

  • 计算机不像人类那样处理“或多或少精确”。除非您想深入研究机器学习解决方案,否则您需要通过算法定义这意味着什么。
  • 取最左/右上/下的中间位置,就完成了。
  • 为了什么??如果组件是一个圆圈或其他什么,我不会得到信息,我只会知道中心点。所以例如它也可以是一个正方形,...@JonasW。
  • @JonasW。如果我理解正确,您的评论没有多大意义,而且过于简单化了
  • 您可以尝试将一个圆(参见例如here)拟合到轮廓,并使用拟合残差来衡量您的形状有多“圆”。

标签: javascript algorithm math matrix coordinates


【解决方案1】:

您的算法似乎只检查 X 轴和 Y 轴上最远的四个点。我想如果你提供代表正方形的点,它也会通过is_circle 测试。

我建议您使用称为e 的一些额外的圆度余量进行两阶段测试。遍历整个点并记住x_min, y_min, x_maxy_max。然后检查 X 的 delta 和 Y 的 delta 之间的差异是否在误差范围内,即abs((x_max-x_min) - (y_max-y_min)) &lt;= e。这会检查形状的方形,使其可以是圆形,而不是椭圆形。如果该测试通过,则在(x_c, y_c) = (x_min+(x_max-x_min)/2, y_min+(y_max-y_min)/2) 处计算中心点c,并为每个点计算半径(从任何点到中心c 的距离)是否在误差范围e 内。为了节省昂贵的计算,请检查每个点的平方半径是否在误差范围内,即是否​​abs((x-x_c)^2 + (y-y_c)^2 - r^2) &lt;= e,其中r^2 是针对中心c 和列表中的第一个点计算的。

【讨论】:

  • 匿名用户投票?写简短的评论会伤害吗?