之前在C#上发布了一个问题。Net Mandelbrot集合,这是一个很有帮助的回答,但是我必须回到这个Mandelbrot集合,在它的双变量上实现一个结构,定义(虚坐标和实坐标)。
作为一个刚接触structs并且对structs有点生疏的人,我想就我做错了什么以及如何改进所述代码提出一些建议,因为只要看看它,我相信它可以稍微优化一下。这是使用结构的正确方法吗?如果没有,有哪些替代方案或最佳技术?谢谢
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace wmcMandelbrot
{
struct doubleVar
{
public double realCoord, imagCoord;
public double realTemp, imagTemp, realTemp2, arg;
public double newIcoord, newIcoord1, newIcoord2;
public double rCoord, rCoord1, rCoord2;
}
class Program
{
static void Main(string[] args)
{
doubleVar doubleNum;
int iterations;
Console.WriteLine("Enter first imaginary coord: ");
doubleNum.newIcoord = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter second imaginary coord: ");
doubleNum.newIcoord1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter third imaginary coord: ");
doubleNum.newIcoord2 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter first real coord: ");
doubleNum.rCoord = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter second real coord: ");
doubleNum.rCoord1 = Convert.ToDouble(Console.ReadLine());
Console.WriteLine("Enter third real coord: ");
doubleNum.rCoord2 = Convert.ToDouble(Console.ReadLine());
for (doubleNum.imagCoord = doubleNum.newIcoord; doubleNum.imagCoord >= -doubleNum.newIcoord1; doubleNum.imagCoord -= doubleNum.newIcoord2)
{
for (doubleNum.realCoord = -doubleNum.rCoord; doubleNum.realCoord <= doubleNum.rCoord1; doubleNum.realCoord += doubleNum.rCoord2)
{
iterations = 0;
doubleNum.realTemp = doubleNum.realCoord;
doubleNum.imagTemp = doubleNum.imagCoord;
doubleNum.arg = (doubleNum.realCoord * doubleNum.realCoord) + (doubleNum.imagCoord * doubleNum.imagCoord);
while ((doubleNum.arg < 4) && (iterations < 40))
{
doubleNum.realTemp2 = (doubleNum.realTemp * doubleNum.realTemp) - (doubleNum.imagTemp * doubleNum.imagTemp) - doubleNum.realCoord;
doubleNum.imagTemp = (2 * doubleNum.realTemp * doubleNum.imagTemp) - doubleNum.imagCoord;
doubleNum.realTemp = doubleNum.realTemp2;
doubleNum.arg = (doubleNum.realTemp * doubleNum.realTemp) + (doubleNum.imagTemp * doubleNum.imagTemp);
iterations += 1;
}
switch (iterations % 4)
{
case 0:
Console.Write(".");
break;
case 1:
Console.Write("o");
break;
case 2:
Console.Write("O");
break;
case 3:
Console.Write("@");
break;
}
}
Console.Write("\n");
}
Console.ReadKey();
}
}
}
只存储定义坐标(读取部分和虚部)所需的值,而不存储任何临时值是有意义的。计算值也可以是属性,如下所示:
public struct MapPoint
{
public double realCoord, imagCoord;
public double realConst, imagConst;
public MapPoint(double realConst, double imagConst)
: this(realConst, imagConst, realConst, imagConst) { }
public MapPoint(double realCoord, double imagCoord, double realConst, double imagConst)
{
this.realCoord = realCoord;
this.imagCoord = imagCoord;
this.realConst = realConst;
this.imagConst = imagConst;
}
public double Argument // calculated property
{
get { return realCoord * realCoord + imagCoord * imagCoord; }
}
public MapPoint Iterate()
{
// Do the z = z^2+c thing
return new MapPoint(
realCoord * realCoord - imagCoord * imagCoord + realConst,
2 * realCoord * imagCoord + realConst,
realConst, imagConst);
}
}
现在要像这样使用此结构:
void Main() {
for( double y=...
for( double x=...
int iterations = 0;
MapPoint point = new MapPoint(x, y);
while (iterations < 40 || point.Argument < 4.0)
{
point = point.Iterate();
iterations++;
}
switch (iterations % 4)
{
//...
}
...
}
关键是所有的计算都在结构内部完成,靠近信息存储的位置。这样,该结构可以在其他地方以最小的工作量重复使用,而无需再次重新编写计算块。此外,任何临时值在不需要时都会被丢弃,并且不会存储在重要值旁边。
请promise阅读这里和这里的结构,然后将上面的代码重新编写为您自己的代码。
我认为你应该用一个结构来表示每个复数。然后,该结构可以包含加、减、乘这些复数的函数:
如。
struct Complex
{
public double real;
public double imag;
public Complex(double r, double i)
{
real = r;
imag = i;
}
public Complex add(Complex operand)
{
return new Complex(real + operand.real, imag + operand.imag);
}
public Complex multiply(Complex operand)
{
return new Complex(real * operand.real - imag * operand.imag, real * operand.imag + operand.real * imag);
}
}
然后,要使用struct,您可以执行以下操作
Complex c = new Complex( ...coordinate goes here... );
Complex z = new Complex(0,0);
// z -> z^2 + c
Complex result = z.multiply(z).add(c);
等
您还可以将“sq”(数字平方)或“pow”(提升到给定的幂)或“arg”(在上面的代码中)添加到复数结构中。天空是极限!请注意,这些函数不必返回另一个复数,例如,“arg”将返回一个double。
此外,如果您总是将两个复数(映射点和z值)组合在一起,您可以创建一个结构来保存两个复数:
struct MapPoint
{
Complex c;
Complex z;
}
等等对我来说,将逻辑上不可分割的结构中的事物或总是作为一个整体工作的事物分组是有意义的。
有一个简单的JS代码,可以呈现非常基本的Mandelbrot分形。 任务是沿其轴以随机角度旋转此分形。它不应该是画布旋转或它的图像数据,但我必须调整初始的分形公式来做到这一点。 例如,如果角度为45度或以弧度为单位的PI/4,则输出应如下所示 我试过玩没有任何成功。
对于复杂变量,我使用以下复杂类文件。 下面的java代码是Mandelbrot集合的迭代计算器示例。 提前谢谢!
我制作了一个程序来计算mandelbrot集合中的点。对于不属于mandelbrot集的点,我会记录起点发散到震级大于2的地方所需的迭代次数。基本上,对于mandelbrot集合之外的每一点,我都有一个计数器,可以显示它在1到256的范围内发散的速度。我想做的是根据每个点发散的速度给它一个颜色。例如,在255次迭代中发散的点可能是白色的,发散越快,着色越多。我已经做了一个简单的调整,在20步以上的
迷人可爱的Mandelbrot集箍和卷曲是浮点计算不准确的结果吗? 我编写了各种Mandelbrot集实现,例如动态缩放和回放。一些使用定点算法,另一些使用FPU。 我见过这个问题,它表明每一个芽都是数学上光滑的形状,周围有较小的芽。 海马形状等的游行是计算机浮点运算局限性的副作用,而不是实际的曼德布罗特集吗? 海马?由Spektre添加: 我一直想说的是,浮点运算,无论是定点运算还是固定意义运算
我想用Java生成Mandelbrot集合的PNG照片,输出应该可以在google图像搜索中轻松找到。 该集合定义为以下序列: 其中,和是复数,的模数总是小于2。 我首先为复数定义了一个类,该类还包含所需的基本复杂操作。 然后我定义了Mandelbrot类,该类获取复数c(基于像素)的数量,使用Mandelbrot方法检查这些数字是否在Mandelbrot集中,并将该方法的输出转换为要显示的颜色。
我知道关于这件事,阿雷迪回答了很多问题。然而,我的略有不同。无论何时我们实现平滑着色算法,我都理解它。 其中n是逃逸迭代,2是z的幂,如果我没有弄错,z是该逃逸迭代处复数的模。然后,我们在颜色之间的线性插值中使用这个重整化的逃逸值来生成平滑的带状mandelbrot集。我已经看到了关于这个的其他问题的答案,我们通过HSB到RGB的转换来运行这个值,但是我仍然无法理解这将如何提供平滑的颜色渐变,以及