Java Mandelbrot visualization questions on zooming and coloring
I am trying to program a visualisation for the Mandelbrot set in java, and there are a couple of things that I am struggling with to program. I realize that questions around this topic have been asked a lot and there is a lot of documentation online but a lot of things seem very complicated and I am relatively new to programming.
The first issue
The first issue I have is to do with zooming in on the fractal. My goal is to make an "infinite" zoom on the fractal (of course not infinite, as far as a regular computer allows it regarding calculation time and precision). The approach I am currently going for is the following on a timer:
- Draw the set using some number of iterations on the range (-2, 2) on the real axis and (2, 2) on the imaginary axis.
- Change those ranges to zoom in.
- Redraw that section of the set with the number of iterations.
It's the second step that I struggle with. This is my current code:
for (int Py = beginY; Py < endY; Py++) {
for (int Px = beginX; Px < endX; Px++) {
double x0 = map(Px, 0, height,-2, 2);
double y0 = map(Py, 0, width, -2, 2);
Px and Py are the coordinates of the pixels in the image. The image is 1000x1000. The map funtion takes a number, in this case Px or Py, with a range of (0, 1000) and devides it evenly over the range (-2, 2), so it returns the corresponding value in that range.
I think that in order to zoom in, I'll have to change the -2 and 2 values by some way in the timer, but whatever I try, it doesn't seem to work. The zoom always ends up slowing down after a while or it will end up zooming in on a part of the set that is in the set, so not the borders. I tried multiplying them by some scale factor every timer tick, but that doesn't really produce the result I was looking for.
Now I have two questions about this issue.
- Is this the right approach to visualizing the set and zooming in(draw, change range, redraw)?
- If it is, how do I zoom in properly on an area that is interesting and that will keep zooming in properly even after running for a minute?
The second issue
Of course when visualizing something, you need to get some actual visual thing. In this case I want to color the set in a way similar to what you see here: (https://upload.wikimedia.org/wikipedia/commons/f/fc/Mandel_zoom_08_satellite_antenna.jpg).
My guess is that you have use the amount of iterations a pixel went through to before breaking out of the loop to give it some color value. However, I only really know how to do this with a black and white color scheme. I tried making a color array that holds the same amount of different gray colors as the amount of max iterations, starting from black and ending in white. Here is my code:
Color colors = new Color[maxIterations + 2];
for (int i = 0; i < colors.length; i++) {
colors[i] = new Color((int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255));
}
I then just filled in the amount of iterations in the array and assigned that color to the pixel. I have two questions about this:
- Will this also work as we zoom into the fractal in the previously described manner?
- How can I add my own color scheme in this, like in the picture? I've read some things about "linear interpolation" but I don't really understand what it is and in what way it can help me.
java mandelbrot
add a comment |
I am trying to program a visualisation for the Mandelbrot set in java, and there are a couple of things that I am struggling with to program. I realize that questions around this topic have been asked a lot and there is a lot of documentation online but a lot of things seem very complicated and I am relatively new to programming.
The first issue
The first issue I have is to do with zooming in on the fractal. My goal is to make an "infinite" zoom on the fractal (of course not infinite, as far as a regular computer allows it regarding calculation time and precision). The approach I am currently going for is the following on a timer:
- Draw the set using some number of iterations on the range (-2, 2) on the real axis and (2, 2) on the imaginary axis.
- Change those ranges to zoom in.
- Redraw that section of the set with the number of iterations.
It's the second step that I struggle with. This is my current code:
for (int Py = beginY; Py < endY; Py++) {
for (int Px = beginX; Px < endX; Px++) {
double x0 = map(Px, 0, height,-2, 2);
double y0 = map(Py, 0, width, -2, 2);
Px and Py are the coordinates of the pixels in the image. The image is 1000x1000. The map funtion takes a number, in this case Px or Py, with a range of (0, 1000) and devides it evenly over the range (-2, 2), so it returns the corresponding value in that range.
I think that in order to zoom in, I'll have to change the -2 and 2 values by some way in the timer, but whatever I try, it doesn't seem to work. The zoom always ends up slowing down after a while or it will end up zooming in on a part of the set that is in the set, so not the borders. I tried multiplying them by some scale factor every timer tick, but that doesn't really produce the result I was looking for.
Now I have two questions about this issue.
- Is this the right approach to visualizing the set and zooming in(draw, change range, redraw)?
- If it is, how do I zoom in properly on an area that is interesting and that will keep zooming in properly even after running for a minute?
The second issue
Of course when visualizing something, you need to get some actual visual thing. In this case I want to color the set in a way similar to what you see here: (https://upload.wikimedia.org/wikipedia/commons/f/fc/Mandel_zoom_08_satellite_antenna.jpg).
My guess is that you have use the amount of iterations a pixel went through to before breaking out of the loop to give it some color value. However, I only really know how to do this with a black and white color scheme. I tried making a color array that holds the same amount of different gray colors as the amount of max iterations, starting from black and ending in white. Here is my code:
Color colors = new Color[maxIterations + 2];
for (int i = 0; i < colors.length; i++) {
colors[i] = new Color((int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255));
}
I then just filled in the amount of iterations in the array and assigned that color to the pixel. I have two questions about this:
- Will this also work as we zoom into the fractal in the previously described manner?
- How can I add my own color scheme in this, like in the picture? I've read some things about "linear interpolation" but I don't really understand what it is and in what way it can help me.
java mandelbrot
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42
add a comment |
I am trying to program a visualisation for the Mandelbrot set in java, and there are a couple of things that I am struggling with to program. I realize that questions around this topic have been asked a lot and there is a lot of documentation online but a lot of things seem very complicated and I am relatively new to programming.
The first issue
The first issue I have is to do with zooming in on the fractal. My goal is to make an "infinite" zoom on the fractal (of course not infinite, as far as a regular computer allows it regarding calculation time and precision). The approach I am currently going for is the following on a timer:
- Draw the set using some number of iterations on the range (-2, 2) on the real axis and (2, 2) on the imaginary axis.
- Change those ranges to zoom in.
- Redraw that section of the set with the number of iterations.
It's the second step that I struggle with. This is my current code:
for (int Py = beginY; Py < endY; Py++) {
for (int Px = beginX; Px < endX; Px++) {
double x0 = map(Px, 0, height,-2, 2);
double y0 = map(Py, 0, width, -2, 2);
Px and Py are the coordinates of the pixels in the image. The image is 1000x1000. The map funtion takes a number, in this case Px or Py, with a range of (0, 1000) and devides it evenly over the range (-2, 2), so it returns the corresponding value in that range.
I think that in order to zoom in, I'll have to change the -2 and 2 values by some way in the timer, but whatever I try, it doesn't seem to work. The zoom always ends up slowing down after a while or it will end up zooming in on a part of the set that is in the set, so not the borders. I tried multiplying them by some scale factor every timer tick, but that doesn't really produce the result I was looking for.
Now I have two questions about this issue.
- Is this the right approach to visualizing the set and zooming in(draw, change range, redraw)?
- If it is, how do I zoom in properly on an area that is interesting and that will keep zooming in properly even after running for a minute?
The second issue
Of course when visualizing something, you need to get some actual visual thing. In this case I want to color the set in a way similar to what you see here: (https://upload.wikimedia.org/wikipedia/commons/f/fc/Mandel_zoom_08_satellite_antenna.jpg).
My guess is that you have use the amount of iterations a pixel went through to before breaking out of the loop to give it some color value. However, I only really know how to do this with a black and white color scheme. I tried making a color array that holds the same amount of different gray colors as the amount of max iterations, starting from black and ending in white. Here is my code:
Color colors = new Color[maxIterations + 2];
for (int i = 0; i < colors.length; i++) {
colors[i] = new Color((int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255));
}
I then just filled in the amount of iterations in the array and assigned that color to the pixel. I have two questions about this:
- Will this also work as we zoom into the fractal in the previously described manner?
- How can I add my own color scheme in this, like in the picture? I've read some things about "linear interpolation" but I don't really understand what it is and in what way it can help me.
java mandelbrot
I am trying to program a visualisation for the Mandelbrot set in java, and there are a couple of things that I am struggling with to program. I realize that questions around this topic have been asked a lot and there is a lot of documentation online but a lot of things seem very complicated and I am relatively new to programming.
The first issue
The first issue I have is to do with zooming in on the fractal. My goal is to make an "infinite" zoom on the fractal (of course not infinite, as far as a regular computer allows it regarding calculation time and precision). The approach I am currently going for is the following on a timer:
- Draw the set using some number of iterations on the range (-2, 2) on the real axis and (2, 2) on the imaginary axis.
- Change those ranges to zoom in.
- Redraw that section of the set with the number of iterations.
It's the second step that I struggle with. This is my current code:
for (int Py = beginY; Py < endY; Py++) {
for (int Px = beginX; Px < endX; Px++) {
double x0 = map(Px, 0, height,-2, 2);
double y0 = map(Py, 0, width, -2, 2);
Px and Py are the coordinates of the pixels in the image. The image is 1000x1000. The map funtion takes a number, in this case Px or Py, with a range of (0, 1000) and devides it evenly over the range (-2, 2), so it returns the corresponding value in that range.
I think that in order to zoom in, I'll have to change the -2 and 2 values by some way in the timer, but whatever I try, it doesn't seem to work. The zoom always ends up slowing down after a while or it will end up zooming in on a part of the set that is in the set, so not the borders. I tried multiplying them by some scale factor every timer tick, but that doesn't really produce the result I was looking for.
Now I have two questions about this issue.
- Is this the right approach to visualizing the set and zooming in(draw, change range, redraw)?
- If it is, how do I zoom in properly on an area that is interesting and that will keep zooming in properly even after running for a minute?
The second issue
Of course when visualizing something, you need to get some actual visual thing. In this case I want to color the set in a way similar to what you see here: (https://upload.wikimedia.org/wikipedia/commons/f/fc/Mandel_zoom_08_satellite_antenna.jpg).
My guess is that you have use the amount of iterations a pixel went through to before breaking out of the loop to give it some color value. However, I only really know how to do this with a black and white color scheme. I tried making a color array that holds the same amount of different gray colors as the amount of max iterations, starting from black and ending in white. Here is my code:
Color colors = new Color[maxIterations + 2];
for (int i = 0; i < colors.length; i++) {
colors[i] = new Color((int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255),
(int)map(i, 0, maxIterations + 2, 0, 255));
}
I then just filled in the amount of iterations in the array and assigned that color to the pixel. I have two questions about this:
- Will this also work as we zoom into the fractal in the previously described manner?
- How can I add my own color scheme in this, like in the picture? I've read some things about "linear interpolation" but I don't really understand what it is and in what way it can help me.
java mandelbrot
java mandelbrot
edited Nov 19 '18 at 22:17
halfer
14.6k758112
14.6k758112
asked Nov 19 '18 at 19:25
EliturboEliturbo
62
62
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42
add a comment |
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42
add a comment |
1 Answer
1
active
oldest
votes
It sounds like you've made a good start.
Re the first issue: I believe there are ways to automatically choose an "interesting" portion of the set to zoom in on, but I don't know what they are. And I'm quite sure it involves more than just applying some linear function to your current bounding rectangle, which is what it sounds like you're doing.
So you could try to find out what these methods are (might get mathematically complicated), but if you're new to programming, you'll probably find it easier to let the user choose where to zoom. This is also more fun in the beginning, since you can run your program repeatedly and explore a new part of the set each time.
A simple way to do this is to let the user draw a rectangle over the image, and use your map
function to convert the pixel coordinates of the drawn rectangle to the new real and imaginary coordinates of your zoom area.
You could also combine both approaches: once you've found somewhere you find interesting by manually selecting the zoom area, you can set this as your "final destination", and have the code gradually and smoothly zoom into it, to create a nice movie.
It will always get gradually slower though, as you start using ever more precise coordinates, until you reach the limits of precision with double
and it becomes a pixellated mess. From there, if you want to zoom further, you'll have to look into arbitrary-precision arithmetic with BigDecimal
- and it will continue to get slower and slower.
Re the second issue: starting off by calculating a value of numIterations / maxIterations
(i.e. between 0 and 1) for each pixel is the right idea (I think this is basically what you're doing).
From there, there are all sorts of ways to convert this value to a colour, it's time to get creative!
A simple one is to have an array of a few very different colours. E.g. if you had white (0.0), red (0.25), green (0.5), blue (0.75), black (1.0), then if your calculated number was exactly one of the ones listed, you'd use the corresponding colour. If it's somewhere between, you blend the colours, e.g. for 0.3 you'd take:
((0.5-0.3)*red + (0.3-0.25)*green) / (0.5 - 0.25)
= 0.8*red + 0.2*green
Taking a weighted average of two colours is something I'll leave as an exercise ;)
(hint: take separate averages of the r, g, and b values. Playing with the alpha values could maybe also work).
Another one, if you want to get more mathsy, is to take an equation for a spiral and use it to calculate a point on a plane in HSB colour space (you can keep the brightness at some fixed value, say 1). In fact, any curve in 2D or 3D which you know how to write as an equation of one real variable can be used this way to give you smoothly changing colours, if you interpret the coordinates as points in some colour space.
Hope that's enough to keep you going! Let me know if it's not clear.
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381336%2fjava-mandelbrot-visualization-questions-on-zooming-and-coloring%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
It sounds like you've made a good start.
Re the first issue: I believe there are ways to automatically choose an "interesting" portion of the set to zoom in on, but I don't know what they are. And I'm quite sure it involves more than just applying some linear function to your current bounding rectangle, which is what it sounds like you're doing.
So you could try to find out what these methods are (might get mathematically complicated), but if you're new to programming, you'll probably find it easier to let the user choose where to zoom. This is also more fun in the beginning, since you can run your program repeatedly and explore a new part of the set each time.
A simple way to do this is to let the user draw a rectangle over the image, and use your map
function to convert the pixel coordinates of the drawn rectangle to the new real and imaginary coordinates of your zoom area.
You could also combine both approaches: once you've found somewhere you find interesting by manually selecting the zoom area, you can set this as your "final destination", and have the code gradually and smoothly zoom into it, to create a nice movie.
It will always get gradually slower though, as you start using ever more precise coordinates, until you reach the limits of precision with double
and it becomes a pixellated mess. From there, if you want to zoom further, you'll have to look into arbitrary-precision arithmetic with BigDecimal
- and it will continue to get slower and slower.
Re the second issue: starting off by calculating a value of numIterations / maxIterations
(i.e. between 0 and 1) for each pixel is the right idea (I think this is basically what you're doing).
From there, there are all sorts of ways to convert this value to a colour, it's time to get creative!
A simple one is to have an array of a few very different colours. E.g. if you had white (0.0), red (0.25), green (0.5), blue (0.75), black (1.0), then if your calculated number was exactly one of the ones listed, you'd use the corresponding colour. If it's somewhere between, you blend the colours, e.g. for 0.3 you'd take:
((0.5-0.3)*red + (0.3-0.25)*green) / (0.5 - 0.25)
= 0.8*red + 0.2*green
Taking a weighted average of two colours is something I'll leave as an exercise ;)
(hint: take separate averages of the r, g, and b values. Playing with the alpha values could maybe also work).
Another one, if you want to get more mathsy, is to take an equation for a spiral and use it to calculate a point on a plane in HSB colour space (you can keep the brightness at some fixed value, say 1). In fact, any curve in 2D or 3D which you know how to write as an equation of one real variable can be used this way to give you smoothly changing colours, if you interpret the coordinates as points in some colour space.
Hope that's enough to keep you going! Let me know if it's not clear.
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
add a comment |
It sounds like you've made a good start.
Re the first issue: I believe there are ways to automatically choose an "interesting" portion of the set to zoom in on, but I don't know what they are. And I'm quite sure it involves more than just applying some linear function to your current bounding rectangle, which is what it sounds like you're doing.
So you could try to find out what these methods are (might get mathematically complicated), but if you're new to programming, you'll probably find it easier to let the user choose where to zoom. This is also more fun in the beginning, since you can run your program repeatedly and explore a new part of the set each time.
A simple way to do this is to let the user draw a rectangle over the image, and use your map
function to convert the pixel coordinates of the drawn rectangle to the new real and imaginary coordinates of your zoom area.
You could also combine both approaches: once you've found somewhere you find interesting by manually selecting the zoom area, you can set this as your "final destination", and have the code gradually and smoothly zoom into it, to create a nice movie.
It will always get gradually slower though, as you start using ever more precise coordinates, until you reach the limits of precision with double
and it becomes a pixellated mess. From there, if you want to zoom further, you'll have to look into arbitrary-precision arithmetic with BigDecimal
- and it will continue to get slower and slower.
Re the second issue: starting off by calculating a value of numIterations / maxIterations
(i.e. between 0 and 1) for each pixel is the right idea (I think this is basically what you're doing).
From there, there are all sorts of ways to convert this value to a colour, it's time to get creative!
A simple one is to have an array of a few very different colours. E.g. if you had white (0.0), red (0.25), green (0.5), blue (0.75), black (1.0), then if your calculated number was exactly one of the ones listed, you'd use the corresponding colour. If it's somewhere between, you blend the colours, e.g. for 0.3 you'd take:
((0.5-0.3)*red + (0.3-0.25)*green) / (0.5 - 0.25)
= 0.8*red + 0.2*green
Taking a weighted average of two colours is something I'll leave as an exercise ;)
(hint: take separate averages of the r, g, and b values. Playing with the alpha values could maybe also work).
Another one, if you want to get more mathsy, is to take an equation for a spiral and use it to calculate a point on a plane in HSB colour space (you can keep the brightness at some fixed value, say 1). In fact, any curve in 2D or 3D which you know how to write as an equation of one real variable can be used this way to give you smoothly changing colours, if you interpret the coordinates as points in some colour space.
Hope that's enough to keep you going! Let me know if it's not clear.
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
add a comment |
It sounds like you've made a good start.
Re the first issue: I believe there are ways to automatically choose an "interesting" portion of the set to zoom in on, but I don't know what they are. And I'm quite sure it involves more than just applying some linear function to your current bounding rectangle, which is what it sounds like you're doing.
So you could try to find out what these methods are (might get mathematically complicated), but if you're new to programming, you'll probably find it easier to let the user choose where to zoom. This is also more fun in the beginning, since you can run your program repeatedly and explore a new part of the set each time.
A simple way to do this is to let the user draw a rectangle over the image, and use your map
function to convert the pixel coordinates of the drawn rectangle to the new real and imaginary coordinates of your zoom area.
You could also combine both approaches: once you've found somewhere you find interesting by manually selecting the zoom area, you can set this as your "final destination", and have the code gradually and smoothly zoom into it, to create a nice movie.
It will always get gradually slower though, as you start using ever more precise coordinates, until you reach the limits of precision with double
and it becomes a pixellated mess. From there, if you want to zoom further, you'll have to look into arbitrary-precision arithmetic with BigDecimal
- and it will continue to get slower and slower.
Re the second issue: starting off by calculating a value of numIterations / maxIterations
(i.e. between 0 and 1) for each pixel is the right idea (I think this is basically what you're doing).
From there, there are all sorts of ways to convert this value to a colour, it's time to get creative!
A simple one is to have an array of a few very different colours. E.g. if you had white (0.0), red (0.25), green (0.5), blue (0.75), black (1.0), then if your calculated number was exactly one of the ones listed, you'd use the corresponding colour. If it's somewhere between, you blend the colours, e.g. for 0.3 you'd take:
((0.5-0.3)*red + (0.3-0.25)*green) / (0.5 - 0.25)
= 0.8*red + 0.2*green
Taking a weighted average of two colours is something I'll leave as an exercise ;)
(hint: take separate averages of the r, g, and b values. Playing with the alpha values could maybe also work).
Another one, if you want to get more mathsy, is to take an equation for a spiral and use it to calculate a point on a plane in HSB colour space (you can keep the brightness at some fixed value, say 1). In fact, any curve in 2D or 3D which you know how to write as an equation of one real variable can be used this way to give you smoothly changing colours, if you interpret the coordinates as points in some colour space.
Hope that's enough to keep you going! Let me know if it's not clear.
It sounds like you've made a good start.
Re the first issue: I believe there are ways to automatically choose an "interesting" portion of the set to zoom in on, but I don't know what they are. And I'm quite sure it involves more than just applying some linear function to your current bounding rectangle, which is what it sounds like you're doing.
So you could try to find out what these methods are (might get mathematically complicated), but if you're new to programming, you'll probably find it easier to let the user choose where to zoom. This is also more fun in the beginning, since you can run your program repeatedly and explore a new part of the set each time.
A simple way to do this is to let the user draw a rectangle over the image, and use your map
function to convert the pixel coordinates of the drawn rectangle to the new real and imaginary coordinates of your zoom area.
You could also combine both approaches: once you've found somewhere you find interesting by manually selecting the zoom area, you can set this as your "final destination", and have the code gradually and smoothly zoom into it, to create a nice movie.
It will always get gradually slower though, as you start using ever more precise coordinates, until you reach the limits of precision with double
and it becomes a pixellated mess. From there, if you want to zoom further, you'll have to look into arbitrary-precision arithmetic with BigDecimal
- and it will continue to get slower and slower.
Re the second issue: starting off by calculating a value of numIterations / maxIterations
(i.e. between 0 and 1) for each pixel is the right idea (I think this is basically what you're doing).
From there, there are all sorts of ways to convert this value to a colour, it's time to get creative!
A simple one is to have an array of a few very different colours. E.g. if you had white (0.0), red (0.25), green (0.5), blue (0.75), black (1.0), then if your calculated number was exactly one of the ones listed, you'd use the corresponding colour. If it's somewhere between, you blend the colours, e.g. for 0.3 you'd take:
((0.5-0.3)*red + (0.3-0.25)*green) / (0.5 - 0.25)
= 0.8*red + 0.2*green
Taking a weighted average of two colours is something I'll leave as an exercise ;)
(hint: take separate averages of the r, g, and b values. Playing with the alpha values could maybe also work).
Another one, if you want to get more mathsy, is to take an equation for a spiral and use it to calculate a point on a plane in HSB colour space (you can keep the brightness at some fixed value, say 1). In fact, any curve in 2D or 3D which you know how to write as an equation of one real variable can be used this way to give you smoothly changing colours, if you interpret the coordinates as points in some colour space.
Hope that's enough to keep you going! Let me know if it's not clear.
edited Nov 19 '18 at 20:19
answered Nov 19 '18 at 20:12
OpenSauceOpenSauce
7,17811728
7,17811728
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
add a comment |
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
Thank you for your reply. I will for sure take a closer look at the way to zoom in on interesting portions. After your recommendation, I tried user input way of zooming and it works. This is already a good alternative, however, I would still like to have some sort of automatic zoom. You say that I can make the program zoom in a saved location, but that is the thing I don't really know how to do. Either the image gets stretched, the zoom slows down or I zoom into a "white" part of the set, where you can't really see anything. (...)
– Eliturbo
Nov 20 '18 at 20:07
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
For the second issue, I don't really understand how to use the equation for a spiral to assign a color. I assume I use the ration of iteration/maxIterations for the angle or something? But how do I then use that information to get a color?
– Eliturbo
Nov 20 '18 at 20:10
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381336%2fjava-mandelbrot-visualization-questions-on-zooming-and-coloring%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Infinite zoom won't be possible on a computer, but you can zoom until precision is lost. 64 bit IEEE floating point numbers give you 18 digits of precision.
– duffymo
Nov 19 '18 at 19:30
@duffymo Yeah you're right. My goal is just to make a zoom until I can't anymore because of these or similar limitations. I'll clarify that in the post.
– Eliturbo
Nov 19 '18 at 19:34
I've done it with Java, but I can't access the BitBucket repo I saved it in from work. I'll try to remember to post it later.
– duffymo
Nov 19 '18 at 19:42