我正在尝试诊断并修复一个错误,该错误归结为当 X 和 Y 很小时,X/Y 会产生不稳定的结果:
在这种情况下,cx和patharea都平滑增加。它们的比率在大数时是平滑的渐近线,但在“小”数时是不稳定的。显而易见的第一个想法是我们已经达到了浮点精度的极限,但实际数字本身还远远没有接近它。 ActionScript“数字”类型是 IEE 754 双精度浮点数,因此应该具有 15 位十进制数字的精度(如果我没读错的话)。
分母(路径面积)的一些典型值:
0.0000000002119123
0.0000000002137313
0.0000000002137313
0.0000000002155502
0.0000000002182787
0.0000000002200977
0.0000000002210072
和分子 (cx):
0.0000000922932995
0.0000000930474444
0.0000000930582124
0.0000000938123574
0.0000000950458711
0.0000000958000159
0.0000000962901528
0.0000000970442977
0.0000000977984426
其中每一个都单调增加,但如上所示,比率是混乱的。
当数字较大时,它会趋于平滑的双曲线。
所以,我的问题是:当您需要将一个数字除以另一个数字时,处理非常小的数字的正确方法是什么?
我想过提前将分子和/或分母乘以 1000,但无法完全解决。
有问题的实际代码是recalculate()
功能here https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/WayUI.as。它计算多边形的质心,但当多边形很小时,质心会在该位置周围不规则地跳跃,并且最终可能与多边形相距很远。上面的数据系列是沿一致方向移动多边形的一个节点的结果(用手,这就是它不完全平滑的原因)。
这是 Adobe Flex 4.5。
我认为问题很可能是由代码中的以下行引起的:
sc = (lx*latp-lon*ly)*paint.map.scalefactor;
如果你的多边形非常小,那么lx
and lon
几乎相同,因为ly
and latp
。与结果相比,它们都非常大,因此您要减去两个几乎相等的数字。
为了解决这个问题,我们可以利用以下事实:
x1*y2-x2*y1 = (x2+(x1-x2))*y2 - x2*(y2+(y1-y2))
= x2*y2 + (x1-x2)*y2 - x2*y2 - x2*(y2-y1)
= (x1-x2)*y2 - x2*(y2-y1)
所以,试试这个:
dlon = lx - lon
dlat = ly - latp
sc = (dlon*latp-lon*dlat)*paint.map.scalefactor;
该值在数学上是相同的,但项要小一个数量级,因此误差也应该小一个数量级。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)