java - code - fractal en processing
Generando fractal Remolino (3)
¡Esto es genial, me equivoqué al pensar que se requería un tiempo de ejecución exponencial! ¡Los fractales parecían más dimensionales que mi imaginación!
Gracias @ Jan Dvorak!
Lo siguiente también funciona (en mis coordenadas, xcenter=300
, ycenter=100
y radius=50
son parámetros de dibujo globales) y funciona más rápido:
void drawFractal2(Graphics g) {
double x1 = 0;
double y1 = 0;
double x2 = 0;
double y2 = 0;
double p;
g.fillOval(xcenter + (int) (x1 * radius), ycenter + (int) (y1 * radius), 3, 3);
for(int i=0; i<100000; ++i) {
p = Math.random();
if (p < p1) {
x2 = x1(x1, y1);
y2 = y1(x1, y1);
}
else {
x2 = x2(x1, y1);
y2 = y2(x1, y1);
}
g.fillOval(xcenter + (int) (x2 * radius), ycenter + (int) (y2 * radius), 3, 3);
x1 = x2;
y1 = y2;
}
}
y la imagen es mejor
Necesito dibujar un remolino fractal usando el algoritmo Iterated Function System .
Hay coeficientes para este fractal:
0.745455 -0.459091 0.406061 0.887121 1.460279 0.691072 0.912675
-0.424242 -0.065152 -0.175758 -0.218182 3.809567 6.741476 0.087325
Y aquí está mi código:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Surface extends JPanel {
double a1 = 0.745455;
double b1 = -0.459091;
double d1 = 0.406061;
double e1 = 0.887121;
double c1 = 1.460279;
double f1 = 0.691072;
double p1 = 0.912675;
double a2 = -0.424242;
double b2 = -0.065152;
double d2 = -0.175758;
double e2 = -0.218182;
double c2 = 3.809567;
double f2 = 6.741476;
double p2 = 0.087325;
double x1(double x, double y) {
return a1 * x + b1 * y + c1;
}
double y1(double x, double y) {
return d1 * x + e1 * y + f1;
}
double x2(double x, double y) {
return a2 * x + b2 * y + c2;
}
double y2(double x, double y) {
return d2 * x + e2 * y + f2;
}
public void paint(Graphics g) {
drawFractal(g);
}
void drawFractal(Graphics g) {
double x1 = 300;
double y1 = 300;
double x2 = 0;
double y2 = 0;
g.fillOval(300 + (int) x1, 300 + (int) y1, 3, 3);
for (int i = 0; i < 10000; i++) {
double p = Math.random();
if (p < 0.91675) {
x2 = x1(x1, y1);
y2 = y1(x1, y1);
g.fillOval(300 + (int) x2, 300 + (int) y2, 3, 3);
x1 = x2;
y1 = y2;
} else {
x2 = x2(x1, y1);
y2 = y2(x1, y1);
g.fillOval(300 + (int) x2, 300 + (int) y2, 3, 3);
x1 = x2;
y1 = y2;
}
}
}
}
Lamentablemente, con este código me sale una imagen equivocada:
Sería genial si alguien pudiera señalar mi error.
Tu generación parece correcta (es decir, no hagas x1 = x2 +300; y1 = y2 +300;
), pero tu problema es que estás fuera de la escala a los efectos del renderizado. Esto significa que hay muy pocos puntos que quedan fuera del centro de la imagen.
Su ventana es [0..600]x[0..600]
. Intente multiplicar x2
e y2
con 50, de modo que represente la región [-6..6]x[-6..6]
lugar de la región [-300..300]x[-300..300]
del espacio.
Tenga en cuenta que debería ser suficiente dibujar píxeles individuales (como líneas para sí mismo) en lugar de óvalos de 3x3.
int xp = 300 + (int) (x2 * scale);
int yp = 300 + (int) (y2 * scale);
g.drawLine(xp, yp, xp, yp);
Dependiendo de lo que se procesa, es posible que deba ajustar la escala ligeramente para obtener toda la imagen con límites razonables. Tenga en cuenta que la segunda transformación compensa por -6.7
, por lo que una escala de 30 debería ser aproximadamente correcta.
También tenga en cuenta que al usar x1 = x2 +300; y1 = y2 +300;
x1 = x2 +300; y1 = y2 +300;
cambias las transformaciones y obtienes un fractal diferente (en una escala que esperas).
A CONTINUACIÓN ES MI RESPUESTA INCORRECTA
Pero muestra cómo los fractales son más grandes que la intuición, así que lo guardo.
Supongo que su algoritmo debería ser similar a un árbol (recursivo) mientras que el suyo es lineal. Estás dibujando una cadena de puntos, transformándolos uno tras otro. Entonces obtienes una cadena tipo espiral. No puede generar ninguna imagen fractal en principio.
TENGO TU IMAGEN
Tienes 2 errores:
1) pasas 300 tanto en iteración como en desplazamiento de dibujo. Esto es menor
2) Tu algoritmo es lineal. El algoritmo lineal no puede dibujar una imagen similar a un árbol. Si usa valores aleatorios, debe ejecutar el algoritmo varias veces. Una cadena dibuja solo una parte aleatoria de la imagen.
Obtuve tu foto con el siguiente algoritmo recursivo. Funciona lento, pero debes mejorarlo.
void drawFractal(Graphics g, double x1, double y1, int depth) {
double x2 = 0;
double y2 = 0;
if( depth > 20 ) {
return;
}
g.fillOval(xcenter + (int) (x1 * radius), ycenter + (int) (y1 * radius), 3, 3);
x2 = x1(x1, y1);
y2 = y1(x1, y1);
drawFractal(g, x2, y2, depth+1);
x2 = x2(x1, y1);
y2 = y2(x1, y1);
drawFractal(g, x2, y2, depth+1);
}
para ejecutarlo utilicé
public void paint(Graphics g) {
//drawFractal(g);
drawFractal(g, 0, 0, 0);
}
los parámetros son
int xcenter = 300;
int ycenter = 100;
int radius = 50;
la imagen es la siguiente: