1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
| public class FractalPanel extends JPanel {
private boolean started;
private volatile boolean done;
private volatile Image image;
public FractalPanel() {
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if ( image!=null ) {
g.drawImage(image, 0, 0, this);
}
}
public void start(FractalRenderer renderer, long trefresh) {
trefresh = Math.max(0, trefresh);
synchronized(this) {
if ( started ) return;
started=true;
}
done=false;
int iteration = 1;
while (!done) {
long time = System.currentTimeMillis();
int width=getWidth();
int height=getHeight();
Image image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
//g.setClip(0, 0, getWidth(), getHeight());
try {
String message = renderer.getName() + " / iteration " + iteration;
if ( !renderer.render(g, iteration++, width, height) ) {
done = false;
}
renderMessage(g, message, height);
} finally {
g.dispose();
}
this.image=image;
repaint();
time = trefresh - (System.currentTimeMillis()-time);
if ( time>0) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(this) {
started=false;
image=null;
}
}
private void renderMessage(Graphics g, String message, int height) {
FontMetrics fm = g.getFontMetrics();
g.setColor(Color.WHITE);
g.fillRect(10, height - 10 - fm.getAscent() , (int)fm.getStringBounds(message, g).getWidth()+20, fm.getHeight() );
g.setColor(Color.RED);
g.drawString(message, 20, height-10);
}
public void stop() {
synchronized(this) {
if ( !started ) return;
started=false;
done=false;
}
}
public static interface FractalRenderer {
boolean render(Graphics g, int iteration, int width, int height);
String getName();
}
// méthode de démo
public static void main(String[] args) {
JFrame frame = new JFrame("Exemple");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FractalPanel panel = new FractalPanel();
frame.add(panel);
frame.setSize(640, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.start(new HilbertRenderer(),1000);
//panel.start(new SierpinkiTapisRenderer(),1000);
}
// stateful non thread-safe class
public static class HilbertRenderer implements FractalRenderer {
//Point de localisation
private Point location;
//Tableau de couleurs
private Color colorWheel[];
//Indice du tableau de couleur
private int colorIdx;
public HilbertRenderer () {
//Instancie le tableau de 1024 couleurs et instancie l'indice à 0
colorWheel = new Color[1024];
colorIdx = 0;
for(int i = 0; i < 128; i++)
{
colorWheel[i] = new Color(0, 255 - i, i);
}
}
@Override
public String getName() {
return "Hilbert";
}
@Override
public boolean render(Graphics g, int iteration, int width, int height) {
hilbert(g, iteration, width, height);
return true;
}
public void hilbert(Graphics g, int iteration, int largeur, int hauteur) {
//La localisation est à null
location = null;
//On appelle la fonction de dessous
hilbert(g, iteration, 0, 0, largeur, hauteur, 0, 225);
}
public void hilbert(Graphics g, int ite, int j, int k, int larg, int haut, int j1, int k1) {
//La largeur et la hauteur sont divisé par 2
int largDiv = larg / 2;
int hautDiv = haut / 2;
if(ite == 0)
{
if(location != null)
{
//Définition de la couleur fixée par le tableau de couleur et son indice
g.setColor(colorWheel[colorIdx]);
//Dessine une ligne avec 2 points définis par les coordonnées
//(location.x, location.y) et (j+largDiv, k+hautDiv)
g.drawLine(location.x, location.y, j + largDiv, k + hautDiv);
//Permet de définir l'indice du tableau de couleur pour créer un dégradé de couleur
if(++colorIdx >= 1024)
{
colorIdx = 0;
}
}
//Définition de la localisation
location = new Point(j + largDiv, k + hautDiv);
return;
}
//En fonction de la valeur de j1 et k1, on fait des appels recursifs de la fonction
//Donc j1 et k1 peuvent changer à chaque récursivité
switch(j1)
{
default:
break;
case 0:
if(k1 == 225)
{
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 90, 225);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 0, 225);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 0, 225);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 270, 45);
}
if(k1 == 135)
{
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 270, 135);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 0, 135);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 0, 135);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 90, 315);
}
break;
case 90:
if(k1 == 315)
{
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 180, 315);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 90, 315);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 90, 315);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 0, 135);
}
if(k1 == 225)
{
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 0, 225);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 90, 225);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 90, 225);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 180, 45);
}
break;
case 180:
if(k1 == 45)
{
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 270, 45);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 180, 45);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 180, 45);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 90, 225);
}
if(k1 == 315)
{
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 90, 315);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 180, 315);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 180, 315);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 270, 135);
}
break;
case 270:
if(k1 == 45)
{
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 180, 45);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 270, 45);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 270, 45);
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 0, 225);
}
if(k1 == 135)
{
hilbert(g, ite - 1, j + largDiv, k + hautDiv, largDiv, hautDiv, 0, 135);
hilbert(g, ite - 1, j, k + hautDiv, largDiv, hautDiv, 270, 135);
hilbert(g, ite - 1, j, k, largDiv, hautDiv, 270, 135);
hilbert(g, ite - 1, j + largDiv, k, largDiv, hautDiv, 180, 315);
}
break;
}
}
}
public static class SierpinkiTapisRenderer implements FractalRenderer {
//Représente le nombre de fois que l'on repète les formules de Sierpinki
//Tableau de couleurs
private Color colorWheel[];
//Indice du tableau de couleur
private int colorIdx;
public SierpinkiTapisRenderer(){
//Instancie le tableau de 400 couleurs et instancie l'indice à 0
colorWheel = new Color[400];
colorIdx = 0;
for(int i = 0; i < 200; i++)
{
colorWheel[i] = new Color(i + 56, 4, i + 56);
}
// Remplissage de la suite du tableau de couleur dans une couleur avec
// son dégradé
for(int j = 0; j < 200; j++)
{
colorWheel[j + 200] = new Color(255, 255 - j, 255 - j );
}
}
@Override
public String getName() {
return "Tapis de Sierpi\u0144ski";
}
@Override
public boolean render(Graphics g, int iteration, int width, int height) {
tapis(g, iteration, 0, 0, width, height);
return true;
}
public void tapis(Graphics g, int iteration, int j, int k, int larg, int haut)
{
if(iteration == 1)
{
g.setColor(colorWheel[colorIdx]);
//Dessine un carré de sommet j, k, largeur, hauteur avec une couleur définie auparavant
g.fillRect(j, k, larg, haut);
//Permet de définir l'indice du tableau de couleur pour créer un dégradé de couleur
if(++colorIdx >= 400)
colorIdx = 0;
//g.setColor(Color.BLACK);
//Dessine un carré de sommet j, k, largeur, hauteur en noir
g.drawRect(j, k, larg, haut);
}
else
{
//On divise par 3 la hauteur et la largeur pour pouvoir dessiner 9 carrés
int largDiv = larg / 3;
int hautDiv = haut / 3;
//Permet de dessiner 8 carrés dans le carré précédemment dessiné
tapis(g, iteration - 1, j, k, largDiv, hautDiv);
tapis(g, iteration - 1, j + largDiv, k, largDiv, hautDiv);
tapis(g, iteration - 1, j + 2 * largDiv, k, largDiv, hautDiv);
tapis(g, iteration - 1, j, k + hautDiv, largDiv, hautDiv);
tapis(g, iteration - 1, j + 2 * largDiv, k + hautDiv, largDiv, hautDiv);
tapis(g, iteration - 1, j, k + 2 * hautDiv, largDiv, hautDiv);
tapis(g, iteration - 1, j + largDiv, k + 2 * hautDiv, largDiv, hautDiv);
tapis(g, iteration - 1, j + 2 * largDiv, k + 2 * hautDiv, largDiv, hautDiv);
}
}
}
} |
Partager