javascript - JavaScript 中更高的精度
问题描述
我正在尝试在 JavaScript 中使用更高精度的数字进行计算,以便能够更多地放大 Mandlebrot 集。(经过一定程度的缩放后,由于精度低,结果会“像素化”)
我看过这个问题,所以我尝试使用 BigNumber 之类的库,但速度慢得无法使用。我一直在尝试解决这个问题,我认为唯一的方法是使用慢速库。
有更快的图书馆吗?
有没有其他方法可以计算更高精度的数字?
有没有其他方法可以放大 Mandlebrot 集?
可能不需要添加此代码,但这是我用来检查点是否在 Mandlebrot 集中的函数。
function mandelbrot(x, y, it) {
var z = [0, 0]
var c1 = [x, y]
for (var i = 0; i < it; i++) {
z = [z[0]*z[0] - z[1]*z[1] + c1[0], 2*z[0]*z[1] + c1[1]]
if (Math.abs(z[0]) > 2, Math.abs(z[1]) > 2) {
break
}
}
return i
}
解决方案
关键不是 JavaScript 数字的原始数字精度(尽管这当然有其影响),而是基本的 Mandelbrot “转义”测试的工作方式,特别是阈值迭代计数。为了计算复平面中的一个点是在集合内还是在集合外,您一遍又一遍地迭代该点的公式(我不完全记得,也不想查找),直到显然该点在达到迭代阈值之前发散(公式从复平面的原点“逃脱”很多)或不发散。
渲染集合视图时的迭代阈值,该视图覆盖复平面原点周围的大部分视图(从原点向所有方向大约 2 个单位)可以低至 500,以便在现代计算机上的合理放大倍数。但是,当您放大时,迭代阈值需要与复平面上的“窗口”大小成反比增加。如果没有,那么“逃逸”测试就不能以足够的精度在更高的放大倍率下描绘出精细的细节。
我在 JavaScript 实现中使用的公式是
maxIterations = 400 * Math.log(1/dz0)
其中dz0
是(任意)平面上窗口的宽度。当放大到集合的视图时(嗯,集合的“边缘”,事情很有趣),dz0
变得非常小,因此迭代阈值上升到数千。
当然,对于“逃逸”的点(即不属于 Mandelbrot 集的点)的迭代计数可以用作一种“距离”测量。在几次迭代内逃脱的点显然不是“接近”集合,而仅在 2000 次迭代后逃脱的点更接近。该距离质量可以在可视化中以各种方式使用,或者提供颜色值(常见),或者如果集合被渲染为 3D 视图(其中集合作为一种“台面”),则可能提供 z 轴值三个维度和边界是一个垂直的“悬崖”两侧)。
推荐阅读
- c# - 如何检查 GameObject 是否包含网格渲染器但不包含任何碰撞器,然后向其添加碰撞器?
- java - 无法使用 Retrofit 从 API 检索键/值对
- c++ - 使用 std::call_once 引发异常的错误
- powershell - 用于过滤 Windows 事件日志的 Powershell 脚本
- python - 如何从散景中的邻接矩阵重新创建使用 matplotlib 制作的颜色图
- visual-studio - 有没有其他人看过这个 datagridview 错误?
- java - 使用 srimzi 在 Openshift 上设置 Kafka
- python - 我试图制作一个打印素数的代码,但它会吐出诸如 27 和 35 之类的数字
- javascript - Firebase .set() 与合并选项错误第二个参数必须是有效的函数
- javascript - Flask-SocketIO 发出错误请求