无限和的分形生成

时间:2013-01-25 20:14:25

标签: graphics infinite fractals

我在计算机图形学课程网站上找到了项目描述。我正在努力完成项目。

以下是问题说明的链接:

http://www.pdfhost.net/index.php?Action=Download&File=901bc7785bef41364b3a40f6f4493926

以下是我的代码。我遇到的问题是该系列的条款增长如此之快,我无法正确地将点映射到屏幕。从问题描述中可以看出,这些点可以在-2 - 2平方内映射,但点之间的值差异非常大,以至于通过最大值进行归一化会将大多数点折叠为单个像素。

我认为我有一个根本的误解,我无法识别。任何帮助或见解将不胜感激!

int w = 800, h = 600;
int numTimes = 10, cSize = 5;
float xr = 2, yr = 2;

void setup() {
  size(w,h);
}

void draw() {
  background(255);

  Complex v = new Complex(mouseX*(xr/w) - (xr/2), mouseY*(yr/h) - (yr/2));  
  Complex[] exps = new Complex[numTimes];

  for (int i = 0; i < numTimes; i++) {
    exps[i] = complexExp(v,i);
  }

  ellipse(w/2, h/2, cSize, cSize);
  for (int i = 0; i < numTimes; i++) {
    drawSeries(new Complex(0,0), exps, i, i);
  }
}

void drawSeries(Complex vToDraw, Complex[] exps, int count, int clrTrunc) {
  if (count == 0) {
    Complex v = exps[0];   

    float progress = float(clrTrunc) / float(numTimes);
    fill(255*progress, 180, 255 - 255*progress);

    vToDraw.add(v);
    ellipse(vToDraw.r*(w/xr) + (w/2), vToDraw.i*(h/xr) + h/2, cSize, cSize);
    vToDraw.sub(v);
    vToDraw.sub(v);
    ellipse(vToDraw.r*(w/xr) + (w/2), vToDraw.i*(h/xr) + h/2, cSize, cSize);
  } else {
    Complex v = exps[count];

    vToDraw.add(v);
    drawSeries(vToDraw, exps, count - 1, clrTrunc );
    vToDraw.sub(v);
    vToDraw.sub(v);
    drawSeries(vToDraw, exps, count - 1,clrTrunc );
  }
}

Complex complexExp(Complex v, int times) {
  if (times == 0) {
    return new Complex(1, 1);
  } else if ( times == 1) {
    return new Complex( v.r*v.r - v.i*v.i, 2*v.r*v.i );
  } else {
    return complexExp( new Complex( v.r*v.r - v.i*v.i, 2*v.r*v.i ), times - 1 );
  }
}

class Complex {
  float r, i;

  Complex() {
    this.r = 0;
    this.i = 0;
  } 

  Complex(float r, float i) {
    this.r = r;
    this.i = i;
  }

  void add(Complex nv) {
      this.r += nv.r;
      this.i += nv.i;
  }

  void sub(Complex nv) {
      this.r -= nv.r;
      this.i -= nv.i;
  }
}

1 个答案:

答案 0 :(得分:2)

如果您编写更完整的Complex类,我认为您可以使代码更清晰。

int w = 800, h = 600;
int numTimes = 10, cSize = 5;
float xr = 3, yr = 3;

void setup() {
  size(w,h);
  noLoop();
}
void mousePressed() {
  redraw();
}

void draw() {
  background(255);

  Complex v = new Complex(mouseX*(xr/w) - (xr/2), mouseY*(yr/h) - (yr/2));  
  Complex[] exps = new Complex[numTimes];

  for (int i = 0; i < numTimes; i++) {
    exps[i] = v.raisedTo(i);
    print(exps[i]);
  }

  ellipse(w/2, h/2, cSize, cSize);
  print(exps);
  drawSerie(exps, numTimes);
}

void drawSerie(Complex[] exps, int total)
{
  Complex partial = new Complex(0, 0);
  drawPartial(exps, total -1, partial);
}

void drawFinal(Complex toDraw)
{
   point(toDraw.r*(w/xr) + (w/2), toDraw.i*(h/xr) + h/2);
}

void drawPartial(Complex [] exps, int depth, Complex partial)
{
  if (depth == -1)
  {
    drawFinal(partial);
    return;
  }
  int nextDepth = depth -1;
  drawPartial(exps, nextDepth, partial);
  Complex element = exps[depth];
  drawPartial(exps, nextDepth, partial.add(element));
  drawPartial(exps, nextDepth, partial.sub(element));
}


class Complex {
  float r, i;

  Complex() {
    this.r = 0;
    this.i = 0;
  } 

  Complex(float r, float i) {
    this.r = r;
    this.i = i;
  }

  Complex(Complex other)
  {
    this.r = other.r;
    this.i = other.i;
  }

  Complex mult(Complex other)
  {
    return new Complex(this.r*other.r - this.i*other.i, this.r*other.i + this.i*other.r);
  }

  Complex add(Complex nv) {
      return new Complex(this.r + nv.r, this.i + nv.i);
  }

  Complex sub(Complex nv) {
      return new Complex(this.r - nv.r,  this.i - nv.i);
  }

  Complex raisedTo(int n) {
  if (n == 0) {
    return new Complex(1, 0);
  }
    else if (n % 2 == 0)
  {
    return (this.mult(this)).raisedTo(n/2);
  } 
  else 
  {
    return this.mult(this.raisedTo(n - 1 ));
  }

}
  String  toString()
  {
    return "real: " + this.r + " imaginary: " + this.i;
  }
}

系列的计算效率不高,但我认为很明显