FOV demo forked from somewhere

by Augustus Yuan

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
<body onload="start()">
  <p>
    Move mouse to change viewing direction. Click to reposition viewer.<br/><br/>
      <label for="chkDebug">Debug View</label>
      <input type="checkbox" name="chkDebug" onchange="toggleDebugView()">
    </p>
  <canvas id="canvas2d" width="640" height="480" />
</body>

CSS

body {
  margin: 0;
  background: #eee;
}

JavaScript

"use strict";

 var canvas = document.getElementById("canvas2d");
 var ctx, scene;
 var FoV = 1.25663706143; // 72° field of vision in radians
 var halfFoV = FoV / 2;
 var halfFoVCos = Math.cos(halfFoV); // 0.809016994375
 var halfFoVSin = Math.sin(halfFoV); // 0.587785252292
 var visionRadius = 240;
 var personRadius = 5;
 var wallColour = "105, 105, 105";
 var observerColour = "255, 128, 128";
 var targetColour = "128, 128, 255";
 var targetSeenColour = "255, 0, 255";
 // 0.01 or even 0.05 doesn't work in this case: an angle point was found by an
 // edge – sector arc intersection; later the ray formed due to this angle point
 // hits the same (blocking) edge and the edge – ray intersection point obtained
 // would be on the arc, but the squared distance between the sector centre and
 // this point is slightly smaller than the sector radius.
 // Test case: keep only the first two and the world boundary polygons, set
 // sector.centre = (129, 316), rotate sector 360° and test for correctness.
 // Test case: keep only the triangle and the world boundary polygons, set
 // sector.centre = (120, 249), rotate sector 360° and test for correctness.
 var epsilon = 0.075;
 var halfAuxRayTilt = 8.72664625995e-3; // half degree in radians
 var halfAuxRayTiltCos = Math.cos(halfAuxRayTilt); // 0.999961923064
 var halfAuxRayTiltSin = Math.sin(halfAuxRayTilt); // 8.72653549837e-3

 // enable this for debug view
 var debug = false;

 function isZero(v) {
   return (Math.abs(v[0]) + Math.abs(v[1])) <= epsilon;
 }

 function cross2d(a, b) {
   return (a[0] * b[1]) - (a[1] * b[0]);
 }

 // direction is optional; defaults to counter-clockwise
 function perp2d(v, clockwise) {
   clockwise = clockwise || false;
   if (clockwise)
     return vec2.fromValues(v[1], -v[0]);
   return vec2.fromValues(-v[1], v[0]);
 }

 // line should have start point, vector and square length
 function invLerp(line, point) {
   var t = vec2.create();
   vec2.sub(t, point, line.ends[0]);
   return...