Skip to content

Commit

Permalink
creation of the fractal git
Browse files Browse the repository at this point in the history
this git is for one of my random project about Fractal.
  • Loading branch information
PhysicDev committed Feb 15, 2024
1 parent a7bb6b5 commit 6823d99
Show file tree
Hide file tree
Showing 14 changed files with 726 additions and 0 deletions.
Binary file added Fractal.jar
Binary file not shown.
52 changes: 52 additions & 0 deletions example/Cantor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package example;

import java.awt.Color;

import fractal.Fractal;
import fractal.Utilities;

public class Cantor {

public static void main(String[] args) {

Fractal Cantor=new Fractal(1,Utilities::Cantor);
Cantor.setMaxDepth(9);
Cantor.setSampling(100);

System.out.println("printing Cantor Set ...\n\n");

double test=3*3*3*3*3-1;
for(int j=0;j<6;j++) {
for(int i=0;i<=test;i++)
System.out.print((Cantor.checkPix((double)i/test)>=j)?"1":"_");
System.out.println("");
}

System.out.println("\ngenerating Picture ...\n\n");

//pre cmpile of the function for the benchmark
Cantor.drawFractal(3*3*3*3*3*3-1, 250, Color.WHITE, Color.BLACK, 5, new double[] {0d}, new double[] {1d}, new double[] {0d});
Cantor.drawFractalSampling(3*3*3*3*3*3-1, 250, Color.WHITE, Color.BLACK, 5, new double[] {0d}, new double[] {1d}, new double[] {0d});

long benchmarkStart=System.nanoTime();
Utilities.saveImage(Cantor.drawFractal(3*3*3*3*3*3-1, 200, Color.WHITE, Color.BLACK, 5, new double[] {0d}, new double[] {1d}, new double[] {0d})
,"Cantor_well_choosen_size_.png","png");
long perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");


benchmarkStart=System.nanoTime();
Utilities.saveImage(Cantor.drawFractal(1000, 200, Color.WHITE, Color.BLACK, 5, new double[] {0d}, new double[] {1d}, new double[] {0d})
,"Cantor_unprecise_.png","png");
perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");

benchmarkStart=System.nanoTime();
Utilities.saveImage(Cantor.drawFractalSampling(1000, 200, Color.WHITE, Color.BLACK, 5, new double[] {0d}, new double[] {1d}, new double[] {0d})
,"Cantor_precise_.png","png");
perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");

}

}
50 changes: 50 additions & 0 deletions example/Menger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package example;

import java.awt.Color;

import fractal.Fractal;
import fractal.Utilities;

public class Menger {

public static void main(String[] args) {

Fractal Menger=new Fractal(2,Utilities::Menger);
Menger.setMaxDepth(9);
Menger.setSampling(100);

System.out.println("printing Menger Fractal ...\n\n");
double test=3*3*3*3-1;
for(int j=0;j<=test;j++) {
for(int i=0;i<=test;i++)
System.out.print((Menger.checkPix((double)i/test,(double)j/test)>=4)?"O":" ");
System.out.println("");
}


System.out.println("\ngenerating Picture ...\n\n");

//pre compile of the function for the benchmark
Menger.drawFractal(3*3*3*3*3*3-1, 3*3*3*3*3*3-1, Color.WHITE, Color.BLACK, 5);
Menger.drawFractalSampling(3*3*3*3*3*3-1, 3*3*3*3*3*3-1, Color.WHITE, Color.BLACK, 5);

long benchmarkStart=System.nanoTime();
Utilities.saveImage(Menger.drawFractal(3*3*3*3*3*3-1, 3*3*3*3*3*3-1, Color.WHITE, Color.BLACK, 5)
,"Menger_well_choosen_size_.png","png");
long perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");

benchmarkStart=System.nanoTime();
Utilities.saveImage(Menger.drawFractal(1000, 1000, Color.WHITE, Color.BLACK, 5)
,"Menger_unprecise_.png","png");
perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");

benchmarkStart=System.nanoTime();
Utilities.saveImage(Menger.drawFractalSampling(1000, 1000, Color.WHITE, Color.BLACK, 5)
,"Menger_precise_.png","png");
perf=System.nanoTime()-benchmarkStart;
System.out.println("performance : "+perf/1e6+" ms\n");
}

}
65 changes: 65 additions & 0 deletions example/Sierpinsky.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package example;

import java.awt.Color;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import fractal.Fractal;
import fractal.Utilities;

