summaryrefslogtreecommitdiff
path: root/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'index.html')
-rw-r--r--index.html279
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>&lt;</code>,<code>&gt;</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&lt;coords.length; i++) {
+ var branch = [];
+ for (var j=0; j&lt;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>