Question

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.

Était-ce utile?

La solution

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.

Autres conseils

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 :)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top