【问题标题】:Rendering Barnsley Fern fractal without the probabilities在没有概率的情况下渲染巴恩斯利蕨分形
【发布时间】:2014-06-04 12:23:53
【问题描述】:

我正在编写一个程序来呈现巴恩斯利蕨分形的突变。我的程序完美运行,并准确生成了我希望它生成的输出。我进一步阅读了有关迭代函数系统的信息,并了解到这些分形可以在不使用概率的情况下进行渲染,并在每次迭代中执行所有四个仿射变换。我知道这会增加计算时间,但我想知道我们如何才能消除图片中的概率?

例如,绘制我的蕨类植物的四个函数的概率分别为 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());
}   

编辑
我想通过丢弃概率来实现的主要目标。正在测试我自己的转换函数,除非通过反复试验,我显然不会知道概率。那里有什么帮助吗?

详细来说,假设我有四个其他函数,但我不知道要使用什么概率,有没有一种方法可以知道概率,除了通过反复试验。

【问题讨论】:

  • 我不完全确定我是否理解正确,但我喜欢你想要的:point = f4.transform(f3.transform(f2.transform(f1.transform(point)))); //Ad infinitum 但这给你留下了选择颜色的问题
  • @Dawnkeeper 你完全理解我。但我已经尝试过你建议的东西。这个东西只在图像上渲染一个像素。在每次迭代中,这一点都保持不变。 :(
  • 是的,刚刚自己测试过,这不是解决方案......嗯

标签: java algorithm fractals


【解决方案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 的 Wikipedia 描述也有一个使用整个图像并应用转换来获取新图像然后再次使用新图像重新开始的示例。这不需要随机性。

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

【讨论】:

  • 我想通过丢弃概率来实现的主要目标。正在测试我自己的转换函数,除非通过反复试验,我显然不会知道概率。那里有什么帮助吗?详细地说,假设我有四个其他函数,但我不知道使用什么概率,除了反复试验之外,有没有一种方法可以知道概率。
  • 对不起,但为此你需要一个非常喜欢数学的人^_^
  • 你猜怎么着?我是真正喜欢数学的人。检查我上面的答案。 ^_^
【解决方案2】:

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

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

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

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

在哪里 |det。 Ai| 是矩阵 Ai 的行列式的绝对值,由下式给出:|ad - bc|

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

虽然最终使用概率进行渲染,但应注意 ∑ Pi=1

例子:

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

A1 = (0, 0, 0, 0.25)
A2 = (0.95, 0.005, -0.005, 0.93)
A3 = (0.035, -0.2, 0.16, 0.04)
A4 = (-0.04, 0.2, 0.16, 0.04)

现在:

|确定。一个1| = |(0*0.25)-(0*0)| = 0
|确定。 A2| = |(0.95*0.93)-(0.005*-0.005)| = 0.883525
|确定。 A3| = |(0.035*0.04)-(-0.2*0.16)| = 0.0334
|确定。 A4| = |(-0.04*0.04)-(0.2*0.16)| = 0.0336

所有Ais的总和 = (0 + 0.883525 + 0.0334 + 0.0336) = 0.950525

然后概率是:

P1 = 0 ≈ 0.01
P2 = 0.883525/0.950525 = 0.929512637 ≈ 0.93
P3 = 0.0334/0.950525 = 0.0351384761 ≈ 0.03
P4 = 0.0336/0.950525 = 0.0353488861 ≈ 0.03

所以,最终的概率是:1%, 93%, 3%, 3%,总和为 100%,可以用作检查。

顺便说一句,这四个函数产生了 Barnsley Fern 的突变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2020-02-06
    相关资源
    最近更新 更多