Javascript 怎么能把一个圆平均分到 1,000,000,000% 缩放呢?

How can Javascript be used to divide a circle equally so that it's correct to 1,000,000,000% zoom?

分离自:

使用浮点精度计算圆上的点位置时存在舍入误差

示例:

function pointsOnACircle (whichpoint, numberOfPoints, cx, cy, radius) {
    //Returns a point along the outside of a circle, starting at (whichpoint=1) = 0 degrees

    eachpoint = whichpoint * 2 * Math.PI /numberOfPoints;
    var thiscx = cx + (radius * Math.sin(eachpoint));
    var thiscy = cy - (radius * Math.cos(eachpoint));

    thisPoint = [ thiscx, thiscy ];

    return thisPoint;
}

如果函数是运行 as fourthPointofSix = pointsOnACircle (4, 6, 126, 126, 63); 那么返回的点数是

0: 71.44039956158039 1: 157.50000000000003

http://www.ttmath.org/online_calculator处的计算器计算,数字应该是:

0: 71.440399561580365.. 1: 157.5

同样,如果我们运行 fifthPointofSix = pointsOnACircle (5, 6, 126, 126, 63); 那么返回的点数是:

0: 71.44039956158034 1: 94.50000000000004

他们应该是:

0: 71.440399561580365... 1: 94.5

注意:点4和点5的x应该是一样的,但是返回的不一样

是否有解决这些基于圆的精确计算的标准解决方案?

很有可能需要非常大的变焦。其中一个例子是交互式分形图。对于这种应用程序,您不想缩放静态对象,您需要一个动态解决方案,在该解决方案中重新计算对象,以便精度适合比例因子。例如在这个程序中 Scalable circle 你可以缩放到任何你想要的级别。此解决方案使用圆方程 (x-1)^2 + y^2 = 1 的隐式版本。

如果我们看一下数字的精度 IEEE floating point double 给我们 15-16 位十进制数字的浮点精度。这对于 1e7 = 1,000,000,000% 缩放应该没问题。 Math.sin() 和 Math.cos() 精确到最后一个二进制数字。

取问题中的值并减去实际值 71.44039956158039 - 71.440399561580365 = 2.842170943040401e-14 现在将其乘以比例因子 1e7 得到 2.842170943040401e-7 误差小于百万分之一像素。 (我使用 chrome javascript 控制台进行计算)。

如果这里的比例因子是 1e14,我们可能会开始遇到问题,错误是 2.8421709430404007 几个像素。对于该级别的缩放,您需要不同的算法。好消息是,在这种缩放级别下,圆圈与直线无法区分。所以我们可以只使用 y=m x+c。更难的一点是找出圆上的一个点是否在我们的视野范围内。我们开始遇到指定圆半径的准确性问题。

一共有三个简答:

  1. 通过使用支持该精度数学的外部库(然后有效地使用它)
  2. 作为整数进行计算(例如,乘以 1,000,000,000,进行计算,然后除以相同的数额)
  3. 通过在代码中构建缩放功能并在缩放时重新绘制显示

注意:据我所知,只有 #3 允许在屏幕上显示圆的数学精确表示。在所有情况下,贝塞尔曲线都用于非常接近圆的近似值,但在前两种情况下,1,000,000,000% 的缩放足以表明贝塞尔曲线不是正确的圆,而在第三种情况下,曲线是为视口生成。