I have to make a c# program which creates a form and one of its controls has to be a control that makes a sketch of a Mandelbrot set in which you can zoom in and tell on which point you want to centre. In my opinion i'm doing the right thing, but when I want to start the program, I don't get the desired image of a standard Mandelbrot set. For the Mandelbrot sketch control I've got the next bit of my Mandelbrot class:
class Mandelbrotsketchscreen : UserControl
{
//a method that draws every point with a certain paint
//a method that chooses the right colour
//a method that translates the pixel coordinates of the control to the actual coordinates
//gives the number how many times the function has to be used
private static int Mandelnumber(PointF p, PointF middle, double scale, int max, Size size)
{
PointF realpoint = new PointF();
realpoint.X = (float)(middle.X + (p.X - size.Width / 2) * scale);
realpoint.Y = (float)(middle.Y + (p.Y - size.Height / 2) * scale);
PointF help = new PointF(0, 0);
int i;
for (i = 1; i <= max; i++)
{
help.X = help.X * help.X - help.Y * help.Y + realpoint.X;
help.Y = 2 * help.X * help.Y + realpoint.Y;
if (Math.Sqrt(help.X * help.X + help.Y * help.Y) > 2)
break;
}
return i;
}
}
Can someone tell me if I'm doing the calculation wrong or that maybe my loops are wrong?
The new values for help.X
and help.Y
need to be calculated based on the previous values of help.X
and help.Y
.
Your code first calculates the new help.X
value based on the previous help.X and help.Y values. So far, so good. But then, your code calculates help.Y
using the new help.X value instead of the previous help.X value.
Thus, a solution/fix for your problem can be as simple as:
for (i = 1; i <= max; i++)
{
var newX = help.X * help.X - help.Y * help.Y + realpoint.X;
var newY = 2 * help.X * help.Y + realpoint.Y;
help.X = newX;
help.Y = newY;
if (Math.Sqrt(help.X * help.X + help.Y * help.Y) > 2)
break;
}
(Side note: The newY variable in my example here is not strictly necessary. I chose to use it to clearly illustrate the distinction between previous and new values for help.X and help.Y.)
A different (and shorter) solution has been mentioned by Eric Lippert in the comments: Just create a new help
point instead of mutating/modifying the existing help
point:
for (i = 1; i <= max; i++)
{
help = new PointF(
help.X * help.X - help.Y * help.Y + realpoint.X,
2 * help.X * help.Y + realpoint.Y
);
if (help.X * help.X + help.Y * help.Y > 4)
break;
}
This shorter solution also eliminates the rather slow square root computation by comparing against the square of 2 (= 4).