J1M60

## 3D JAVASCRIPT
----------------

                   ----||----------
                 <  JS || SH AWK C  >
                   ----||----------
                       ||
                       
                   Bad news:  WE
                   Good news: 1 ly
                       
Install 3D JavaScript Turtle:

  https://github.com/danny/viewer

Press green button

  [ Clone or Download | v ]
  
Select "Download ZIP", extract content of the viewer-master folder into <somewhere>\Turtle3D.

Open with browser (Chrome, Firefox) local file: 

  <somewhere>\Turtle3D\viewer.html

Test functionality: 

  + click "Turtle Commands", press execute.
  + try (get familiar with) "Conrol" panel sliders and toggles.
  + "Refresh" to clear.
  + Re-"Enter" browser's URL to restart.

Turtle can:

  turtle.forward(steps)
  turtle.turnUp(degrees)
  turtle.turnDown(degrees)
  turtle.turnLeft(degrees)
  turtle.turnRight(degrees)
  turtle.changeColor(color)
  turtle.penUp()
  turtle.penDown()
  
Note: Due to limitations of the OpenGL Core Profile with the 
      WebGL renderer on most platforms linewidth will always be 1
      regardless of the set value
      
        https://threejs.org/docs/#api/en/materials
          /LineBasicMaterial.linewidth). 

Initial code: 

  for (var i = 0; i < 1000; i++){
    turtle.turnRight (1);
    turtle.turnUp (10);
    turtle.forward (10);
  }

Initial color: 0xff0000

  turtle.changeColor (0xFF); // RGB only
      
## ANNEX A. Turtle3D modified:

viewer.html

  <!DOCTYPE html>
  <html>
    <head> 
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 
      <title>Viewer</title>
      <style type="text/css">
        body {
          font-family: Monospace;
          font-size: 12px;
          background-color: #f5f5f5;
          margin: 0px;
          overflow: hidden;
        }
      </style>

      <link rel='stylesheet' type='text/css'
            href='css/turtle_commands.css' />
      <script type='text/javascript' 
              src='js/lib/Three.js'>
      </script>
      <script type='text/javascript'
              src='js/lib/THREEx.WindowResize.js'>
      </script>
      <script type='text/javascript'
              src='js/lib/DAT.GUI.min.js'>
      </script>
      <script type='text/javascript'
              src='js/lib/RequestAnimationFrame.js'>
      </script>
      <script type='text/javascript'
              src='js/lib/jquery-1.6.2.js'>
      </script>
      <script type='text/javascript'
              src='js/SphericalPoint.js'>
      </script>
      <script type='text/javascript' 
              src='js/MouseCamera.js'>
      </script>
      <script type='text/javascript' 
              src='js/Turtle.js'>
      </script>
    </head>
    <body>

    <script>
      var mc, stats, scene, turtle;
      $(document).ready (function () {
        mc = setup();
        mc.addGrid ();
        animate ();
      });

      function setup() {
        var container = document.createElement( 'div' );
        document.body.appendChild( container );

        scene = new THREE.Scene();

        turtle = new Turtle (scene);
        turtle.drawTurtle();

        var ambientLight = new THREE.AmbientLight( 0x404040 );
        scene.addLight( ambientLight );

        var renderer = new THREE.WebGLRenderer({antialias:true});
        renderer.setSize( window.innerWidth, window.innerHeight );

        container.appendChild(renderer.domElement);

        mc = new MouseCamera (scene, renderer);
        mc.addMouseListeners ();

        THREEx.WindowResize(renderer, mc.camera);
        return mc;
      }

      var i = 0;
      function animate() {
        requestAnimationFrame( animate );

        mc.rotate();
        mc.render();
      }

    </script>
  </body>
  </html>

EOF

-----------------------

js/turtle.js

  function Turtle (scene) {
    var self = this;

    this.scene = scene;

    this.position = new SphericalPoint (0,0,0);
    this.oldPosition = new THREE.Vector3 (0,0, 0);
    this.stepSize = 5;

    this.penDown = true;
    this.color = 0xff0000;
    this.width = 3;

    this.turtleMesh;

    this.forward = function(steps){

      self.position.radius = steps * self.stepSize;
      self.position.origin = self.oldPosition;

      var newPos = self.position.getVector();

      if (self.penDown)
        self.drawLine (
          new THREE.Vertex (self.oldPosition), 
          new THREE.Vertex(newPos)
        );

      self.oldPosition = newPos;
      self.turtleMesh.position = newPos;

      console.log (self.position.toString())
    }

    this.turnUp = function (degree) {
      self.turnDown (-degree);
    }

    this.turnDown = function(degree) {
      self.position.addPhi (degree);
    }

    this.turnLeft = function (degree) {
      self.position.addTheta(degree);
    }

    this.turnRight = function (degree) {
      self.turnLeft (-degree);
    }

    this.changeColor = function (aColor) {
      self.color = aColor;
    }

    this.changeWidth = function (aWidth) {
      self.width = aWidth;
    }

    this.penUp = function () {
      this.penDown = false;
    }

    this.penDown = function () {
      this.penDown = true;
    }

    this.drawTurtle = function () {
      var cube = new THREE.CubeGeometry( 25, 100, 25 );

      cube.vertices[ 0 ].position.multiplyScalar( 0.01 );
      cube.vertices[ 1 ].position.multiplyScalar( 0.01 );
      cube.vertices[ 4 ].position.multiplyScalar( 0.01 );
      cube.vertices[ 5 ].position.multiplyScalar( 0.01 );

      var material = new THREE.MeshBasicMaterial( 
        {color: self.color, opacity:0.8, transparent:true }
      );

      self.turtleMesh = new THREE.Mesh( cube, material );
      self.turtleMesh.position.set (0,50,0);
      self.turtleMesh.rotation.x = 80;
      self.turtleMesh.rotation.z = 45;
      self.turtleMesh.updateMatrix();
      self.turtleMesh.matrixAutoUpdate = true;
      self.scene.addChild( self.turtleMesh );
    }

    this.drawLine = function (oldVertex, newVertex) {
      var material = new THREE.LineBasicMaterial( 
        { linewidth: self.width, color: self.color, opacity: 1 } );
      var g2 = new THREE.Geometry();
      g2.vertices.push (oldVertex);
      g2.vertices.push (newVertex);

      self.line = new THREE.Line( g2, material );
      self.line.matrixAutoUpdate = true;
      scene.addChild (self.line);
    }
}

EOF 
