1

我有一些按顺序排列的点,由用户绘制。

我想在这些点之间找到重要的点。正如我所定义的,重要的一点是我们点的方向突然改变的点。例如,手工绘制的“Z”,必须有两个重点。

我尝试计算相邻点之间的角度,但这并没有给我想要的结果。计算斜率的变化是一样的。

也许我需要以某种方式优化角度寻找,但我不知道。任何的想法?

编辑:这是比较角度的Java代码:

int nBreakPoints = 0;
double nextangle = 0;
double nextr;
double r = Math.sqrt(Math.pow(points[1].x-points[0].x, 2) 
    + Math.pow(points[1].y-points[0].y, 2));
double angle = Math.asin((points[1].y-points[0].y) / r)*180/Math.PI; 
double cumR = r;
int firstI = 0;
for(int i=1; i<points.length-2 ;i++)
{
    nextr = (int) Math.sqrt(Math.pow(points[i].x-points[i+1].x, 2) 
        + Math.pow(points[i+1].y-points[i].y, 2));
    cumR += nextr;
    if(cumR < 20 || cumR==0) continue;
    nextangle = Math.asin((points[i].y-points[firstI].y) / cumR)*180/Math.PI;
    if(Math.abs(angle-nextangle) >= 20) nBreakPoints++;
    r = nextr;
    angle = nextangle;
    cumR = 0;
    firstI = i;
}

好的,它只是计算两点之间的角度,如果它们不是 20 度,我们就有了一个新的重要点。

只是要注意,cumRfirstI添加以防止“太近”的点被带入计算。

4

1 回答 1

1

如果角度翻转 360°,您的角度计算可能会失败。例如,一个角度是 179°,下一个角度是 -179°。绝对差异很大,但角度非常接近。

这是一个更强大的方法:

pp = points[i - 1] //the preceding point; if it exists
p = points[i]
pn = points[i + 1] //the next point; if it exists
dp = [p.x - pp.x, p.y - pp.y] //direction of incoming line
dn = [pn.x - p.x, pn.y - p.y] //direction of outgoing line
r = Math.sqrt((dp.x * dp.x + dp.y * dp.y) * (dn.x * dn.x + dn.y * dn.y)) //product of vector lengths
cos = (dp.x * dn.x + dp.y * dn.y) / r //cosine of angle
angle = Math.acos(cos) * 180 / Math.PI;
if(angle > 20)
    ...

如果这些点彼此非常靠近并且容易受到噪音影响,那么考虑更大范围而不是相邻点可能是合理的:

pp = points[i - n]
p = points[i]
pn = points[i + n]

n可以是一个常数,您可以根据应用程序进行选择。您还可以查找与当前点有一定距离的下一个点:

for(int j = i - 1; j >= 0; --j)
{
    dp = [p.x - points[j].x, p.y - points[j].y]
    rp = dp.x * dp.x + dp.y * dp.y;
    if(rp > square_threshold)
        break;
}

...下一点也是如此。

于 2013-08-09T09:19:38.630 回答