我正在制作一个程序来呈现巴恩斯利蕨分形的突变。我的程序完美无缺地生成了我希望它生成的输出。我进一步阅读了迭代函数系统,并了解到这些分形可以在不使用概率的情况下进行渲染,并在每次迭代中执行所有四个仿射变换。我知道这会增加计算时间,但我想知道我们如何才能消除图片中的概率?
例如,绘制我的蕨类植物的四个函数的概率分别为 2%、84%、7% 和 7%。
对于那些说“我在帖子中找不到问题”的人,这里再次以粗体显示问题。 : 我们如何在每次迭代中使用所有四个函数而不是根据概率选择四个函数之一?
相关代码如下:
仿射变换.java
public class AffineTransformation
{
private double[][] transformation=new double[2][2];
private double[][] translation=new double[2][1];
public AffineTransformation(double a,double b,double c,double d,double e,double f)
{
transformation[0][0] = a;
transformation[0][1] = b;
transformation[1][0] = c;
transformation[1][1] = d;
translation[0][0] = e;
translation[1][0] = f;
}
public Point transform(Point point)
{
double x = point.getX();
double y = point.getY();
double u = 0.0;
double v = 0.0;
u = transformation[0][0]*x + transformation[0][1]*y;
v = transformation[1][0]*x + transformation[1][1]*y;
u = u + translation[0][0];
v = v + translation[1][0];
return new Point(u,v);
}
}
渲染循环
AffineTransformation f1 = new AffineTransformation(0,0,0,0.25,0,-0.4);
AffineTransformation f2 = new AffineTransformation(0.95,0.005,-0.005,0.93,-0.002,0.5);
AffineTransformation f3 = new AffineTransformation(0.035,-0.2,0.16,0.04,-0.09,0.02);
AffineTransformation f4 = new AffineTransformation(-0.04,0.2,0.16,0.04,0.083,0.12);
Point point = new Point(0.5,0.0);
int N=Width*Height;
for(int i=0;i< N*25;i++)
{
Point newpoint = new Point();
double probability = Math.random();
if(probability < 0.02)
{
newpoint = f1.transform(point);
color=new Color(0x002147);
}
else if(probability < 0.86)
{
newpoint = f2.transform(point);
color=new Color(0x120A8F);
}
else if(probability < 0.93)
{
newpoint = f3.transform(point);
color=new Color(0x002147);
}
else
{
newpoint = f4.transform(point);
color=new Color(0x002147);
}
point = newpoint;
int X=((int)(point.getX()*W/3)+W/2)/2 + W/4-1;
int Y=(int)(point.getY()*H/8) + H/9 -1;
image.setRGB(X,Y, color.getRGB());
}
编辑
我想通过丢弃概率来实现的主要目标。正在测试我自己的转换函数,显然我不会知道概率,除非通过反复试验。有什么帮助吗?
详细说明,假设我有四个其他函数,但我不知道使用什么概率,有没有一种方法可以知道概率,除了通过反复试验。
最佳答案
每个转换都有特定的功能(参见 Wikipedia) 所以像我们已经尝试过的那样将它们链接在一起是行不通的。
什么会起作用是这样的:
for(int i=0;i< N*25;i++)
{
Point newpoint1 = f1.new Point(0,0);
Point newpoint2 = f1.new Point(0,0);
Point newpoint3 = f1.new Point(0,0);
Point newpoint4 = f1.new Point(0,0);
double probability = Math.random();
newpoint1 = f1.transform(point);
newpoint2 = f2.transform(point);
newpoint3 = f3.transform(point);
newpoint4 = f4.transform(point);
drawToImage(image, newpoint1, Width, Height, Color.red);
drawToImage(image, newpoint2, Width, Height, Color.green);
drawToImage(image, newpoint3, Width, Height, Color.red);
drawToImage(image, newpoint4, Width, Height, Color.LIGHT_GRAY);
if(probability < 0.02)
{
point = newpoint1;
}
else if(probability < 0.86)
{
point = newpoint2;
}
else if(probability < 0.93)
{
point = newpoint3;
}
else
{
point = newpoint4;
}
}
问题是您仍然必须随机选择下一步的点,否则将无法正常工作。您只需增加每个周期的计算量。
您是否有指向“可以在没有概率的情况下运行”声明的来源的链接,甚至更好的关于这样做的改进的声明?
稍作阅读后编辑
您现在使用的算法是逐点生成分形。参见 Chaos game
IFS 的维基百科描述也有一个使用整个图像并应用转换以获得新图像然后重新开始使用新图像的示例。这不需要随机性。
我无法测试这个,所以不知道它是否真的有效。
关于java - 在没有概率的情况下渲染 Barnsley Fern 分形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24037365/