3

从标题中可以看出,我正忙于编写一个小程序,用于在 Java 中可视化分形。任何处理分形的人都会到达他/她寻找解决方案以消除这些愚蠢的“条带”的地步,而您只需按照逃脱所需的迭代次数为像素着色。所以我搜索了一种更高级的着色算法,找到了“标准化迭代计数”。我使用的公式是:

float loc = (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);

互联网上的每个人都对这个算法非常满意,每个人都使用它,每个人都得到了很好的结果。除了我。我想,这个算法应该提供一个介于 0 和 1 之间的浮点数。但这不会发生。我做了一些计算并得出结论,该算法仅适用于 c.abs() >= Math.E && c.abs() <= Math.exp(2) (即 Math.E * Math.E )。就数字而言,这意味着,我对这个等式的输入必须介于 2.718 和 7.389 之间。

但是,当复数 c 的大小大于 2 时,它被认为趋于无穷大。但是对于任何小于 Math.E 的 Input,我得到的值都大于 1。对于任何大于 Math.exp(2) 的数字,它都为负数。如果复数逃逸得非常快,就会出现这种情况。

所以请告诉我:我做错了什么。我很绝望。

谢谢。

编辑:

我错了:我发布的代码是正确的,我只是 1. 以错误的方式使用它,因此它没有提供正确的输出。2. 必须将 mandelbrot/julia 算法的救助值设置为 10,否则我将再次获得愚蠢的乐队。

问题解决了!

4

2 回答 2

2

正如您已经发现的那样,在平滑看起来正确之前,您需要增加救助半径。

二是坐标可以具有的最小长度,这样当您将其平方并添加初始值时,它不会导致更小的长度。如果之前的长度是 2.0,并且您将其平方,那么您将拥有 4.0 的长度(指向任何方向),并且 c 的任何值最多可以减少 2.0(通过精确指向相反的方向) . 如果 c 大于那个值,那么它会立即开始逃逸。

现在,为了估计迭代次数的小数部分,我们查看最终的 |z|。如果 z 只是简单地平方并且没有添加 c,那么它的长度将在 2.0 和 4.0 之间(新值必须大于 2.0 才能退出,旧值必须小于 2.0 才能没有退出早点出来)。

如果没有 c,取 |z| 在 2 和 4 之间的比例位置会给我们迭代次数的一小部分。如果 |z| 接近 4,那么之前的长度一定接近 2,所以在之前的迭代中它已经接近救助,并且平滑的结果应该接近之前的迭代计数来表示。如果它接近于 2,那么之前的迭代距离退出更远,因此平滑的结果应该更接近新的迭代计数。

不幸的是,c 搞砸了。c 越大,该简单关系中的潜在误差就越大。即使旧的长度接近 2.0,它也可能已经降落,以至于 c 的影响使它看起来一定更小。

增加救助可以减轻增加 c 的影响。如果 bailout 为 64,则结果长度将在 64 和 4096 之间,并且 c 的最大偏移量 2 对结果的影响相对较小。

于 2013-06-22T20:18:03.640 回答
0

您遗漏了迭代值,试试这个:

float loc = <iteration_value> + (float) 1 - Math.log(Math.log(c.abs())) / Math.log(2);

是公式iteration_value中产生的迭代次数。c

于 2012-04-05T10:47:12.677 回答