我有一些点,按顺序排列,由用户绘制。
我想在这些要点之间找到重点。重要的是,正如我所定义的那样,我们突然改变了点的方向。例如,手工绘制的'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度,我们有一个新的重点。
请注意,我们会添加cumR
和firstI
,以防止“太近”的点进入计算。
答案 0 :(得分: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;
}
......下一点也一样。