package fractal;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.imageio.ImageIO;
/
@author Chris Philip
*/*
*public class DragonFractal {*
*private static boolean[] iteration;*
*private static int lineLength, xMin, xMax, yMin, yMax, width, height;*
*public static void main(String args[]) {*
*int iterations=Integer.parseInt(args[0]);*
*calcTurns(iterations);*
*calcSize(iterations);*
*draw(iterations);*
*}*
*private static void calcTurns(int iterations) {*
*boolean old[];*
*iteration = new boolean[] {true};*
*for(int i=2;i<=iterations;i++) {*
*old=iteration;*
*iteration=new boolean[old.length*2+1];*
*iteration[old.length]=true;*
*System.arraycopy(old, 0, iteration, 0, old.length);*
*System.arraycopy(old, 0, iteration, old.length+1, old.length/2);*
*iteration[old.length*3/2+1]=false;*
*System.arraycopy(old,old.length/2+1,iteration,(iteration.length-3)*3/4+3,old.length/2);*
*}*
*}*
*private static void calcSize(int iterations) {*
*double angle=Math.PI/4*iterations;*
*lineLength=2+(iterations%2);*
*int xStart=0,*
*xEnd=xStart+(int)(lineLength*Math.cos(angle)),*
*yStart=0,*
*yEnd=yStart+(int)(lineLength*Math.sin(angle));*
*xMin=xStart>xEnd?xEnd:xStart;*
*xMax=xStart>xEnd?xStart:xEnd;*
*yMin=yStart>yEnd?yEnd:yStart;*
*yMax=yStart>yEnd?yStart:yEnd;*
*for(int i=0; i<iteration.length; i++) {*
*angle+=Math.PI/2*(iteration?-1:1);
xStart=xEnd;
yStart=yEnd;
xEnd=xStart+(int)(lineLength*Math.cos(angle));
yEnd=yStart+(int)(lineLength*Math.sin(angle));
xMin=xMin>xEnd?xEnd:xMin;
xMax=xMax<xEnd?xEnd:xMax;
yMin=yMin>yEnd?yEnd:yMin;
yMax=yMax<yEnd?yEnd:yMax;
}
width=xMax-xMin+1;
height=yMax-yMin+1;
+}+
+private static void draw(int iterations) {+
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
BigDecimal counter=new BigDecimal("1"),
max=(new BigDecimal("2")).pow(iterations);
double angle=Math.PI/4*iterations;
int xStart=-xMin,
xEnd=xStart(int)(lineLength*Math.cos(angle)),
yStart=-yMin+1,
yEnd=yStart+(int)(lineLength*Math.sin(angle));
for(boolean turn:iteration) {
g.setColor(new Color(Color.HSBtoRGB((counter.divide(max, 3, RoundingMode.UP)).floatValue(), 1, 1)));
counter = counter.add(BigDecimal.ONE);
g.drawLine(xStart,height-yStart,xEnd,height-yEnd);
angle+=Math.PI/2*(turn?-1:1);
xStart=xEnd;
yStart=yEnd;
xEnd=xStart+(int)(lineLength*Math.cos(angle));
yEnd=yStart+(int)(lineLength*Math.sin(angle));
}
g.setColor(new Color(Color.HSBtoRGB((counter.divide(max, RoundingMode.UP)).floatValue(), 1, 1)));
g.drawLine(xStart,height-yStart,xEnd,height-yEnd);
try {
BufferedImage bi = image;
File outputfile = new File("C:\\Users\\Chris\\Desktop\\NewDragonCurve-"+iterations+".png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
System.out.println("YOU FAIL");
}
}
}
Magical_Tiger wrote:Do you expect people to read the code when it's formatted like that?
Here is my code, all in one class:
package fractal;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import javax.imageio.ImageIO;
/**
*
* @author Chris Philip
*/
public class DragonFractal {
private static boolean[] iteration;
private static int lineLength, xMin, xMax, yMin, yMax, width, height;
public static void main(String args[]) {
int iterations=Integer.parseInt(args[0]);
calcTurns(iterations);
calcSize(iterations);
draw(iterations);
}
private static void calcTurns(int iterations) {
boolean old[];
iteration = new boolean[] {true};
for(int i=2;i<=iterations;i++) {
old=iteration;
iteration=new boolean[old.length*2+1];
iteration[old.length]=true;
System.arraycopy(old, 0, iteration, 0, old.length);
System.arraycopy(old, 0, iteration, old.length+1, old.length/2);
iteration[old.length*3/2+1]=false;
System.arraycopy(old,old.length/2+1,iteration,(iteration.length-3)*3/4+3,old.length/2);
}
}
private static void calcSize(int iterations) {
double angle=Math.PI/4*iterations;
lineLength=2+(iterations%2);
int xStart=0,
xEnd=xStart+(int)(lineLength*Math.cos(angle)),
yStart=0,
yEnd=yStart+(int)(lineLength*Math.sin(angle));
xMin=xStart>xEnd?xEnd:xStart;
xMax=xStart>xEnd?xStart:xEnd;
yMin=yStart>yEnd?yEnd:yStart;
yMax=yStart>yEnd?yStart:yEnd;
for(int i=0; i<iteration.length; i++) {
angle+=Math.PI/2*(iteration?-1:1);
xStart=xEnd;
yStart=yEnd;
xEnd=xStart+(int)(lineLength*Math.cos(angle));
yEnd=yStart+(int)(lineLength*Math.sin(angle));
xMin=xMin>xEnd?xEnd:xMin;
xMax=xMax<xEnd?xEnd:xMax;
yMin=yMin>yEnd?yEnd:yMin;
yMax=yMax<yEnd?yEnd:yMax;
}
width=xMax-xMin+1;
height=yMax-yMin+1;
// System.out.println("Iteration "+iterations+
// ":\tWidth: "+(xMax-xMin+1)+
// "\tHeight: "+(yMax-yMin+1)+
// "\tXMax: "+xMax+
// "\tMMin: "+xMin+
// "\tYMax: "+yMax+
// "\tYMin: "+yMin);
}
private static void draw(int iterations) {
BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics g=image.getGraphics();
BigDecimal counter=new BigDecimal("1"),
max=(new BigDecimal("2")).pow(iterations);
double angle=Math.PI/4*iterations;
int xStart=-xMin,
xEnd=xStart+(int)(lineLength*Math.cos(angle)),
yStart=-yMin+1,
yEnd=yStart+(int)(lineLength*Math.sin(angle));
for(boolean turn:iteration) {
g.setColor(new Color(Color.HSBtoRGB((counter.divide(max, 3, RoundingMode.UP)).floatValue(), 1, 1)));
counter = counter.add(BigDecimal.ONE);
g.drawLine(xStart,height-yStart,xEnd,height-yEnd);
angle+=Math.PI/2*(turn?-1:1);
xStart=xEnd;
yStart=yEnd;
xEnd=xStart+(int)(lineLength*Math.cos(angle));
yEnd=yStart+(int)(lineLength*Math.sin(angle));
}
g.setColor(new Color(Color.HSBtoRGB((counter.divide(max, RoundingMode.UP)).floatValue(), 1, 1)));
g.drawLine(xStart,height-yStart,xEnd,height-yEnd);
try {
BufferedImage bi = image;
File outputfile = new File("C:\\Users\\Chris\\Desktop\\NewDragonCurve-"+iterations+".png");
ImageIO.write(bi, "png", outputfile);
} catch (IOException e) {
System.out.println("YOU FAIL");
}
}
}
Magical_Tiger wrote:The array is part of the problem since a large array means less memory for the image.
The array isn't the problem,
I can calculate the turns up to the 29th iteration almost instantly but the length of the 30th iteration is greater than the range of an int when I call array.length.Larger than 2 billion?
I have both x86 and x64 java, but I am not specifying which to use, should I?It depends on what you got in your path/environment. I don't know if you are using an IDE or not, but you need to configure the IDE to use the 64 bit version if you also got a 32 bit version.
Magical_Tiger wrote:What do you mean by that? You can create a tile in a loop. That tile should however not depend on data from any other tile, and you should not try to keep all tiles in memory.
If I were to create tiles, would I have to create each tile independently or could I do a loop.
I am asking from a memory standpoint, but also would I not have to at some point create the full size image even if I tile it?Why do you need the full size image?
Magical_Tiger wrote:You would never be able to allocate an array that is large enough in that case. Doesn't matter if you got 50 terrabytes of memory. The size of an array is based on an int.
The length of the array 2^iteration - 1 so, yeah ITS OVER 2 BILLION.
I am using netbeans 6.8 and I believe that there is no 64-bit version, but is there a way to configure it to use the 64-bit java?Don't know. I'm using Eclipse, and you can configure eclipse to execute programs using the 64-bit VM. I expect you to be able to do the same in Netbeans, but you don't need to do that if you are executing from command line.
I have built the program into a .jar and am running it from CMD so do I actually need to change to x64 in my IDE.No
And I understand how to tile it know thanks.What does java -version say if you enter that on the command line?
Magical_Tiger wrote:That means that you are using 64-bit VM from command line if that is what java -version displayed.
My java version is... 1.6.0_17
java SE is1.6.0_17-bo4
hotspot 64-bit VM 14.3-b01