# Robot 2D Path Planning Demo

See corresponding lecture notes:
• The blue box on the ground is the room. Move the camera with WASD keys and mouse.
• The red rectangle on the floor is the robot. Move the robot with IJKL keys.
• The floating white walls are the robot's allowable region in configuration space (calculated in OpenSCAD).
• The red floating sphere is the robot's position in configuration space.
• The yellow line is the automatically determined path to home, (0,0.5,1.80).

Er, JavaScript or WebGL doesn't seem to be running, so basically all you're going to see is the bare code...

 var robot=sim.robot; // pull robot object // Move robot via keyboard var drive=0.0, turn=0.0; // forward/backward via I and K if (lib.key['i']) drive=+1.0; if (lib.key['k']) drive=-1.0; // turn left/right via J and L if (lib.key['j']) turn=+1.0; if (lib.key['l']) turn=-1.0; // Robot orientation change: robot.position.z+=lib.dt*turn; // Robot drives forward this vector: var forward=robot.forward(robot.position); robot.position.pe(forward.t(lib.dt*drive)); // Update GUI robot.update(); function clamp(x,limit) { if (x>limit) return limit; if (x<-limit) return -limit; return x; } // Auto-driving path to home: var target=new vec3(0,0.5,1.80); // dead center var pathpoints=new THREE.Geometry(); var P=robot.position.clone(); for (var step=0;step<=120;step++) { var F=robot.forward(P); var turn_target=target.clone(); turn_target.z=1.80+clamp(1.0*Math.atan2(-P.x,P.y),0.2); var best=null, best_dist=1.0e3; var delXY=0.10; // drive plan step size, m var delZ=0.02; // turn plan step size, 100*deg // Consider every combination of driving and turning: for (var drive=-delXY;drive<=delXY;drive+=delXY) for (var turn=-delZ;turn<=delZ;turn+=delZ) { var next=P.p(F.t(drive)); next.z+=turn; var shift=turn_target.m(next); shift.x*=5.0; // correct X first var dist=shift.length(); if (dist=3) { // have a full wall face wallgeom.faces.push(new THREE.Face3( wallgeom.vertices.length-1, wallgeom.vertices.length-2, wallgeom.vertices.length-3 )); faces.push(cur_face); cur_face=[]; } } // Load wall geometry (vertex calls) eval(PixAnvil.loadTab("Walls")); // Return true if this point is inside our wall geometry function point_inside(v) { var crossings=0; for (var fi in faces) { if (ray_hits_face(faces[fi],v)) crossings++; } return crossings%2!=0; } // Return true if this is a valid point robot.valid=function(position) { return point_inside(position); } // Return true if this face intersects a ray from this point // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm function ray_hits_face(f,v) { var V1=f[0], V2=f[1], V3=f[2]; var O=v, D=new vec3(1,0,0); var e1=V2.m(V1); var e2=V3.m(V1); var P=new vec3(); P.crossVectors(D,e2); var det=e1.dot(P); var EPSILON=0.001; if (det>-EPSILON && det=1.0) return 0.0; P.crossVectors(T,e1); var v=D.dot(P)*inv_det; if (v<0.0 || u+v>=1.0) return 0.0; var t=e2.dot(P)*inv_det; if (t>EPSILON) return true; else return false;0 } // Draw wall geometry wallgeom.computeBoundingSphere(); scene.add(new THREE.Mesh( wallgeom, new THREE.MeshDepthMaterial({ wireframe:true }) )); // Ground and selected walls as glowing grid var linegeom=new THREE.Geometry(); var lineZ=0.0; var range=16; for (var x=-range;x<=range;x+=2) { linegeom.vertices.push(new vec3(x,-range,lineZ)); linegeom.vertices.push(new vec3(x,+range,lineZ)); linegeom.vertices.push(new vec3(x+1,+range,lineZ)); linegeom.vertices.push(new vec3(x+1,-range,lineZ)); } for (var y=-range;y<=range;y+=2) { linegeom.vertices.push(new vec3(+range,y,lineZ)); linegeom.vertices.push(new vec3(-range,y,lineZ)); linegeom.vertices.push(new vec3(-range,y+1,lineZ)); linegeom.vertices.push(new vec3(+range,y+1,lineZ)); } var lines=new THREE.Line(linegeom, new THREE.LineBasicMaterial({ color: 0x00bf00 // faint green lines }), THREE.LinePieces ); scene.add(lines); camera.lookAt(scene.position); PixAnvil.renderer.setClearColor(0x000000, 1.0); // black // Converted STL file to JavaScript vertex() calls with: // cat foo.stl | grep vertex | awk '{printf(" vertex(%.3f,%.3f,%.3f);\n",\$2,\$3,\$4);}' > this.js vertex(-114.000,37.500,0.000); vertex(114.000,700.500,0.000); vertex(114.000,37.500,0.000); vertex(114.000,700.500,0.000); vertex(-114.000,37.500,0.000); vertex(-114.000,700.500,0.000); vertex(108.628,49.952,9.998); vertex(114.000,700.500,0.000); vertex(108.629,688.051,9.998); vertex(114.000,700.500,0.000); vertex(108.628,49.952,9.998); vertex(114.000,37.500,0.000); vertex(-108.629,688.047,10.000); vertex(108.629,688.051,9.998); vertex(114.000,700.500,0.000); vertex(-108.629,688.047,10.000); vertex(114.000,700.500,0.000); vertex(-114.000,700.500,0.000); vertex(-114.000,700.500,0.000); vertex(-108.628,49.952,9.998); vertex(-108.629,688.047,10.000); vertex(-114.000,700.500,0.000); vertex(-114.000,37.500,0.000); vertex(-108.628,49.952,9.998); vertex(108.628,49.952,9.998); vertex(-108.628,49.952,9.998); vertex(114.000,37.500,0.000); vertex(-108.628,49.952,9.998); vertex(-114.000,37.500,0.000); vertex(114.000,37.500,0.000); vertex(108.628,49.949,351.006); vertex(113.462,699.254,360.000); vertex(113.463,38.745,360.000); vertex(-108.627,688.045,351.000); vertex(113.462,699.254,360.000); vertex(108.629,688.053,351.003); vertex(113.462,699.254,360.000); vertex(-108.627,688.045,351.000); vertex(-113.463,699.255,360.000); vertex(-113.462,38.746,360.000); vertex(108.628,49.949,351.006); vertex(113.463,38.745,360.000); vertex(108.628,49.949,351.006); vertex(-113.462,38.746,360.000); vertex(-108.629,49.947,351.004); vertex(-113.462,38.746,360.000); vertex(-113.463,699.255,360.000); vertex(-108.627,688.045,351.000); vertex(108.629,688.051,9.998); vertex(-108.629,688.047,10.000); vertex(105.697,677.110,20.000); vertex(105.697,677.110,20.000); vertex(-108.629,688.047,10.000); vertex(-105.697,677.107,20.004); vertex(-108.628,49.952,9.998); vertex(108.628,49.952,9.998); vertex(105.697,60.890,20.000); vertex(-108.628,49.952,9.998); vertex(105.697,60.890,20.000); vertex(-105.697,60.890,20.000); vertex(-108.629,688.047,10.000); vertex(-105.697,60.890,20.000); vertex(-105.697,677.107,20.004); vertex(-105.697,60.890,20.000); vertex(-108.629,688.047,10.000); vertex(-108.628,49.952,9.998); vertex(105.697,60.890,20.000); vertex(108.629,688.051,9.998); vertex(105.697,677.110,20.000); vertex(108.629,688.051,9.998); vertex(105.697,60.890,20.000); vertex(108.628,49.952,9.998); vertex(-105.261,70.403,30.544); vertex(-105.697,677.107,20.004); vertex(-105.697,60.890,20.000); vertex(105.258,667.573,30.572); vertex(-105.697,677.107,20.004); vertex(-105.267,667.610,30.516); vertex(105.697,677.110,20.000); vertex(-105.697,677.107,20.004); vertex(105.258,667.573,30.572); vertex(105.278,70.266,30.351); vertex(105.697,677.110,20.000); vertex(105.258,667.573,30.572); vertex(105.697,677.110,20.000); vertex(105.278,70.266,30.351); vertex(105.697,60.890,20.000); vertex(-105.697,60.890,20.000); vertex(105.278,70.266,30.351); vertex(-105.261,70.403,30.544); vertex(105.278,70.266,30.351); vertex(-105.697,60.890,20.000); vertex(105.697,60.890,20.000); vertex(-105.267,667.610,30.516); vertex(-105.261,70.403,30.544); vertex(-107.303,660.790,40.471); vertex(105.258,667.573,30.572); vertex(107.312,77.237,40.550); vertex(105.278,70.266,30.351); vertex(105.258,667.573,30.572); vertex(-107.303,660.790,40.471); vertex(107.369,660.685,40.785); vertex(105.258,667.573,30.572); vertex(-105.267,667.610,30.516); vertex(-107.303,660.790,40.471); vertex(-105.261,70.403,30.544); vertex(107.312,77.237,40.550); vertex(-107.336,77.222,40.578); vertex(-105.261,70.403,30.544); vertex(105.278,70.266,30.351); vertex(107.312,77.237,40.550); vertex(-107.303,660.790,40.471); vertex(-111.760,81.681,50.426); vertex(-111.749,656.311,50.426); vertex(-111.760,81.681,50.426); vertex(-107.303,660.790,40.471); vertex(-107.336,77.222,40.578); vertex(-107.336,77.222,40.578); vertex(-107.303,660.790,40.471); vertex(-105.261,70.403,30.544); vertex(107.369,660.685,40.785); vertex(-111.749,656.311,50.426); vertex(111.870,656.283,50.666); vertex(107.369,660.685,40.785); vertex(-107.303,660.790,40.471); vertex(-111.749,656.311,50.426); vertex(107.369,660.685,40.785); vertex(107.312,77.237,40.550); vertex(105.258,667.573,30.572); vertex(-111.760,81.681,50.426); vertex(107.312,77.237,40.550); vertex(111.722,81.647,50.309); vertex(-107.336,77.222,40.578); vertex(107.312,77.237,40.550); vertex(-111.760,81.681,50.426); vertex(111.870,656.283,50.666); vertex(118.519,83.741,60.311); vertex(111.722,81.647,50.309); vertex(111.870,656.283,50.666); vertex(-118.499,654.273,60.284); vertex(118.578,654.275,60.391); vertex(111.870,656.283,50.666); vertex(-111.749,656.311,50.426); vertex(-118.499,654.273,60.284); vertex(111.870,656.283,50.666); vertex(111.722,81.647,50.309); vertex(107.369,660.685,40.785); vertex(107.369,660.685,40.785); vertex(111.722,81.647,50.309); vertex(107.312,77.237,40.550); vertex(-111.760,81.681,50.426); vertex(118.519,83.741,60.311); vertex(-118.662,83.726,60.516); vertex(-111.760,81.681,50.426); vertex(111.722,81.647,50.309); vertex(118.519,83.741,60.311); vertex(-118.662,83.726,60.516); vertex(-128.110,654.699,71.000); vertex(-118.499,654.273,60.284); vertex(-128.110,654.699,71.000); vertex(-118.662,83.726,60.516); vertex(-128.110,83.302,71.000); vertex(128.111,654.695,71.000); vertex(118.519,83.741,60.311); vertex(118.578,654.275,60.391); vertex(118.519,83.741,60.311); vertex(128.111,654.695,71.000); vertex(128.110,83.303,71.000); vertex(-111.749,656.311,50.426); vertex(-118.662,83.726,60.516); vertex(-118.499,654.273,60.284); vertex(-118.662,83.726,60.516); vertex(-111.749,656.311,50.426); vertex(-111.760,81.681,50.426); vertex(118.578,654.275,60.391); vertex(-128.110,654.699,71.000); vertex(128.111,654.695,71.000); vertex(-128.110,654.699,71.000); vertex(118.578,654.275,60.391); vertex(-118.499,654.273,60.284); vertex(118.578,654.275,60.391); vertex(118.519,83.741,60.311); vertex(111.870,656.283,50.666); vertex(-118.662,83.726,60.516); vertex(128.110,83.303,71.000); vertex(-128.110,83.302,71.000); vertex(128.110,83.303,71.000); vertex(-118.662,83.726,60.516); vertex(118.519,83.741,60.311); vertex(-128.110,654.699,71.000); vertex(-128.110,83.302,71.000); vertex(-139.047,657.630,81.000); vertex(128.110,83.303,71.000); vertex(139.043,657.623,80.996); vertex(139.046,80.372,81.000); vertex(139.043,657.623,80.996); vertex(128.110,83.303,71.000); vertex(128.111,654.695,71.000); vertex(128.111,654.695,71.000); vertex(-139.047,657.630,81.000); vertex(139.043,657.623,80.996); vertex(-139.047,657.630,81.000); vertex(128.111,654.695,71.000); vertex(-128.110,654.699,71.000); vertex(-128.110,83.302,71.000); vertex(139.046,80.372,81.000); vertex(-139.047,80.372,81.001); vertex(139.046,80.372,81.000); vertex(-128.110,83.302,71.000); vertex(128.110,83.303,71.000); vertex(150.877,662.731,90.500); vertex(139.046,80.372,81.000); vertex(139.043,657.623,80.996); vertex(-139.047,80.372,81.001); vertex(-139.047,657.630,81.000); vertex(-128.110,83.302,71.000); vertex(150.877,662.731,90.500); vertex(-139.047,657.630,81.000); vertex(-150.877,662.731,90.500); vertex(139.043,657.623,80.996); vertex(-139.047,657.630,81.000); vertex(150.877,662.731,90.500); vertex(-139.047,80.372,81.001); vertex(150.877,75.269,90.500); vertex(-150.877,75.269,90.500); vertex(-139.047,80.372,81.001); vertex(139.046,80.372,81.000); vertex(150.877,75.269,90.500); vertex(-139.047,80.372,81.001); vertex(-150.877,75.269,90.500); vertex(-139.047,657.630,81.000); vertex(-139.047,657.630,81.000); vertex(-150.877,75.269,90.500); vertex(-150.877,662.731,90.500); vertex(-150.877,75.269,90.500); vertex(139.046,80.372,100.000); vertex(-139.046,80.372,100.000); vertex(-150.877,75.269,90.500); vertex(150.877,75.269,90.500); vertex(139.046,80.372,100.000); vertex(150.877,75.269,90.500); vertex(139.046,80.372,81.000); vertex(150.877,662.731,90.500); vertex(-150.877,662.731,90.500); vertex(-150.877,75.269,90.500); vertex(-139.051,657.625,99.996); vertex(150.877,662.731,90.500); vertex(-139.051,657.625,99.996); vertex(139.043,657.624,100.004); vertex(-139.051,657.625,99.996); vertex(150.877,662.731,90.500); vertex(-150.877,662.731,90.500); vertex(-139.046,80.372,100.000); vertex(128.110,83.303,109.999); vertex(-128.111,83.302,110.000); vertex(128.110,83.303,109.999); vertex(-139.046,80.372,100.000); vertex(139.046,80.372,100.000); vertex(-139.046,80.372,100.000); vertex(-139.051,657.625,99.996); vertex(-150.877,75.269,90.500); vertex(139.043,657.624,100.004); vertex(150.877,75.269,90.500); vertex(150.877,662.731,90.500); vertex(150.877,75.269,90.500); vertex(139.043,657.624,100.004); vertex(139.046,80.372,100.000); vertex(-139.051,657.625,99.996); vertex(-128.111,83.302,110.000); vertex(-128.107,654.698,110.002); vertex(-128.111,83.302,110.000); vertex(-139.051,657.625,99.996); vertex(-139.046,80.372,100.000); vertex(139.046,80.372,100.000); vertex(139.043,657.624,100.004); vertex(128.110,83.303,109.999); vertex(139.043,657.624,100.004); vertex(-128.107,654.698,110.002); vertex(128.111,654.696,110.000); vertex(-128.107,654.698,110.002); vertex(139.043,657.624,100.004); vertex(-139.051,657.625,99.996); vertex(-128.111,83.302,110.000); vertex(118.528,83.738,120.677); vertex(-118.520,83.741,120.690); vertex(-128.111,83.302,110.000); vertex(128.110,83.303,109.999); vertex(118.528,83.738,120.677); vertex(128.111,654.696,110.000); vertex(128.110,83.303,109.999); vertex(139.043,657.624,100.004); vertex(-128.107,654.698,110.002); vertex(-128.111,83.302,110.000); vertex(-118.699,654.274,120.412); vertex(128.111,654.696,110.000); vertex(-118.699,654.274,120.412); vertex(118.460,654.269,120.786); vertex(-118.699,654.274,120.412); vertex(128.111,654.696,110.000); vertex(-128.107,654.698,110.002); vertex(-118.520,83.741,120.690); vertex(111.687,81.627,130.781); vertex(-111.722,81.647,130.690); vertex(-118.520,83.741,120.690); vertex(118.528,83.738,120.677); vertex(111.687,81.627,130.781); vertex(-118.520,83.741,120.690); vertex(-118.699,654.274,120.412); vertex(-128.111,83.302,110.000); vertex(118.528,83.738,120.677); vertex(128.111,654.696,110.000); vertex(118.460,654.269,120.786); vertex(128.111,654.696,110.000); vertex(118.528,83.738,120.677); vertex(128.110,83.303,109.999); vertex(-118.699,654.274,120.412); vertex(-118.520,83.741,120.690); vertex(-111.763,656.312,130.549); vertex(112.064,656.228,130.000); vertex(-111.763,656.312,130.549); vertex(111.601,656.445,131.004); vertex(118.460,654.269,120.786); vertex(-111.763,656.312,130.549); vertex(112.064,656.228,130.000); vertex(-111.763,656.312,130.549); vertex(118.460,654.269,120.786); vertex(-118.699,654.274,120.412); vertex(111.601,656.445,131.004); vertex(111.687,81.627,130.781); vertex(112.064,656.228,130.000); vertex(-107.338,77.274,140.332); vertex(111.687,81.627,130.781); vertex(107.285,77.123,140.661); vertex(-111.722,81.647,130.690); vertex(111.687,81.627,130.781); vertex(-107.338,77.274,140.332); vertex(-111.763,656.312,130.549); vertex(-118.520,83.741,120.690); vertex(-111.722,81.647,130.690); vertex(112.064,656.228,130.000); vertex(118.528,83.738,120.677); vertex(118.460,654.269,120.786); vertex(118.528,83.738,120.677); vertex(112.064,656.228,130.000); vertex(111.687,81.627,130.781); vertex(-111.763,656.312,130.549); vertex(-111.722,81.647,130.690); vertex(-107.338,77.274,140.332); vertex(111.601,656.445,131.004); vertex(-107.304,660.800,140.522); vertex(107.302,660.791,140.530); vertex(111.601,656.445,131.004); vertex(-111.763,656.312,130.549); vertex(-107.304,660.800,140.522); vertex(-105.261,70.408,150.459); vertex(107.285,77.123,140.661); vertex(105.278,70.248,150.663); vertex(-107.338,77.274,140.332); vertex(107.285,77.123,140.661); vertex(-105.261,70.408,150.459); vertex(-107.338,77.274,140.332); vertex(-107.304,660.800,140.522); vertex(-111.763,656.312,130.549); vertex(107.302,660.791,140.530); vertex(111.687,81.627,130.781); vertex(111.601,656.445,131.004); vertex(111.687,81.627,130.781); vertex(107.302,660.791,140.530); vertex(107.285,77.123,140.661); vertex(-107.304,660.800,140.522); vertex(-107.338,77.274,140.332); vertex(-105.261,70.408,150.459); vertex(107.302,660.791,140.530); vertex(-105.273,667.508,150.289); vertex(105.267,667.558,150.387); vertex(107.302,660.791,140.530); vertex(-107.304,660.800,140.522); vertex(-105.273,667.508,150.289); vertex(105.697,677.109,160.999); vertex(105.278,70.248,150.663); vertex(105.267,667.558,150.387); vertex(-105.261,70.408,150.459); vertex(105.697,60.890,161.000); vertex(-105.697,60.891,160.999); vertex(-105.261,70.408,150.459); vertex(105.278,70.248,150.663); vertex(105.697,60.890,161.000); vertex(-105.261,70.408,150.459); vertex(-105.697,677.105,160.996); vertex(-105.273,667.508,150.289); vertex(-105.261,70.408,150.459); vertex(-105.273,667.508,150.289); vertex(-107.304,660.800,140.522); vertex(105.267,667.558,150.387); vertex(107.285,77.123,140.661); vertex(107.302,660.791,140.530); vertex(107.285,77.123,140.661); vertex(105.267,667.558,150.387); vertex(105.278,70.248,150.663); vertex(105.267,667.558,150.387); vertex(-105.697,677.105,160.996); vertex(105.697,677.109,160.999); vertex(-105.697,677.105,160.996); vertex(105.267,667.558,150.387); vertex(-105.273,667.508,150.289); vertex(-105.697,677.105,160.996); vertex(-105.261,70.408,150.459); vertex(-105.697,60.891,160.999); vertex(-105.697,60.891,160.999); vertex(105.697,60.890,161.000); vertex(108.628,49.954,171.000); vertex(-105.697,60.891,160.999); vertex(108.628,49.954,171.000); vertex(-108.628,49.954,171.000); vertex(-105.697,60.891,160.999); vertex(-108.626,688.047,171.000); vertex(-105.697,677.105,160.996); vertex(105.278,70.248,150.663); vertex(105.697,677.109,160.999); vertex(105.697,60.890,161.000); vertex(-108.626,688.047,171.000); vertex(105.697,677.109,160.999); vertex(-105.697,677.105,160.996); vertex(105.697,677.109,160.999); vertex(-108.626,688.047,171.000); vertex(108.628,688.046,171.000); vertex(-108.626,688.047,171.000); vertex(-105.697,60.891,160.999); vertex(-108.628,49.954,171.000); vertex(113.730,38.123,180.500); vertex(-113.731,38.123,180.500); vertex(108.628,49.954,171.000); vertex(108.628,49.954,171.000); vertex(-113.731,38.123,180.500); vertex(-108.628,49.954,171.000); vertex(-108.628,49.954,171.000); vertex(-113.730,699.876,180.500); vertex(-108.626,688.047,171.000); vertex(-113.730,699.876,180.500); vertex(-108.628,49.954,171.000); vertex(-113.731,38.123,180.500); vertex(113.730,699.877,180.500); vertex(108.628,49.954,171.000); vertex(108.628,688.046,171.000); vertex(108.628,49.954,171.000); vertex(113.730,699.877,180.500); vertex(113.730,38.123,180.500); vertex(108.628,688.046,171.000); vertex(105.697,60.890,161.000); vertex(105.697,677.109,160.999); vertex(105.697,60.890,161.000); vertex(108.628,688.046,171.000); vertex(108.628,49.954,171.000); vertex(-113.730,699.876,180.500); vertex(113.730,699.877,180.500); vertex(108.628,688.046,171.000); vertex(-113.730,699.876,180.500); vertex(108.628,688.046,171.000); vertex(-108.626,688.047,171.000); vertex(113.730,38.123,180.500); vertex(113.730,699.877,180.500); vertex(108.627,688.043,190.000); vertex(108.627,688.043,190.000); vertex(108.629,49.950,190.001); vertex(113.730,38.123,180.500); vertex(-108.628,49.952,189.999); vertex(113.730,38.123,180.500); vertex(108.629,49.950,190.001); vertex(113.730,38.123,180.500); vertex(-108.628,49.952,189.999); vertex(-113.731,38.123,180.500); vertex(-113.730,699.876,180.500); vertex(108.627,688.043,190.000); vertex(113.730,699.877,180.500); vertex(108.627,688.043,190.000); vertex(-113.730,699.876,180.500); vertex(-108.628,688.046,190.000); vertex(-108.628,49.952,189.999); vertex(-113.730,699.876,180.500); vertex(-113.731,38.123,180.500); vertex(-113.730,699.876,180.500); vertex(-108.628,49.952,189.999); vertex(-108.628,688.046,190.000); vertex(108.629,49.950,190.001); vertex(108.627,688.043,190.000); vertex(105.696,677.109,200.004); vertex(-108.628,49.952,189.999); vertex(108.629,49.950,190.001); vertex(105.697,60.889,200.000); vertex(-108.628,49.952,189.999); vertex(105.697,60.889,200.000); vertex(-105.697,60.889,199.999); vertex(-105.698,677.109,199.998); vertex(105.696,677.109,200.004); vertex(108.627,688.043,190.000); vertex(-105.698,677.109,199.998); vertex(108.627,688.043,190.000); vertex(-108.628,688.046,190.000); vertex(-108.628,688.046,190.000); vertex(-108.628,49.952,189.999); vertex(-105.698,677.109,199.998); vertex(105.697,60.889,200.000); vertex(105.696,677.109,200.004); vertex(105.269,667.648,210.465); vertex(-105.697,60.889,199.999); vertex(-105.698,677.109,199.998); vertex(-108.628,49.952,189.999); vertex(105.696,677.109,200.004); vertex(105.697,60.889,200.000); vertex(108.629,49.950,190.001); vertex(-105.697,60.889,199.999); vertex(105.259,70.425,210.580); vertex(-105.276,70.413,210.602); vertex(-105.697,60.889,199.999); vertex(105.697,60.889,200.000); vertex(105.259,70.425,210.580); vertex(105.269,667.648,210.465); vertex(-105.698,677.109,199.998); vertex(-105.267,667.559,210.609); vertex(105.696,677.109,200.004); vertex(-105.698,677.109,199.998); vertex(105.269,667.648,210.465); vertex(-105.267,667.559,210.609); vertex(-107.285,77.124,220.339); vertex(-107.311,660.749,220.573); vertex(-107.285,77.124,220.339); vertex(-105.267,667.559,210.609); vertex(-105.276,70.413,210.602); vertex(105.259,70.425,210.580); vertex(105.269,667.648,210.465); vertex(107.318,660.746,220.600); vertex(-105.698,677.109,199.998); vertex(-105.276,70.413,210.602); vertex(-105.267,667.559,210.609); vertex(-105.276,70.413,210.602); vertex(-105.698,677.109,199.998); vertex(-105.697,60.889,199.999); vertex(-107.285,77.124,220.339); vertex(105.259,70.425,210.580); vertex(107.305,77.176,220.453); vertex(-105.276,70.413,210.602); vertex(105.259,70.425,210.580); vertex(-107.285,77.124,220.339); vertex(105.269,667.648,210.465); vertex(-107.311,660.749,220.573); vertex(107.318,660.746,220.600); vertex(105.269,667.648,210.465); vertex(-105.267,667.559,210.609); vertex(-107.311,660.749,220.573); vertex(-111.686,81.627,230.218); vertex(-107.311,660.749,220.573); vertex(-107.285,77.124,220.339); vertex(107.318,660.746,220.600); vertex(111.747,81.682,230.401); vertex(107.305,77.176,220.453); vertex(107.318,660.746,220.600); vertex(107.305,77.176,220.453); vertex(105.259,70.425,210.580); vertex(-107.285,77.124,220.339); vertex(111.747,81.682,230.401); vertex(-111.686,81.627,230.218); vertex(-107.285,77.124,220.339); vertex(107.305,77.176,220.453); vertex(111.747,81.682,230.401); vertex(107.318,660.746,220.600); vertex(-111.759,656.320,230.424); vertex(111.824,656.305,230.546); vertex(107.318,660.746,220.600); vertex(-107.311,660.749,220.573); vertex(-111.759,656.320,230.424); vertex(-111.759,656.320,230.424); vertex(-118.587,83.741,240.430); vertex(-118.545,654.258,240.372); vertex(-118.587,83.741,240.430); vertex(-111.759,656.320,230.424); vertex(-111.686,81.627,230.218); vertex(111.747,81.682,230.401); vertex(111.824,656.305,230.546); vertex(118.472,654.269,240.231); vertex(111.824,656.305,230.546); vertex(111.747,81.682,230.401); vertex(107.318,660.746,220.600); vertex(-111.686,81.627,230.218); vertex(-111.759,656.320,230.424); vertex(-107.311,660.749,220.573); vertex(-118.587,83.741,240.430); vertex(111.747,81.682,230.401); vertex(118.575,83.733,240.399); vertex(-111.686,81.627,230.218); vertex(111.747,81.682,230.401); vertex(-118.587,83.741,240.430); vertex(111.824,656.305,230.546); vertex(-118.545,654.258,240.372); vertex(118.472,654.269,240.231); vertex(111.824,656.305,230.546); vertex(-111.759,656.320,230.424); vertex(-118.545,654.258,240.372); vertex(128.111,654.698,251.001); vertex(118.575,83.733,240.399); vertex(118.472,654.269,240.231); vertex(118.575,83.733,240.399); vertex(128.111,654.698,251.001); vertex(128.111,83.302,251.001); vertex(118.472,654.269,240.231); vertex(118.575,83.733,240.399); vertex(111.747,81.682,230.401); vertex(-118.587,83.741,240.430); vertex(128.111,83.302,251.001); vertex(-128.111,83.303,251.001); vertex(128.111,83.302,251.001); vertex(-118.587,83.741,240.430); vertex(118.575,83.733,240.399); vertex(128.111,654.698,251.001); vertex(-118.545,654.258,240.372); vertex(-128.110,654.697,251.000); vertex(118.472,654.269,240.231); vertex(-118.545,654.258,240.372); vertex(128.111,654.698,251.001); vertex(-128.110,654.697,251.000); vertex(-128.111,83.303,251.001); vertex(-139.040,657.632,260.998); vertex(-118.587,83.741,240.430); vertex(-128.110,654.697,251.000); vertex(-118.545,654.258,240.372); vertex(-128.110,654.697,251.000); vertex(-118.587,83.741,240.430); vertex(-128.111,83.303,251.001); vertex(-128.111,83.303,251.001); vertex(139.047,80.372,261.001); vertex(-139.047,80.373,261.002); vertex(-128.111,83.303,251.001); vertex(128.111,83.302,251.001); vertex(139.047,80.372,261.001); vertex(128.111,654.698,251.001); vertex(-139.040,657.632,260.998); vertex(139.047,657.626,261.000); vertex(-139.040,657.632,260.998); vertex(128.111,654.698,251.001); vertex(-128.110,654.697,251.000); vertex(-139.040,657.632,260.998); vertex(-139.047,80.373,261.002); vertex(-150.877,662.730,270.500); vertex(128.111,83.302,251.001); vertex(139.047,657.626,261.000); vertex(139.047,80.372,261.001); vertex(139.047,657.626,261.000); vertex(128.111,83.302,251.001); vertex(128.111,654.698,251.001); vertex(-139.047,80.373,261.002); vertex(-139.040,657.632,260.998); vertex(-128.111,83.303,251.001); vertex(-139.047,80.373,261.002); vertex(150.877,75.269,270.500); vertex(-150.877,75.269,270.500); vertex(-139.047,80.373,261.002); vertex(139.047,80.372,261.001); vertex(150.877,75.269,270.500); vertex(139.047,657.626,261.000); vertex(-150.877,662.730,270.500); vertex(150.877,662.730,270.500); vertex(-150.877,662.730,270.500); vertex(139.047,657.626,261.000); vertex(-139.040,657.632,260.998); vertex(150.877,662.730,270.500); vertex(-139.055,657.633,280.004); vertex(139.046,657.628,280.000); vertex(-139.055,657.633,280.004); vertex(150.877,662.730,270.500); vertex(-150.877,662.730,270.500); vertex(150.877,75.269,270.500); vertex(139.047,80.372,261.001); vertex(150.877,662.730,270.500); vertex(150.877,662.730,270.500); vertex(139.047,80.372,261.001); vertex(139.047,657.626,261.000); vertex(-150.877,662.730,270.500); vertex(-139.047,80.373,280.000); vertex(-139.055,657.633,280.004); vertex(-139.047,80.373,280.000); vertex(-150.877,662.730,270.500); vertex(-150.877,75.269,270.500); vertex(150.877,75.269,270.500); vertex(150.877,662.730,270.500); vertex(139.041,80.374,280.005); vertex(-139.047,80.373,261.002); vertex(-150.877,75.269,270.500); vertex(-150.877,662.730,270.500); vertex(-150.877,75.269,270.500); vertex(139.041,80.374,280.005); vertex(-139.047,80.373,280.000); vertex(139.041,80.374,280.005); vertex(-150.877,75.269,270.500); vertex(150.877,75.269,270.500); vertex(139.046,657.628,280.000); vertex(-128.115,654.697,289.998); vertex(128.111,654.699,289.998); vertex(-128.115,654.697,289.998); vertex(139.046,657.628,280.000); vertex(-139.055,657.633,280.004); vertex(-139.055,657.633,280.004); vertex(-139.047,80.373,280.000); vertex(-128.115,654.697,289.998); vertex(139.046,657.628,280.000); vertex(139.041,80.374,280.005); vertex(150.877,662.730,270.500); vertex(128.111,654.699,289.998); vertex(139.041,80.374,280.005); vertex(139.046,657.628,280.000); vertex(-139.047,80.373,280.000); vertex(128.109,83.303,289.999); vertex(-128.110,83.303,290.000); vertex(-139.047,80.373,280.000); vertex(139.041,80.374,280.005); vertex(128.109,83.303,289.999); vertex(128.111,654.699,289.998); vertex(-119.020,654.298,300.004); vertex(118.458,654.270,300.787); vertex(-119.020,654.298,300.004); vertex(128.111,654.699,289.998); vertex(-128.115,654.697,289.998); vertex(-118.328,654.298,301.000); vertex(118.458,654.270,300.787); vertex(-119.020,654.298,300.004); vertex(-128.115,654.697,289.998); vertex(-118.635,83.734,300.492); vertex(-119.020,654.298,300.004); vertex(-118.635,83.734,300.492); vertex(-128.115,654.697,289.998); vertex(-128.110,83.303,290.000); vertex(-128.110,83.303,290.000); vertex(-128.115,654.697,289.998); vertex(-139.047,80.373,280.000); vertex(139.041,80.374,280.005); vertex(128.111,654.699,289.998); vertex(128.109,83.303,289.999); vertex(-118.635,83.734,300.492); vertex(128.109,83.303,289.999); vertex(118.661,83.726,300.482); vertex(-128.110,83.303,290.000); vertex(128.109,83.303,289.999); vertex(-118.635,83.734,300.492); vertex(118.458,654.270,300.787); vertex(-111.762,656.312,310.551); vertex(111.759,656.320,310.575); vertex(-111.762,656.312,310.551); vertex(118.458,654.270,300.787); vertex(-118.328,654.298,301.000); vertex(-119.020,654.298,300.004); vertex(-118.635,83.734,300.492); vertex(-118.328,654.298,301.000); vertex(-118.328,654.298,301.000); vertex(-118.635,83.734,300.492); vertex(-111.762,656.312,310.551); vertex(-111.762,656.312,310.551); vertex(-118.635,83.734,300.492); vertex(-111.747,81.681,310.600); vertex(118.661,83.726,300.482); vertex(128.111,654.699,289.998); vertex(118.458,654.270,300.787); vertex(128.111,654.699,289.998); vertex(118.661,83.726,300.482); vertex(128.109,83.303,289.999); vertex(118.661,83.726,300.482); vertex(118.458,654.270,300.787); vertex(111.876,81.716,310.338); vertex(-118.635,83.734,300.492); vertex(111.876,81.716,310.338); vertex(-111.747,81.681,310.600); vertex(111.876,81.716,310.338); vertex(-118.635,83.734,300.492); vertex(118.661,83.726,300.482); vertex(107.329,660.724,320.330); vertex(-111.762,656.312,310.551); vertex(-107.353,660.723,320.310); vertex(111.759,656.320,310.575); vertex(-111.762,656.312,310.551); vertex(107.329,660.724,320.330); vertex(111.759,656.320,310.575); vertex(111.876,81.716,310.338); vertex(118.458,654.270,300.787); vertex(111.876,81.716,310.338); vertex(111.759,656.320,310.575); vertex(107.329,660.724,320.330); vertex(111.876,81.716,310.338); vertex(107.329,660.724,320.330); vertex(107.374,77.314,320.217); vertex(-111.747,81.681,310.600); vertex(107.374,77.314,320.217); vertex(-107.305,77.175,320.548); vertex(107.374,77.314,320.217); vertex(-111.747,81.681,310.600); vertex(111.876,81.716,310.338); vertex(107.329,660.724,320.330); vertex(-105.269,667.465,330.218); vertex(105.257,667.569,330.433); vertex(-105.269,667.465,330.218); vertex(107.329,660.724,320.330); vertex(-107.353,660.723,320.310); vertex(-107.353,660.723,320.310); vertex(-107.305,77.175,320.548); vertex(-105.269,667.465,330.218); vertex(-105.269,667.465,330.218); vertex(-107.305,77.175,320.548); vertex(-105.261,70.408,330.460); vertex(-111.747,81.681,310.600); vertex(-107.353,660.723,320.310); vertex(-111.762,656.312,310.551); vertex(-107.353,660.723,320.310); vertex(-111.747,81.681,310.600); vertex(-107.305,77.175,320.548); vertex(107.374,77.314,320.217); vertex(107.329,660.724,320.330); vertex(105.257,667.569,330.433); vertex(107.374,77.314,320.217); vertex(105.257,667.569,330.433); vertex(105.261,70.401,330.457); vertex(-107.305,77.175,320.548); vertex(105.261,70.401,330.457); vertex(-105.261,70.408,330.460); vertex(105.261,70.401,330.457); vertex(-107.305,77.175,320.548); vertex(107.374,77.314,320.217); vertex(105.257,667.569,330.433); vertex(-105.698,677.115,341.003); vertex(105.697,677.110,341.000); vertex(-105.698,677.115,341.003); vertex(105.257,667.569,330.433); vertex(-105.269,667.465,330.218); vertex(-105.261,70.408,330.460); vertex(-105.698,677.115,341.003); vertex(-105.269,667.465,330.218); vertex(-105.261,70.408,330.460); vertex(105.697,60.889,341.000); vertex(-105.697,60.890,341.000); vertex(-105.261,70.408,330.460); vertex(105.261,70.401,330.457); vertex(105.697,60.889,341.000); vertex(-105.698,677.115,341.003); vertex(108.629,688.053,351.003); vertex(105.697,677.110,341.000); vertex(108.629,688.053,351.003); vertex(-105.698,677.115,341.003); vertex(-108.627,688.045,351.000); vertex(105.697,677.110,341.000); vertex(105.261,70.401,330.457); vertex(105.257,667.569,330.433); vertex(105.261,70.401,330.457); vertex(105.697,677.110,341.000); vertex(105.697,60.889,341.000); vertex(-105.698,677.115,341.003); vertex(-105.697,60.890,341.000); vertex(-108.629,49.947,351.004); vertex(108.629,688.053,351.003); vertex(105.697,60.889,341.000); vertex(105.697,677.110,341.000); vertex(-105.698,677.115,341.003); vertex(-105.261,70.408,330.460); vertex(-105.697,60.890,341.000); vertex(-108.629,49.947,351.004); vertex(105.697,60.889,341.000); vertex(108.628,49.949,351.006); vertex(105.697,60.889,341.000); vertex(-108.629,49.947,351.004); vertex(-105.697,60.890,341.000); vertex(-108.627,688.045,351.000); vertex(-108.629,49.947,351.004); vertex(-113.462,38.746,360.000); vertex(113.462,699.254,360.000); vertex(108.628,49.949,351.006); vertex(108.629,688.053,351.003); vertex(105.697,60.889,341.000); vertex(108.629,688.053,351.003); vertex(108.628,49.949,351.006); vertex(-108.629,49.947,351.004); vertex(-108.627,688.045,351.000); vertex(-105.698,677.115,341.003); vertex(-105.697,677.107,20.004); vertex(-105.261,70.403,30.544); vertex(-105.267,667.610,30.516); vertex(105.269,667.648,210.465); vertex(105.259,70.425,210.580); vertex(105.697,60.889,200.000); vertex(-113.463,699.255,360.000); vertex(113.463,38.745,360.000); vertex(113.462,699.254,360.000); vertex(113.463,38.745,360.000); vertex(-113.463,699.255,360.000); vertex(-113.462,38.746,360.000); // User Interface (UI) code: // Camera control: // Update camera coordinate system var s=camera; if (!s.X) { // startup: create initial coordinates s.X=new vec3(1,0,0); s.Y=new vec3(0,0,1); s.Z=new vec3(0,-1,0.0); // camera Z is world Y s.P=new vec3(0,-4,1.8); // initial location } // Move camera via keyboard var move=new vec3(0,0,0); // sums current frame motion // X control via A and D if (lib.key['a']) move.pe(new vec3(-1,0,0)); if (lib.key['d']) move.pe(new vec3(+1,0,0)); // Y control via W and S if (lib.key['w']) move.pe(new vec3(0,0,-1)); if (lib.key['s']) move.pe(new vec3(0,0,+1)); // Z control via Q and Z if (lib.key['q']) move.pe(new vec3(0,+1,0)); if (lib.key['z']) move.pe(new vec3(0,-1,0)); move.te(2.0*lib.dt); // meters/second motion rate s.P.pe(s.X.t(move.x).p(s.Y.t(move.y)).p(s.Z.t(move.z))); // Rotate camera via mouse var speed=0.01; // radians per mouse pixel if (lib.mouseleft) { // move Z with mouse s.Z.pe(s.X.t(-lib.mousedx*speed).p( s.Y.t( lib.mousedy*speed))); } // Keep level: make sure X is horizontal. s.X.z=0.0; s.Y.crossVectors(s.Z,s.X.normalize()); // Orthonormalize s.X.crossVectors(s.Y,s.Z).normalize(); s.Y.crossVectors(s.Z,s.X).normalize(); s.Z.normalize(); // Write coordinate system into matrix s.matrixAutoUpdate=false; // don't trash s.matrixWorldNeedsUpdate=true; // show var m=s.matrix; // the camera's matrix // Utility function: set a matrix column function setCol(m,col,vec) { m.elements[4*col+0]=vec.x; m.elements[4*col+1]=vec.y; m.elements[4*col+2]=vec.z; } setCol(m,0,s.X); setCol(m,1,s.Y); setCol(m,2,s.Z); setCol(m,3,s.P); // position from sim