tags:

views:

231

answers:

4

Here is pseudo-code of how I setup an array representing the MandelBrot set, yet it becomes horribly stretched when leaving an aspect ratio of 1:1.

xStep = (maxX - minX) / width;
yStep = (maxY - minY) / height;

for(i = 0; i < width; i++)
 for(j = 0; j < height; j++)
  {
   constantReal = minReal + xStep * i;
   constantImag = minImag + yStep * j;
   image[i][j] = inSet(constantReal, constantImag);
  }

Thanks!

A: 

It probably has to do with how you are displaying the image array. You use the width variable i as the first index, but usually the first index should be the slowest changing, that is, the height.

Try changing the last line to image[j][i] = ...

Ned Batchelder
Wouldn't that flip it horizontally and vertically, rather than stretching it out?
MusiGenesis
Worse yet, it would write to memory outside of the array if width were not equal to height, which is what the OP is trying to do!
e.James
A: 

Make sure your casts are all correct. xStep and yStep might be the products of integer division instead of the expected floating point division (if that's C# in your sample, it would require some explicit casts to work correctly).

MusiGenesis
+6  A: 

Here is pseudo-code of how I setup an array representing the MandelBrot set, yet it becomes horribly stretched when leaving an aspect ratio of 1:1.

xStep = (maxX - minX) / width;
yStep = (maxY - minY) / height;

Aha! It's because you must keep the same aspect ratio both for the image you will draw and for the region of the complex plane you want to draw. In other words, it must hold

 width     maxX - minX
---------- = ---------------------
 height    maxY - minY

(It follows that xStep == yStep.) Your code probably does not enforce this requirement.

Federico Ramponi
That's it! That never occurred to me. Thanks a ton man. 2:1 works when I have a 2:1 in display-space and complex-space.
TT
A: 

I've had to solve the problem of mapping between screen and user coordinates several times in Java, so I wrote ZoomRect.java, a convenience class that converts between an arbitrary rectangle and the screen canvas. I have no idea how useful it really is, but I think it does a good job of abstracting out this problem.

Internally, it automatically takes care of aspect ratios with this line of code:

int size=Math.min(canvas.width, canvas.height);

which adds extra space on the shorter dimension. You could change it to Math.max to instead crop the longer dimension.

Using it is straightforward:

this.trans = new ZoomRect(this.getSize(), myCoords).getTransform());

graphics.transform(this.trans);

Once you have your canvas using it, you can, say, iterate through the points on your canvas, convert them to complex numbers, and run them through your algorithm.

jleedev