public class Sierpinsky {



public static final int THREAD=6;

public static final boolean OVERWRITE=false;

public static void main(String[] args) {


String folderPath = "./sierpinskyAnim";
if(!(Files.exists(Paths.get(folderPath)) && Files.isDirectory(Paths.get(folderPath)))) {
try {
Files.createDirectories(Paths.get(folderPath));
} catch (IOException e) {
e.printStackTrace();
}
}

Fractal sierpinsky =new Fractal(2,Utilities::Sierpinski);
sierpinsky.setSampling(80);
sierpinsky.setMaxDepth(10);

Utilities.saveImage(sierpinsky.drawFractalSampling(1000, 1000,Color.WHITE, Color.BLACK,2.0, 8,new double[] {-1.0,0.0}
,new double[]{2.0,0},new double[]{0,2.0}),
"sierpinsky_precise_"+".png","png");

ExecutorService executor = Executors.newFixedThreadPool(THREAD);
int frames=1000;
for(int i=0;i<frames-1;i+=1) {
final int taskId = i;
if (!Files.exists(Paths.get(folderPath+"/output"+String.format("%03d", taskId)+".png")) || OVERWRITE)
executor.submit(() -> {
System.out.println("Task " + taskId + " is running on thread " + Thread.currentThread().getName());
double zoomLvl=Math.exp(-taskId/721.35)*2;
double bright=(1.25-(double)(taskId%500)/500d*1.0/4.0)*1.5d;
Utilities.saveImage(sierpinsky.drawFractalSampling(1000, 1000,Color.WHITE, Color.BLACK,bright, 8+((taskId>=500)?1:0),new double[] {-1+taskId/4000d,taskId/2000d}
,new double[]{zoomLvl,0},new double[]{0,zoomLvl}),
folderPath+"/output"+String.format("%03d", taskId)+".png","png");
});
}
executor.shutdown();

try {
executor.awaitTermination((long) 1e10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
Binary file added images/Menger_precise_.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Menger_precise_zoom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Menger_unprecise_.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/Menger_unprecise_zoom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/schemaPix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added javaDocs.zip
Binary file not shown.
61 changes: 61 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# JAVA Fractal Library

this library allow you to create fractal and render them in 2D.

the library consist in one class named Fractal.

## setup

to install the library download the git, and add the file **Fractal.jar** to the environment variable **Classpath**

## basic utilisation

in order to use it you need to create a static method to compute the maximum fractal depth in which a point is in the fractal. Usualy the easiest way to do that is by making a recursive function.

the fractal also need a dimension, this is use to ensure that the program will work as intented and prevent error.

```java
import fractal.Fractal;

public class Test{
static int fractalInit(double[] coord,int maxDepth){
//init method
return fractal(coord,maxDepth, inital argument);
}

static int fractal(double[] coord,int maxDepth, more arguments){
//something like this :
/**
* 1. Checking if not in fractal : return 0
* 2. Checking if reach maxDepth : return 1
* 3. recursive call
*/
}

//we give the init method as argument of the fractal
public Fractal someFractal(2,Test::fractalInit)
}
```

the maximum depth of the fractal is an attribute of the class that can be modified.

## rendering

the fractal class can compute an instance of the java class BufferedImage of the fractal, to do that you have to specify the size of the Image, the color of the fractal and the background and the maximum depth which indicate how deep in the fractal a point need to be to be consider in the fractal.

additionaly you can add information about the position of the camera, more precisely the origin of the camera (the origin is at the upper left corner of the image) and two vector indicating the direction along the X and Y axis corresponding the horizontal and vertical axis of the image. This system allow to render fractal with dimension higher than 2 by selecting a 2D section of a 3D or higher dimension space and redering the fractal in this plane.

there are two main way of rendering the image with the class Fractal.

the first method is the fastest, but is less precise as it compute only the point corresponding to the upper left point of every pixel. this can cause a pixel to be fully drawn or not drawn only because one of its point is or is not in the fractal.

in the next image the pixel indicated in red will be black as the upper left corner of the pixel is in a dark area of the fractal even if the pixel content contain more white.
<img src="images/schemaPix.png" alt="image" width="200" height="auto" margin="auto">

to solve this issue, i've created another drawing method that use a random sampling of points in the pixel to determine on much the pixel should be drawn.

here a comparaison of the render :

<img src="images/Menger_unprecise_.png" alt="image" width="250" height="auto" margin="auto">
<img src="images/Menger_precice_.png" alt="image" width="250" height="auto" margin="auto">

Loading

0 comments on commit 6823d99

Please sign in to comment.