js实现canvas L-system植物生长绘制效果代码

代码语言:html

所属分类:其他

代码描述:js实现canvas L-system植物生长绘制效果代码

代码标签: L-system 植物 生长 绘制 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!doctype html>
<html  lang="en-us">
<head>
	<meta charset="utf-8">

</head>
<body>


<div class="center">
	<article>
		<div class="social">
    
</div>
		<h1 class="title">L-System</h1>
		

		<div class="content"><div>
  <p>Experimenting with Linden Meyer Systems.</p>
<style>
    .post {
        max-width: none;
        width: 800px;
        padding: 0;
    }
</style>
<p><canvas id="canvas"></canvas></p>
<script>
// canvas setup
var d=document,
    canvas = document.getElementById("canvas"),
    c=canvas,
    W=800,H=700;
    c.width = W,
    c.height = H,
    c = c.getContext("2d");

// Math function aliases
var cos  = Math.cos,
    sin  = Math.sin,
    abs  = Math.abs,
    sqrt = Math.sqrt,
    sgn  = function(val) { return val >= 0 ? 1 : -1 },
    atan2= Math.atan2,
    rand = Math.random,
    TAU = 2*Math.PI;

// logging
dolog = true;

function logCreate(mod){
    var i = 0;
    return function(){
        if( !dolog ) return;
        if( i % mod == 0 )
            console.log(arguments);
        i = (i + 1) % mod;
    }
}

log  = logCreate(1);
logS = logCreate(60);

// Mouse
$M = {
    loc  : V2(W/2, H/2),
    dloc : V2(0,0),
    uloc : V2(0,0),
    down : false,
    action : 0,
    pressed : false
};

function V2(x,y){
    return {x : x || 0.0, y:y || 0.0};
}

V2c = function( v ){
    return { x : v.x, y : v.y };
}

V2add = function( a, b, r ){
    r.x = a.x + b.x;
    r.y = a.y + b.y;
}

V2sub = function( a, b, r ){
    r.x = a.x - b.x;
    r.y = a.y - b.y;
}

V2scale = function( a, s, r ){
    c.x = a.x * s;
    c.y = a.y * s;
}

V2dot = function( a, b, r ){
    r.x = a.x * b.x;
    r.y = a.y * b.y;
}

V2rot = function( a, angle, r ){
    r.x = a.x * cos( angle ) - a.y * sin( angle );
    r.y = a.y * sin( angle ) + a.y * cos( angle );
}

RotM2 = function( angle ){
    return {
        x11 : cos( angle ), x12 : -sin( angle ),
        x21 : sin( angle ), x22 :  cos( angle ) 
    };
}

M2xV2 = function( m, v, r ){
    r.x = v.x * m.x11 + v.y * m.x12;
    r.y = v.x * m.x21 + v.y * m.x22;
}

MAX = 1000000;

leaf = {
    axiom : "X",
    rules : {
        "F" : "FF",
        "X" : "F-[[X]+X]+F[+FX]-X"
    }
}

raceme = {
    axiom : "X",
    rules : {
        "F" : "FF",
        "X" : "F-[[F]+F]+F-FX"
    },
    commands : {
        "F" : "~"
    },
    vars : {  //     val   min  max
        angle : [  TAU/9, -MAX, MAX],
        min   : [ TAU/10, -MAX, MAX],
        max   : [ TAU/10, -MAX, MAX],
        spread: [    0.0,  0.0, MAX],
        
        length: [    1.0, -MAX, MAX],
        width : [    2.0,  0.0, MAX],
        
        hue : [ 0.0, -MAX, MAX],
        saturation : [ 70.0, 0.0, 100],
        lightness  : [ 70.0, 0.0, 100],
        alpha : [ 1.0, 0.0, 1.0]
    }
}

