diff options
Diffstat (limited to 'index.html')
| -rw-r--r-- | index.html | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/index.html b/index.html new file mode 100644 index 0000000..8ffe64f --- /dev/null +++ b/index.html @@ -0,0 +1,279 @@ +<!doctype html> +<html> + <head> + <title>L-Systems.JS Playground</title> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> + <script src="http://mrdoob.github.com/three.js/build/Three.js"></script> + <script src="bootstrap.min.js"></script> + <script src="lsys.js"></script> + <link rel="stylesheet" href="bootstrap.css" type="text/css"/> + <link rel="stylesheet" href="style.css" type="text/css"/> + + <link href="prettify.css" type="text/css" rel="stylesheet"/> + <script type="text/javascript" src="prettify.js"></script> + </head> + + <body onload="prettyPrint()"> + + <div class="page"> + <div class="container"> + + <div class="hero-unit"> + <h1>L-Systems.JS</h1> + <p>Explore the power of L-Systems</p> + <p> + <a class="btn btn-large" href="https://raw.github.com/yuvadm/lsys.js/v0.1/lsys.js">Download L-Systems.JS (v0.1)</a> + <a class="btn btn-primary btn-large" href="http://github.com/yuvadm/lsys.js">L-Systems.JS on Github</a> + </p> + </div> + + <h2>About</h2> + <hr> + <div class="row"> + <div class="span12"> + <p><b>L-Systems (short for Lindenmayer systems) are instances of a formal grammar that are used to model growth processes of plant deveopment. L-Systems can be used to generate realistic, natural-looking organisms in simulated environments.</b></p> + + <p>An L-System consists of an initial axiom string, for example: <code>F</code>, and a set of production rules, for example: <code>F -> F-F+FF</code>. The rules are used to iterativey expand the string to a larger one. In our example, two iterations on the string will yield the string <code>F-F+FF-F-F+FF+F-F+FFF-F+FF</code>. L-Systems also include a mechanism that converts the output string into a geometrical representation. The syntax includes:</p> + + <ul> + <li><code>F</code> - a unit vector step forward that draws a line</li> + <li><code>+</code>,<code>-</code>,<code>&</code>,<code>^</code>,<code><</code>,<code>></code> - left and right turns on all three axises</li> + <li><code>|</code> - a vector direction flip</li> + <li><code>[</code>, <code>]</code> - state push and pop functions that enable branch creation. + </ul> + + <p>Proper cartesian coordinates can then be generated from the result string, for processing in the front-end of your choice (WebGL, canvas or SVG). + </p> + + <p>L-Systems.JS was created by <a href="http://y3xz.com">Yuval Adam</a>.</p> + </div> + </div> + + <h2>Usage</h2> + <hr> + <div class="row"> + <div class="span12"> + <p>The canonical usage would be to create the L-System itself by defining the axiom string and the production rules, running the iteration, and generating the respective cartesian coordinates.</p> + <pre class="prettyprint"> +var lsys = new LSystem('F', { 'F': 'F-F+FF' }).iterate(2); +var tree = lsys.print(); +console.log(tree); // F-F+FF-F-F+FF+F-F+FFF-F+FF +var coords = lsys.draw(Math.PI / 2); +console.log(coords); // [[[0,0,0], [0,1,0], [1,1,0], ... ]]</pre> + <p>These coordinates can now be plotted by any front-end. For example, using <a href="http://mrdoob.github.com/three.js/">THREE.js</a>:</p> + <pre class="prettyprint"> +for (var i=0; i<coords.length; i++) { + var branch = []; + for (var j=0; j<coords[i].length; j++) { + branch.push(new THREE.Vector3(coords[i][j][0], coords[i][j][1], coords[i][j][2])); + } + var geometry = new THREE.Shape(branch).createPointsGeometry(); + console.log(geometry); + draw_geometry(geometry); +}</pre> + </div> + </div> + + <h2>Playground</h2> + <hr> + <div class="row"> + <div class="span3"> + <ul class="nav nav-list"> + <li class="nav-header">2D Basics</li> + <li><a href="#" class="lsys-link" data-lsys="koch_curve" data-dim="2D">Koch Curve</a></li> + <li><a href="#" class="lsys-link" data-lsys="sierpinski" data-dim="2D">Sierpinski Triangle</a></li> + <li><a href="#" class="lsys-link" data-lsys="dragon_curve" data-dim="2D">Dragon Curve</a></li> + <li><a href="#" class="lsys-link" data-lsys="hilbert_curve" data-dim="2D">Hilbert Curve</a></li> + <li><a href="#" class="lsys-link" data-lsys="fractal_plant" data-dim="2D">Fractal Plant</a></li> + <li class="nav-header">3D Basics</li> + <li><a href="#" class="lsys-link" data-lsys="tree1" data-dim="3D">Tree 1</a></li> + <li><a href="#" class="lsys-link" data-lsys="3d_hilbert_curve" data-dim="3D">3D Hilbert Curve</a></li> + <li><a href="#" class="lsys-link" data-lsys="3d_axises" data-dim="3D">3D Axises</a></li> + </ul> + </div> + <div class="span9"> + <div id="render-container"></div> + <br/> + <form id="custom-form" class="well form-inline"> + <input id="custom-axiom" type="text" class="span1" placeholder="Axiom"> + <input id="custom-rules" type="text" class="span3" placeholder="Rules"> + <input id="custom-draw-consts" type="text" class="span1" placeholder="Draw Constants"> + <input id="custom-iterations" type="text" class="span1" placeholder="Iterations"> + <input id="custom-angle" type="text" class="span1" placeholder="Angle"> + <button id="custom-draw" type="submit" class="btn">Draw</button> + </form> + </div> + </div> + + <h2>Contribute!</h2> + <hr> + <div class="row"> + <div class="span12"> + <p>The L-Systems.JS project is in a very premature stage. Help us out by going over the <a href="https://github.com/yuvadm/lsys.js/issues">open project issues</a>.</p> + <p>Any other suggestions, feedback, or pull requests would be gladly accepted! :)</p> + </div> + </div> + + </div> + </div> + + <script> + var lsys_dir = { + 'koch_curve': ['F', {'F': 'F+F-F-F+F'}, [], 3, Math.PI/2], + 'sierpinski': ['A', {'A': 'B-A-B', 'B': 'A+B+A'}, ['A', 'B'], 4, Math.PI/3], + 'dragon_curve': ['FX', {'X': 'X+YF', 'Y': 'FX-Y'}, [], 10, Math.PI/2], + 'hilbert_curve': ['A', {'A': '-BF+AFA+FB-', 'B': '+AF-BFB-FA+'}, [], 1, Math.PI/2], + 'fractal_plant': ['X', {'X': 'F-[[X]+X]+F[+FX]-X', 'F': 'FF'}, [], 6, Math.PI*25/180], + 'tree1': ['F', {'F': 'F[-&<F][<+&F]|F[-&>F][+&F]'}, [], 3, Math.PI*23/180], + '3d_hilbert_curve': ['X', {'X': '^<XF^<XFX-F^>>XFX&F+>>XFX-F>X->'}, [], 1, Math.PI/2], + '3d_axises': ['F', {'F': '[FF]++[FF]++[FF]++[FF]>>[FF]<<<<[FF]'}, [], 1, Math.PI/4], + } + + var WIDTH = 500; //window.innerWidth; + var HEIGHT = 300; //window.innerHeight; + + var container; + var scene, camera, controls, renderer; + var lsys_tree, dim; + + var mouseX = 0, mouseY = 0; + var windowHalfX = WIDTH / 2; + var windowHalfY = HEIGHT / 2; + + init(); + draw_axes(); + animate(); + + function init() { + scene = new THREE.Scene(); + + camera = new THREE.PerspectiveCamera(20, WIDTH / HEIGHT, 1, 10000); + camera.position.z = 50; + scene.add(camera); + + light = new THREE.DirectionalLight( 0xffffff ); + light.position.set( 0, 0, 1 ); + scene.add(light); + + renderer = new THREE.WebGLRenderer( { antialias: true } ); + renderer.setSize(WIDTH, HEIGHT); + + container = document.getElementById('render-container'); + container.appendChild(renderer.domElement); + + controls = new THREE.TrackballControls(camera, renderer.domElement); + controls.rotateSpeed = 1.0; + controls.zoomSpeed = 1.2; + controls.panSpeed = 0.8; + controls.noZoom = false; + controls.noPan = false; + controls.staticMoving = true; + controls.dynamicDampingFactor = 0.3; + controls.keys = [65, 83, 68]; + controls.addEventListener('change', render); + + document.addEventListener('mousemove', onDocumentMouseMove, false); + } + + function onDocumentMouseMove( event ) { + mouseX = (event.clientX - windowHalfX); + mouseY = (event.clientY - windowHalfY); + } + + function draw_axes() { + var home = new THREE.Vector3(0,0,0); + + var x_axis = [home, new THREE.Vector3(150,0,0)]; + var y_axis = [home, new THREE.Vector3(0,150,0)]; + var z_axis = [home, new THREE.Vector3(0,0,150)]; + + var axis_geometry = [ + new THREE.Geometry(), + new THREE.Geometry(), + new THREE.Geometry() + ]; + + axis_geometry[0].vertices = x_axis; + axis_geometry[1].vertices = y_axis; + axis_geometry[2].vertices = z_axis; + + var axis_material = [ + new THREE.LineBasicMaterial({ color : 0xff0000 }), + new THREE.LineBasicMaterial({ color : 0x00ff00 }), + new THREE.LineBasicMaterial({ color : 0x0000ff }) + ]; + + var axis_line = [ + new THREE.Line(axis_geometry[0], axis_material[0]), + new THREE.Line(axis_geometry[1], axis_material[1]), + new THREE.Line(axis_geometry[2], axis_material[2]) + ]; + + scene.add(axis_line[0]); + scene.add(axis_line[1]); + scene.add(axis_line[2]); + } + + function draw_lsys(coords) { + lsys_tree = new THREE.Object3D(); + for (var i=0; i<coords.length; i++) { + var g = new THREE.Geometry(); + for (var j=0; j<coords[i].length; j++) { + var v = new THREE.Vector3(coords[i][j][0], coords[i][j][1], coords[i][j][2]); + g.vertices.push(v); + } + var material = new THREE.LineBasicMaterial({ + color : 0x111122, + linewidth : 2 + }); + var line = new THREE.Line(g, material); + lsys_tree.add(line); + } + scene.add(lsys_tree); + } + + function animate() { + requestAnimationFrame(animate); + controls.update(); + render(); + } + + function render() { + renderer.render(scene, camera); + } + + $('a.lsys-link').click(function(e) { + dim = $(this).attr('data-dim'); + var lsys = $(this).attr('data-lsys'); + if (lsys_tree) { + scene.remove(lsys_tree); + } + var d = lsys_dir[lsys]; + var new_lsys = new LSystem(d[0], d[1], d[2]).iterate(d[3]).draw(d[4]); + $('#custom-axiom').val(d[0]); + $('#custom-rules').val(JSON.stringify(d[1]).replace(/\"/g, "'")); + $('#custom-draw-consts').val(JSON.stringify(d[2]).replace(/\"/g, "'")); + $('#custom-iterations').val(d[3]); + $('#custom-angle').val(Math.round(d[4] * 180 / Math.PI)); + draw_lsys(new_lsys); + return false; + }); + + $('#custom-draw').click(function(e) { + var axiom = $('#custom-axiom').val(); + var rules = eval('(' + $('#custom-rules').val() + ')'); + var draw_consts = eval('(' + $('#custom-draw-consts').val() + ')'); + var iterations = $('#custom-iterations').val(); + var angle = $('#custom-angle').val(); + + if (lsys_tree) { + scene.remove(lsys_tree); + } + var custom_lsys = new LSystem(axiom, rules, draw_consts).iterate(iterations).draw(angle * (Math.PI / 180)); + draw_lsys(custom_lsys); + return false; + }); + + </script> + </body> +</html> |
