//x y - , leng - , w - , deform - , rotate - DrawStick = function(x, y, leng, w, deform, rotate) { // canvas . this.c.save(); this.c.translate(x, y); this.c.rotate(rotate.degree()); // degree // x y . x = 0; y = w / -2; // this.c.beginPath(); // x y this.c.moveTo(x, y); // xy ( w/BRANCH_CONSTRICTION) this.c.bezierCurveTo(x, y, x + leng / 2, y + deform, x + leng, y + (w - (w / BRANCH_CONSTRICTION)) / 2); // this.c.lineTo(x + leng, y + w / BRANCH_CONSTRICTION + (w - (w / BRANCH_CONSTRICTION)) / 2); // this.c.bezierCurveTo(x + leng, y + w / BRANCH_CONSTRICTION + (w - (w / BRANCH_CONSTRICTION)) / 2, x + leng / 2, y + w + deform, x, y + w); // this.c.lineTo(x, y); this.c.closePath(); // , this.c.arc(x + leng, y + w / BRANCH_CONSTRICTION / 2 + (w - (w / BRANCH_CONSTRICTION)) / 2, w / BRANCH_CONSTRICTION / 2, 0 * Math.PI, 2 * Math.PI, false); // this.c.fillStyle = BRANCH_COLOR; this.c.fill(); // canvas this.c.restore(); }
var Branch = function(x, y, leng, width, deformation, rotate) { this.params = { x: x, y: y, leng: leng, width: width, deformation: deformation, rotate: rotate, }; this.parent = null; // , , this.children = []; // , . // canvas this.render = function() { drawer.DrawStick(this.params.x, this.params.y, this.params.leng, this.params.width, this.params.deformation, this.params.rotate); } // this.getEndPoints = function() { var ex = this.params.x + this.params.leng * Math.cos(this.params.rotate.degree()), ey = this.params.y + this.params.leng * Math.sin(this.params.rotate.degree()); return [ex, ey]; } // , this.createChild = function(leng, width, deform, rotate) { var exy = this.getEndPoints(); // // children this.children.push(new Branch(exy[0], exy[1], leng, width, deform, rotate)); // this.children[this.children.length - 1].parent = this; return this.children[this.children.length - 1]; } this.render(); // }
new Branch(100,300,200,20,-60,-50).createChild(100,20/1.5,30,-60);
// branches - c [{leng:,deform:,rotate:},{}] main - createDivarication = function(branches, main) { // var wi = this.params.width / BRANCH_CONSTRICTION / 2; for (var i = 0; i < 2; i++) { bi = branches[i]; // branches this.createChild(bi.leng, (i == main) ? (1.9 * wi) : wi * 1.4, bi.deform, this.params.rotate - bi.rotate // ); } return this.children; }
var TreeGenerator = function(){ // - branch this.genF=function(branch) { if (branch.params.width > 1) { // var divarications = [], // dfm = BRANCH_DEFORMATION * branch.params.width / branch.params.leng; // // for (var di = 0; di <= 2; di++) { divarications.push({ leng: rand(40, branch.params.leng), // deform: rand(-dfm, dfm), // rotate: (di == 0) ? (rand(-20, -10)) : (rand(10, 20)) // }); } // var chld = branch.createDivarication(divarications, Math.floor(rand(0, 2))); // for (var ci = 0; ci < 2; ci++) { this.genF(chld[ci]); } } else { // , } } // , this.genT=function(x,y){ // var mainTreeBranch = new Branch(x, y, rand(70, BRANCH_MAXLENGTH), rand(10, BRANCH_MAXWIDTH), rand(-40, 40), rand(-120, -70)); // this.genF(mainTreeBranch); // () drawer.DrawHill(x,y+20); return mainTreeBranch; } }
// Branch. pointPos getPointOnCurve = function(pointPos) { // var ex = this.params.x + this.params.leng / 2 * Math.cos((this.params.rotate + this.params.deformation).degree()), ey = this.params.y + this.params.leng / 2 * Math.sin((this.params.rotate + this.params.deformation).degree()); //t - t [0,1] t = pointPos / 100; // ep = this.getEndPoints(); // x,y x = [this.params.x, ep[0]]; y = [this.params.y, ep[1]]; x,y p1 = [ex, ey]; // par1 = Math.pow((1 - t), 2) * x[0] + (1 - t) * 2 * t * p1[0] + Math.pow(t, 2) * x[1]; // x par2 = Math.pow((1 - t), 2) * y[0] + (1 - t) * 2 * t * p1[1] + Math.pow(t, 2) * y[1]; // y return [par1, par2]; }
//branches - this.createOutgrowth = function(leng, width, pos, deform, rotate) { var startXY = this.getPointOnCurve(pos); // outgrowths( ) this.outgrowths.push(new Branch(startXY[0], startXY[1], leng, width, deform, this.params.rotate + rotate)); return this.outgrowths.reverse()[0]; }
this.genO = function(branch) { if (branch.params.width > 1) { // 1 var outgrowthsCount = rand(0, BRANCH_OUTGROWTH); // BRANCH_OUTGROWTH - . for (var io = 0; io < outgrowthsCount; io++) { // this.genF(branch.createOutgrowth(rand(10, branch.params.leng), rand(1, branch.params.width), rand(1, 100), rand(-10, 10), rand(-40, 40))); } } }
// for (var ci = 0; ci < 2; ci++) { this.genF(chld[ci]); }
// for (var ci = 0; ci < 2; ci++) { if (OUTGROWTH_ISSHOWN) { //OUTGROWTH_ISSHOWN , true if (chld[ci].params.width < OUTGROWTH_BRANCH_WIDTH) { //OUTGROWTH_BRANCH_WIDTH - this.genO(chld[ci]); // } } this.genF(chld[ci]); }
[[ [100, 0], // ( - ) [70, 40] // ]],
this.DrawLeaf = function(x, y, leafPoints, colors, scale, rotate) { // x y lx = x; ly = y; // for (var io = 0; io < 2; io++) { this.c.save(); // this.c.translate(x, y); // this.c.rotate((rotate).degree()); // this.c.scale(scale, scale); // if (io == 1) { // this.c.setTransform(-1, 0, 0, 1, x, y); this.c.scale(scale, scale); this.c.rotate((-180 - (rotate)).degree()); } x = 100 / -2; y = 0; this.c.beginPath(); this.c.moveTo(x, y); var lastPair = [0, 0]; // - for (var bi in leafPoints) { var bp = leafPoints[bi]; // this.c.bezierCurveTo(x + lastPair[0], y + lastPair[1], x + bp[1][0], y + bp[1][1], x + bp[0][0], y + bp[0][1]); // lastPair = [bp[0][0], bp[0][1]]; } // this.c.lineTo(x + LEAF_LENG, y); // LEAF_LENG - . 100 this.c.closePath(); this.c.fillStyle = colors[1]; // this.c.fill(); this.c.strokeStyle = colors[0]; // this.c.stroke(); this.c.restore(); x = lx; y = ly; } }
this.genL = function(branch) { leafCount = branch.params.leng / (LEAF_LENG * LEAF_SCALE) * LEAF_DENSITY; // : LEAF_SCALE - , LEAF_DENSITY - for (var li = 1; li < leafCount; li++) { // var lxy=branch.getPointOnCurve(branch.params.leng/leafCount*li); // // drawer.DrawLeaf(lxy[0], lxy[1], LeafMaps[LEAF_TYPE], ['#353', 'green'], LEAF_SCALE, branch.params.rotate - 180 ); } }
if(LEAF_ISSHOWN){ //LEAF_ISSHOWN - , . true this.genL(branch); }
Source: https://habr.com/ru/post/210614/
All Articles