tree_at_fall = {
    axiom : "SF" + 
            "[(#min=-75;#max=75;*)(#length=1.3;#size*0.35;X)]" +
            "[(#min=-75;#max=75;*)(#length=1.2;#size*0.35;X)]" +
            "[(#min=-45;#max=45;*)(#length=1.5;#size*0.35;X)]" +
            "[(#min=-85;#max=85;*)(#length=1.1;#size*0.35;X)]" +
            "[(#min=-65;#max=65;*)(#length=1.4;#size*0.35;X)]" +
            "[(#min=-35;#max=35;*)(#length=1.6;#size*0.35;X)]" +
            "[(#min=-45;#max=45;*)(#length=1.5;#size*0.35;X)]" +
            "[(#min=-85;#max=85;*)(#length=1.1;#size*0.35;X)]" +
            "[(#min=-75;#max=75;*)(#length=1.3;#size*0.35;X)]",
    rules : {
        "S" : "#size+1;#size*1.5;S",
        "F" : "DFDF",
        "X" : "VX" +
              "|0.1{[R(ZX)L]}{}" +
              "VX" +
              "[Y(ZX)L]" +
              "[Y(ZX)LN]" +
              "[Y(ZX)L]"
    },
    commands : {
        "D" : "(#min=-2;#max=2;*)",
        "F" : "#size*0.9926;(#length=1.5;#hue=0; #alpha=0.5; ~)",
        
        "R" : "(#min=20;#max=60;|0.5{*}{/})",
        "V" : "(#min=-5;#max=5;*)",
        "Y" : "(#min=-75;#max=75;*)",
        "Z" : "#size*0.5;",
        "X" : "(#hue=30;#alpha=0.5;~)",
        
        "L" : "|0.5{#hue-5;}{#hue-17;}(#size=1; #length=0.5; #alpha=0.05;  [  [@=45;%=1.4142;-~+@=18.435; %=3.1623;+~][@=-45;%=1.4142;-~+@=-18.435; %=3.1623;+~]   [@=36.8699;%=1.25;-~+@=14.0362; %=3.0923;+~][@=-36.8699;%=1.25;-~+@=-14.0362; %=3.0923;+~]    [@=26.5651;%=1.118;-~+@=9.4623; %=3.0414;+~][@=-26.5651;%=1.118;-~+@=-9.4623; %=3.0414;+~]    [@=14.0262;%=1.0308;-~+@=4.7636; %=3.0104;+~][@=-14.0262;%=1.0308;-~+@=-4.7636; %=3.0104;+~]  @=0;%=4;~ @=22.0;])",
        
        "P" : "[(#length=0;#size=10;#alpha=0.5;#red<1;#green<1;#blue<1;" +
              "|0.6{|0.6{#red=0.9;#green=0.1;}{#red=0.8;#green=0.2;}}{|0.6{#red=0.7;#green=0.3;}{#red=0.6;#green=0.4;}}" +
              "~)]"
    },
    vars : {  //     val   min  max
        angle : [ TAU/18, -MAX, MAX],
        min   : [ TAU/24, -MAX, MAX],
        max   : [ TAU/12, -MAX, MAX],
        spread: [    0.0,  0.0, MAX],
        
        length: [    1.0, -MAX, MAX],
        width : [    2.0,  0.0, MAX],
        
        hue : [ 0.0, -MAX, MAX],
        saturation : [ 70.0, 0.0, 100],
        lightness  : [ 70.0, 0.0, 100],
        alpha : [ 1.0, 0.0, 1.0]
    }
}

bush_at_night = {
    axiom : "F",
    rules: {
        "F" : "FF/[(#width-5;/F*F*FL)]*[(#width-5;*F/F/FL)]"
    },
    commands: {
        "F" : "(#hue=30;#lightness=15;#saturation=13;~)",
        "L" : "(#width=100;#alpha=0.10;~)"
    },
    vars : {  //     val   min  max
        angle : [    0.0, -MAX, MAX],
        min   : [ TAU/20, -MAX, MAX],
        max   : [ TAU/16, -MAX, MAX],
        spread: [    0.0,  0.0, MAX],
        
        length: [   16.0, -MAX, MAX],
        width : [   20.0,  0.0, MAX],
        
        hue : [ 90.0, -MAX, MAX],
        saturation : [ 70.0, 0.0, 100],
        lightness  : [ 20.0, 0.0, 100],
        alpha : [ 1.0, 0.0, 1.0]
    },
    setup : {
        round : true,
        length_scale : 1.0,
        width_scale : 0.5
    }
}

useDefinition = bush_at_night;
useIterations = 4;

function LSystem(def){
    // system generation
    this.axiom = def.axiom;
    this.rules = def.rules;
    this.commands = def.commands;
    this.vars  = def.vars;
    this.setup = def.setup;
    
    // add implicit undefined extensions
    var extensions = def.axiom;
    for( var r in def.rules )
        extensions += def.rules[r];
    for( var i = 0, l = extensions.length; i < l; i++ ){
        var ext = extensions[i];
        def.rules[ ext ] = def.rules[ ext ] || ext;
    }
    
    this.tree = "";
};

LSystem.prototype.generate = function(iterations){
    var rules = this.rules,
        commands = this.commands,
        tree  = this.axiom,
        new_tree = [];
    
    // generate tree
    for( var it = 0; it < iterations; it++ ){
        var new_tree = [];
        for( var i = 0, l = tree.length; i < l; i++ ){
            var rule = tree.charAt(i);
            new_tree.push( rules[ rule ] || rule );
        }
        tree = new_tree.join("");
    }
    
    // replace with commands
    var cmds = [];
    for( var i = 0, l = tree.length; i < l; i++ ){
        var rule = tree.charAt(i),
            replacement = commands[ rule ] || rule;
        cmds.p.........完整代码请登录后点击上方下载按钮下载查看

网友评论0