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,000,000,000,进行计算,然后除以相同的数额)
- 通过在代码中构建缩放功能并在缩放时重新绘制显示
注意:据我所知,只有 #3 允许在屏幕上显示圆的数学精确表示。在所有情况下,贝塞尔曲线都用于非常接近圆的近似值,但在前两种情况下,1,000,000,000% 的缩放足以表明贝塞尔曲线不是正确的圆,而在第三种情况下,曲线是为视口生成。
分离自:
使用浮点精度计算圆上的点位置时存在舍入误差
示例:
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,000,000,000,进行计算,然后除以相同的数额)
- 通过在代码中构建缩放功能并在缩放时重新绘制显示
注意:据我所知,只有 #3 允许在屏幕上显示圆的数学精确表示。在所有情况下,贝塞尔曲线都用于非常接近圆的近似值,但在前两种情况下,1,000,000,000% 的缩放足以表明贝塞尔曲线不是正确的圆,而在第三种情况下,曲线是为视口生成。