Can someone look over this code and point out why the resulting barnsley fern fractal doesn't look right?

function barnsley (ctx) {

ctx.fillStyle = 'green';
ctx.translate(ctx.canvas.width/2,ctx.canvas.height/2);
var self = this;

this.itts = 100000;
this.ittsCount = 0;
this.x = 0;
this.y = 0;

this.main = function () {
    for (var i=0;i<itts;i++) {
        var rand = Math.random()*100;
        if (rand < 1) {
            self.one();
        } else if (rand < 86) {
            self.two();
        } else if (rand < 94) {
            self.three();
        } else {
            self.four();
        }
    }
}

this.one = function () {
    var xn = self.x;
    var yn = self.y;
    var zx = 0;
    var zy = 0.16 * yn;
    self.drawPoint(zx,zy);
}

this.two = function () {
    var xn = self.x;
    var yn = self.y;
    var zx = 0.85 * xn + 0.4 * yn;
    var zy = -0.04 * xn + 0.85 * yn + 1.6;
    self.drawPoint(zx,zy);
}

this.three = function () {
    var xn = self.x;
    var yn = self.y;
    var zx = 0.2 * xn - 0.26 * yn;
    var zy = 0.23 * xn + 0.22 * yn + 1.6;
    self.drawPoint(zx,zy);
}

this.four = function () {
    var xn = self.x;
    var yn = self.y;
    var zx = -0.15 * xn + 0.28 * yn;
    var zy = 0.26 * xn + 0.24 * yn + 0.44;
    self.drawPoint(zx,zy);
}

this.drawPoint = function (xn,yn) {
    self.x = xn;
    self.y = yn;
    ctx.fillRect(xn*20,-yn*20,1,1);
}

this.main();
}

It has the right general shape but I must be missing something, I've checked the algorithms and such but to no avail. Any help is greatly appreciated.

有帮助吗?

解决方案

There was just a small error while typing the numbers. (I checked against this source, it looks like it uses the same numbers you are using).

In this this.two functions, you need to change

var zx = 0.85 * xn + 0.4 * yn;

to

var zx = 0.85 * xn + 0.04 * yn;

You can see this fix in action on jsFiddle.

其他提示

There are millions of way to do it but I think you might like this one .

Updates/steps are handled by the JS scheduler/timers. It's non-blocking and won't have your CPU go crazy with a heavy for loop.

The fractal data is also handled a different way. You could put any fractal made with affine transforms just by changing the parameters at one place. You also don't have to sum the probabilities as it does it for you.

ex: (StackOverflow won't let me post a JSFiddle link without a code exemple)

var probability_transforms =  [
    {
        "probability": 0.01, 
        "item": function(point){ return affine_transform(point, 0, 0, 0, 0.16, 0, 0) }
    },
    {
        "probability": 0.85, 
        "item": function(point){ return affine_transform(point, 0.85, 0.04, -0.04, 0.85, 0, 1.6) }
    },
    {
        "probability": 0.07,
        "item": function(point){ return affine_transform(point, 0.2, -0.26, 0.23, 0.22, 0, 1.6) }
    },
    {
        "probability": 0.07, 
        "item": function(point){ return affine_transform(point, -0.15, 0.28, 0.26, 0.24, 0, 0.44) }
    }
];

Have fun :)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top