我需要使用算法Iterated Function System绘制分形漩涡。
这个分形有一些系数:
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
这是我的代码:
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;
}
}
}
}
不幸的是,使用此代码我得到了错误的图片:
如果有人可以指出我的错误,那将会很棒。
答案 0 :(得分:14)
你的世代似乎是正确的(即不要做x1 = x2 +300; y1 = y2 +300;
),但是你的问题是你为了渲染的目的而偏离规模。这意味着很少有点落在图像的正中心。
您的窗口是[0..600]x[0..600]
。尝试将x2
和y2
乘以50,以便渲染[-6..6]x[-6..6]
区域而不是[-300..300]x[-300..300]
区域。
请注意,绘制单个像素(作为自身的线条)而不是3x3椭圆就足够了。
int xp = 300 + (int) (x2 * scale);
int yp = 300 + (int) (y2 * scale);
g.drawLine(xp, yp, xp, yp);
根据渲染的内容,您可能需要稍微调整缩放以使整个图像具有合理的边界。请注意-6.7
的第二个转换偏移,因此30的标度应该是正确的。
另请注意,通过使用x1 = x2 +300; y1 = y2 +300;
,您可以更改转换并获得不同的分形(按照您期望的比例)。
答案 1 :(得分:4)
这很棒,我认为指数运行时需要!分形看起来比我的想象更具维度!
谢谢@Jan Dvorak!
以下也有效(在我的坐标中,xcenter=300
,ycenter=100
和radius=50
是全局绘图参数)并且工作得更快:
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;
}
}
并且图片更好
答案 2 :(得分:1)
以下是我不正确的答案
但它表明分形比直觉更大,所以我保留它。
我猜你的算法应该是树状的(递归的)而你的算法是线性的。你只是绘制一个点链,一个接一个地转换它。所以你得到一些螺旋状的链条。它原则上不能生成任何分形图。
我给你的照片
你有2个错误:
1)你将300传递给迭代并作为绘图移位。这是次要的。
2)你的算法是线性的。线性算法无法绘制树状图片。如果使用随机值,则应多次运行算法。一条链只画出图片的一个随机部分。
我用下面的递归算法得到你的照片。它运作缓慢,但你要改进它。
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);
}
运行它我用
public void paint(Graphics g) {
//drawFractal(g);
drawFractal(g, 0, 0, 0);
}
参数
int xcenter = 300;
int ycenter = 100;
int radius = 50;
图片如下: