在没有概率的情况下渲染Barnsley Fern分形

时间:2014-06-04 12:23:54

标签: java algorithm fractals

我正在制作一个程序,使巴恩斯利蕨的分形突变。我的程序完美无瑕地运行并生成我希望它生成的输出。我进一步阅读有关迭代函数系统的内容,并阅读这些分形可以在不使用概率的情况下渲染,并在每次迭代中执行所有四个仿射变换。我知道这会增加计算时间但我想知道如何从图像中删除概率?

例如,吸取蕨类植物的四种功能的概率分别为2%,84%,7%和7%。

对于那些说“我在帖子中找不到问题”的人来说,这是一个大胆的问题。 :我们如何在每次迭代中使用所有四个函数,而不是根据概率选择四个函数中的一个?

以下是相关代码:

AffineTransformation.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());
}   

修改
我想通过抛弃probs来实现的主要目标。是测试我自己的转换函数,显然我不知道除了试错之外的概率。有帮助吗?

详细说明,假设我还有其他四个功能,我不知道使用的概率是多少,是否有方法可以通过反复试验来了解概率。

2 个答案:

答案 0 :(得分:1)

每个变换都有一个特定的功能(见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的描述也有一个例子,使用整个图像并应用转换来获取新图像,然后重新开始使用新图像。这不需要随机性。

我无法测试这个,所以不知道它是否真的有效。

答案 1 :(得分:1)

好吧,我找到了一种方法来确定使用仿射变换函数应该用于完美图像的概率。需要渲染概率的方法称为随机迭代算法

我将在这里描述的方法取自 Michael F. Barnsley 的书, Fractals Everywhere (第3章,标题下:从迭代函数系统计算分形的两种算法(The。

每个仿射变换函数可以表示为:

Affine Transformation

现在,如果我们使用 N 函数绘制分形,则每个函数使用的概率 P i 由下式给出: / p>

Probability function

其中 | det。 i | 是矩阵 A i 的决定因素的绝对值,由下式给出: | ad - bc |

如果对于某些 i ,我们得到 P i = 0 我们分配 P i 一个小的正值,如0.001。

虽然最终使用概率进行渲染但应注意ΣP i = 1

示例:

假设我们有四个仿射变换函数,矩阵值(a,b,c,d),如下所示:

  

1 = (0,0,0,0.25)
  A 2 = (0.95,0.005,-0.005,0.93)
   3 = (0.035,-0.2,0.16,0.04)
   4 = ( - 0.04,0.2,0.16,0.04)

现在:

  

| DET。 A <子> 1 | = |(0 * 0.25) - (0 * 0)| = 0
  | DET。 A <子> 2 | = |(0.95 * 0.93) - (0.005 * -0.005)| = 0.883525
  | DET。 A <子> 3 | = |(0.035 * 0.04) - ( - 0.2 * 0.16)| = 0.0334
  | DET。 A <子> 4 | = |(-0.04 * 0.04) - (0.2 * 0.16)| = 0.0336

总和所有 A i s = (0 + 0.883525 + 0.0334 + 0.0336)= 0.950525

然后概率为:

  

P 1 =0≈ 0.01
  P 2 = 0.883525 / 0.950525 =0.929512637≈ 0.93
  P 3 = 0.0334 / 0.950525 =0.0351384761≈ 0.03
  P 4 = 0.0336 / 0.950525 =0.0353488861≈ 0.03

因此,最终概率为: 1%,93%,3%,3%,总计可达100%,可用作支票。

顺便说一下,这四个函数会产生巴恩斯利蕨的突变。