Hex Artifact Content
Not logged in

Artifact 52461a961c2998ae1e8be3db799bd626a5692710:


0000: 0d 0a 0d 0a 2f 2f 20 72 65 71 75 69 72 65 73 20  ....// requires 
0010: 6d 61 74 72 69 78 5f 76 65 63 74 6f 72 5f 6c 69  matrix_vector_li
0020: 62 2e 6a 73 0d 0a 2f 2f 20 54 4f 44 4f 20 77 65  b.js..// TODO we
0030: 20 63 6f 75 6c 64 20 6d 61 6b 65 20 73 6f 6d 65   could make some
0040: 20 6c 69 62 72 61 72 79 6c 65 73 73 20 77 61 79   libraryless way
0050: 20 6f 66 20 63 68 65 63 6b 69 6e 67 20 64 65 70   of checking dep
0060: 65 6e 64 65 6e 63 69 65 73 20 61 6e 64 20 76 65  endencies and ve
0070: 72 73 69 6f 6e 73 2e 0d 0a 0d 0a 0d 0a 2f 2f 20  rsions.......// 
0080: 67 6c 6f 62 61 6c 20 6e 61 6d 65 73 70 61 63 65  global namespace
0090: 20 6f 62 6a 65 63 74 0d 0a 76 61 72 20 57 69 72   object..var Wir
00a0: 65 66 72 61 6d 65 4d 6f 64 65 6c 3b 0d 0a 0d 0a  eframeModel;....
00b0: 0d 0a 28 66 75 6e 63 74 69 6f 6e 28 29 7b 0d 0a  ..(function(){..
00c0: 0d 0a 0d 0a 0d 0a 0d 0a 0d 0a 2f 2f 20 63 6f 6e  ..........// con
00d0: 76 65 72 74 73 20 61 20 70 6f 69 6e 74 20 66 72  verts a point fr
00e0: 6f 6d 20 74 68 72 65 65 20 73 70 61 63 65 20 74  om three space t
00f0: 6f 20 74 68 65 20 63 61 6e 76 61 73 20 70 6c 61  o the canvas pla
0100: 6e 65 2e 0d 0a 2f 2f 20 4e 6f 74 65 3a 20 62 65  ne...// Note: be
0110: 63 61 75 73 65 20 6f 66 20 64 65 70 74 68 20 70  cause of depth p
0120: 65 72 73 70 65 63 74 69 76 65 2c 20 74 68 69 73  erspective, this
0130: 20 63 6f 6e 76 65 72 73 69 6f 6e 20 69 73 20 6e   conversion is n
0140: 6f 74 0d 0a 2f 2f 20 65 61 73 79 20 74 6f 20 64  ot..// easy to d
0150: 65 66 69 6e 65 20 69 66 20 74 68 65 20 70 6f 69  efine if the poi
0160: 6e 74 20 6c 69 65 73 20 62 65 68 69 6e 64 20 74  nt lies behind t
0170: 68 65 20 63 61 6d 65 72 61 2e 0d 0a 2f 2f 20 54  he camera...// T
0180: 68 65 72 65 20 61 72 65 20 74 77 6f 20 6f 70 74  here are two opt
0190: 69 6f 6e 73 3a 0d 0a 2f 2f 20 57 68 65 6e 20 64  ions:..// When d
01a0: 72 61 77 69 6e 67 20 61 20 6c 69 6e 65 2c 20 61  rawing a line, a
01b0: 6e 6f 74 68 65 72 20 63 6f 6c 69 6e 65 61 72 20  nother colinear 
01c0: 70 6f 69 6e 74 20 69 6e 20 66 72 6f 6e 74 20 6f  point in front o
01d0: 66 20 74 68 65 20 63 61 6d 65 72 61 20 6d 61 79  f the camera may
01e0: 20 62 65 20 70 72 6f 76 69 64 65 64 0d 0a 2f 2f   be provided..//
01f0: 20 74 6f 20 68 65 6c 70 20 66 69 6e 64 20 61 6e   to help find an
0200: 20 61 6c 74 65 72 6e 61 74 65 20 70 6f 69 6e 74   alternate point
0210: 2e 0d 0a 2f 2f 20 69 66 20 62 6f 74 68 20 70 6f  ...// if both po
0220: 69 6e 74 73 20 6c 69 65 20 62 65 68 69 6e 64 20  ints lie behind 
0230: 74 68 65 20 63 61 6d 65 72 61 20 6f 72 20 74 68  the camera or th
0240: 65 20 63 6f 6c 69 6e 65 61 72 5f 70 6f 69 6e 74  e colinear_point
0250: 20 69 73 20 6e 6f 74 20 70 72 6f 76 69 64 65 64   is not provided
0260: 2c 0d 0a 2f 2f 20 74 68 69 73 20 66 75 6e 63 74  ,..// this funct
0270: 69 6f 6e 20 77 69 6c 6c 20 72 65 74 75 72 6e 20  ion will return 
0280: 6e 75 6c 6c 2e 0d 0a 20 0d 0a 66 75 6e 63 74 69  null... ..functi
0290: 6f 6e 20 70 72 6f 6a 65 63 74 28 63 61 6e 76 61  on project(canva
02a0: 73 2c 20 78 79 7a 2c 20 76 69 65 77 2c 20 63 6f  s, xyz, view, co
02b0: 6c 69 6e 65 61 72 5f 70 6f 69 6e 74 29 7b 0d 0a  linear_point){..
02c0: 20 20 20 20 69 66 28 21 78 79 7a 29 20 72 65 74      if(!xyz) ret
02d0: 75 72 6e 20 6e 75 6c 6c 3b 20 20 2f 2f 20 70 6f  urn null;  // po
02e0: 69 6e 74 20 68 61 73 20 62 65 65 6e 20 64 65 6c  int has been del
02f0: 65 74 65 64 20 6f 72 20 64 6f 65 73 20 6e 6f 74  eted or does not
0300: 20 65 78 69 73 74 0d 0a 20 20 20 20 0d 0a 09 76   exist..    ...v
0310: 61 72 20 76 69 65 77 5f 74 72 61 6e 73 66 6f 72  ar view_transfor
0320: 6d 20 3d 20 76 69 65 77 2e 74 72 61 6e 73 66 6f  m = view.transfo
0330: 72 6d 3b 0d 0a 09 76 61 72 20 6f 72 69 67 69 6e  rm;...var origin
0340: 20 3d 20 76 69 65 77 2e 6f 72 69 67 69 6e 3b 0d   = view.origin;.
0350: 0a 09 76 61 72 20 7a 6f 6f 6d 5f 73 63 61 6c 65  ..var zoom_scale
0360: 20 3d 20 76 69 65 77 2e 7a 6f 6f 6d 5f 73 63 61   = view.zoom_sca
0370: 6c 65 3b 0d 0a 09 76 61 72 20 7a 6f 6f 6d 5f 64  le;...var zoom_d
0380: 69 73 74 20 3d 20 76 69 65 77 2e 7a 6f 6f 6d 5f  ist = view.zoom_
0390: 64 69 73 74 3b 0d 0a 09 0d 0a 09 69 66 28 21 7a  dist;......if(!z
03a0: 6f 6f 6d 5f 73 63 61 6c 65 29 20 7a 6f 6f 6d 5f  oom_scale) zoom_
03b0: 73 63 61 6c 65 20 3d 20 31 3b 0d 0a 09 69 66 28  scale = 1;...if(
03c0: 21 7a 6f 6f 6d 5f 64 69 73 74 29 20 7a 6f 6f 6d  !zoom_dist) zoom
03d0: 5f 64 69 73 74 20 3d 20 30 3b 0d 0a 09 69 66 28  _dist = 0;...if(
03e0: 21 6f 72 69 67 69 6e 29 20 6f 72 69 67 69 6e 20  !origin) origin 
03f0: 3d 20 5b 30 2c 30 2c 30 5d 3b 0d 0a 09 0d 0a 09  = [0,0,0];......
0400: 0d 0a 20 20 20 20 76 61 72 20 77 20 3d 20 63 61  ..    var w = ca
0410: 6e 76 61 73 2e 77 69 64 74 68 3b 0d 0a 20 20 20  nvas.width;..   
0420: 20 76 61 72 20 68 20 3d 20 63 61 6e 76 61 73 2e   var h = canvas.
0430: 68 65 69 67 68 74 3b 0d 0a 20 20 20 20 0d 0a 20  height;..    .. 
0440: 20 20 20 76 61 72 20 73 63 61 6c 65 20 3d 20 4d     var scale = M
0450: 61 74 68 2e 6d 69 6e 28 77 2c 20 68 29 3b 0d 0a  ath.min(w, h);..
0460: 20 20 20 20 0d 0a 20 20 20 20 76 61 72 20 76 20      ..    var v 
0470: 3d 20 78 79 7a 2e 73 6c 69 63 65 28 30 29 3b 0d  = xyz.slice(0);.
0480: 0a 20 20 20 20 69 66 28 6f 72 69 67 69 6e 29 20  .    if(origin) 
0490: 76 20 3d 20 76 65 63 74 6f 72 5f 6d 69 6e 75 73  v = vector_minus
04a0: 28 76 2c 20 6f 72 69 67 69 6e 2c 20 76 29 3b 0d  (v, origin, v);.
04b0: 0a 20 20 20 20 0d 0a 20 20 20 20 76 61 72 20 7a  .    ..    var z
04c0: 20 3d 20 76 65 63 74 6f 72 5f 64 6f 74 28 76 69   = vector_dot(vi
04d0: 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b 32 5d 2c  ew_transform[2],
04e0: 20 76 29 3b 0d 0a 20 20 20 20 0d 0a 20 20 20 20   v);..    ..    
04f0: 69 66 28 7a 20 3c 3d 20 2d 7a 6f 6f 6d 5f 64 69  if(z <= -zoom_di
0500: 73 74 29 7b 20 20 2f 2f 20 74 68 69 73 20 70 6f  st){  // this po
0510: 69 6e 74 20 69 73 20 6f 6e 20 74 68 65 20 77 72  int is on the wr
0520: 6f 6e 67 20 73 69 64 65 20 6f 66 20 74 68 65 20  ong side of the 
0530: 76 69 65 77 65 72 2c 20 66 69 6e 64 20 74 68 65  viewer, find the
0540: 20 63 6c 6f 73 65 73 74 20 70 6f 69 6e 74 20 6f   closest point o
0550: 6e 20 74 68 65 20 63 6f 72 72 65 63 74 20 73 69  n the correct si
0560: 64 65 20 69 66 20 77 65 20 63 61 6e 2e 0d 0a 20  de if we can... 
0570: 20 20 20 20 20 20 20 69 66 28 21 63 6f 6c 69 6e         if(!colin
0580: 65 61 72 5f 70 6f 69 6e 74 29 20 72 65 74 75 72  ear_point) retur
0590: 6e 20 6e 75 6c 6c 3b 0d 0a 20 20 20 20 20 20 20  n null;..       
05a0: 20 0d 0a 20 20 20 20 20 20 20 20 76 61 72 20 76   ..        var v
05b0: 32 20 3d 20 63 6f 6c 69 6e 65 61 72 5f 70 6f 69  2 = colinear_poi
05c0: 6e 74 2e 73 6c 69 63 65 28 30 29 3b 0d 0a 20 20  nt.slice(0);..  
05d0: 20 20 20 20 20 20 69 66 28 6f 72 69 67 69 6e 29        if(origin)
05e0: 20 76 65 63 74 6f 72 5f 6d 69 6e 75 73 28 76 32   vector_minus(v2
05f0: 2c 20 6f 72 69 67 69 6e 2c 20 76 32 29 3b 0d 0a  , origin, v2);..
0600: 20 20 20 20 20 20 20 20 0d 0a 20 20 20 20 20 20          ..      
0610: 20 20 76 61 72 20 7a 32 20 3d 20 76 65 63 74 6f    var z2 = vecto
0620: 72 5f 64 6f 74 28 76 69 65 77 5f 74 72 61 6e 73  r_dot(view_trans
0630: 66 6f 72 6d 5b 32 5d 2c 20 76 32 29 3b 0d 0a 20  form[2], v2);.. 
0640: 20 20 20 20 20 20 20 0d 0a 20 20 20 20 20 20 20         ..       
0650: 20 69 66 28 7a 32 20 3c 20 30 29 20 72 65 74 75   if(z2 < 0) retu
0660: 72 6e 20 6e 75 6c 6c 3b 0d 0a 20 20 20 20 20 20  rn null;..      
0670: 20 20 0d 0a 20 20 20 20 20 20 20 20 2f 2f 20 67    ..        // g
0680: 65 74 20 74 68 65 20 63 6f 65 66 66 69 63 69 65  et the coefficie
0690: 6e 74 73 20 66 6f 72 20 61 20 63 6f 6d 70 6c 65  nts for a comple
06a0: 78 20 63 6f 6d 62 69 6e 61 74 69 6f 6e 2e 0d 0a  x combination...
06b0: 20 20 20 20 20 20 20 20 2f 2f 20 74 2a 7a 20 2b          // t*z +
06c0: 20 28 31 2d 74 29 2a 7a 32 20 3d 20 30 2e 30 30   (1-t)*z2 = 0.00
06d0: 30 32 20 20 2d 2d 20 7a 20 6f 66 20 6e 65 77 20  02  -- z of new 
06e0: 70 6f 69 6e 74 20 69 73 20 6a 75 73 74 20 62 61  point is just ba
06f0: 72 65 6c 79 20 69 6e 66 72 6f 6e 74 20 6f 66 20  rely infront of 
0700: 74 68 65 20 63 61 6d 65 72 61 2e 0d 0a 20 20 20  the camera...   
0710: 20 20 20 20 20 0d 0a 20 20 20 20 20 20 20 20 76       ..        v
0720: 61 72 20 74 20 3d 20 28 30 2e 30 30 30 32 20 2d  ar t = (0.0002 -
0730: 20 7a 32 29 2f 28 7a 20 2d 20 7a 32 29 3b 20 20   z2)/(z - z2);  
0740: 2f 2f 20 6e 6f 20 64 69 76 69 73 69 6f 6e 20 62  // no division b
0750: 79 20 7a 65 72 6f 2c 20 7a 20 69 73 20 6e 65 67  y zero, z is neg
0760: 61 74 69 76 65 2c 20 7a 32 20 69 73 20 70 6f 73  ative, z2 is pos
0770: 69 74 69 76 65 0d 0a 20 20 20 20 20 20 20 20 0d  itive..        .
0780: 0a 20 20 20 20 20 20 20 20 76 65 63 74 6f 72 5f  .        vector_
0790: 61 64 64 28 76 65 63 74 6f 72 5f 73 63 61 6c 65  add(vector_scale
07a0: 28 76 2c 20 74 2c 20 76 29 2c 0d 0a 20 20 20 20  (v, t, v),..    
07b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 76                 v
07c0: 65 63 74 6f 72 5f 73 63 61 6c 65 28 76 32 2c 20  ector_scale(v2, 
07d0: 31 2d 74 2c 20 76 32 29 2c 0d 0a 20 20 20 20 20  1-t, v2),..     
07e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 76 29                v)
07f0: 3b 0d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ;..             
0800: 20 20 20 20 20 20 0d 0a 20 20 20 20 20 20 20 20        ..        
0810: 7a 20 3d 20 76 65 63 74 6f 72 5f 64 6f 74 28 76  z = vector_dot(v
0820: 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b 32 5d  iew_transform[2]
0830: 2c 20 76 29 3b 20 7d 0d 0a 0d 0a 20 20 20 20 20  , v); }....     
0840: 20 20 20 0d 0a 20 20 20 20 76 61 72 20 73 63 61     ..    var sca
0850: 6c 65 32 20 3d 20 7a 6f 6f 6d 5f 73 63 61 6c 65  le2 = zoom_scale
0860: 20 2a 20 73 63 61 6c 65 20 2f 20 28 7a 6f 6f 6d   * scale / (zoom
0870: 5f 64 69 73 74 20 2b 20 7a 29 3b 0d 0a 20 20 20  _dist + z);..   
0880: 20 0d 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 20   ..    return [ 
0890: 73 63 61 6c 65 32 20 2a 20 76 65 63 74 6f 72 5f  scale2 * vector_
08a0: 64 6f 74 28 76 69 65 77 5f 74 72 61 6e 73 66 6f  dot(view_transfo
08b0: 72 6d 5b 30 5d 2c 20 76 29 20 2b 20 30 2e 35 20  rm[0], v) + 0.5 
08c0: 2a 20 77 2c 0d 0a 20 20 20 20 20 20 20 20 20 20  * w,..          
08d0: 20 20 20 73 63 61 6c 65 32 20 2a 20 76 65 63 74     scale2 * vect
08e0: 6f 72 5f 64 6f 74 28 76 69 65 77 5f 74 72 61 6e  or_dot(view_tran
08f0: 73 66 6f 72 6d 5b 31 5d 2c 20 76 29 20 2b 20 30  sform[1], v) + 0
0900: 2e 35 20 2a 20 68 20 5d 3b 20 7d 0d 0a 0d 0a 0d  .5 * h ]; }.....
0910: 0a 0d 0a 2f 2f 20 20 4a 75 73 74 20 6c 69 6b 65  ...//  Just like
0920: 20 74 68 65 20 70 72 6f 6a 65 63 74 20 66 75 6e   the project fun
0930: 63 74 69 6f 6e 20 61 62 6f 76 65 20 62 75 74 20  ction above but 
0940: 66 6f 72 20 61 20 73 65 74 20 6f 66 20 70 6f 69  for a set of poi
0950: 6e 74 73 2e 0d 0a 2f 2f 20 20 49 74 27 73 20 70  nts...//  It's p
0960: 75 74 20 69 6e 74 6f 20 61 20 6c 6f 6f 70 20 61  ut into a loop a
0970: 20 6c 69 74 74 6c 65 20 62 65 74 74 65 72 2e 0d   little better..
0980: 0a 66 75 6e 63 74 69 6f 6e 20 70 72 6f 6a 65 63  .function projec
0990: 74 5f 61 6c 6c 28 63 61 6e 76 61 73 2c 20 70 6f  t_all(canvas, po
09a0: 69 6e 74 73 2c 20 70 6f 69 6e 74 5f 70 72 6f 6a  ints, point_proj
09b0: 65 63 74 69 6f 6e 73 2c 20 76 69 65 77 29 7b 0d  ections, view){.
09c0: 0a 0d 0a 09 76 61 72 20 76 69 65 77 5f 74 72 61  ....var view_tra
09d0: 6e 73 66 6f 72 6d 20 3d 20 76 69 65 77 2e 74 72  nsform = view.tr
09e0: 61 6e 73 66 6f 72 6d 3b 0d 0a 09 76 61 72 20 6f  ansform;...var o
09f0: 72 69 67 69 6e 20 3d 20 76 69 65 77 2e 6f 72 69  rigin = view.ori
0a00: 67 69 6e 3b 0d 0a 09 76 61 72 20 7a 6f 6f 6d 5f  gin;...var zoom_
0a10: 73 63 61 6c 65 20 3d 20 76 69 65 77 2e 7a 6f 6f  scale = view.zoo
0a20: 6d 5f 73 63 61 6c 65 3b 0d 0a 09 76 61 72 20 7a  m_scale;...var z
0a30: 6f 6f 6d 5f 64 69 73 74 20 3d 20 76 69 65 77 2e  oom_dist = view.
0a40: 7a 6f 6f 6d 5f 64 69 73 74 3b 0d 0a 09 0d 0a 09  zoom_dist;......
0a50: 69 66 28 21 7a 6f 6f 6d 5f 73 63 61 6c 65 29 20  if(!zoom_scale) 
0a60: 7a 6f 6f 6d 5f 73 63 61 6c 65 20 3d 20 31 3b 0d  zoom_scale = 1;.
0a70: 0a 09 69 66 28 21 7a 6f 6f 6d 5f 64 69 73 74 29  ..if(!zoom_dist)
0a80: 20 7a 6f 6f 6d 5f 64 69 73 74 20 3d 20 30 3b 0d   zoom_dist = 0;.
0a90: 0a 09 69 66 28 21 6f 72 69 67 69 6e 29 20 6f 72  ..if(!origin) or
0aa0: 69 67 69 6e 20 3d 20 5b 30 2c 30 2c 30 5d 3b 0d  igin = [0,0,0];.
0ab0: 0a 09 0d 0a 0d 0a 20 20 20 20 69 66 28 21 70 6f  ......    if(!po
0ac0: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 29  int_projections)
0ad0: 20 70 6f 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f   point_projectio
0ae0: 6e 73 20 3d 20 5b 5d 3b 0d 0a 09 70 6f 69 6e 74  ns = [];...point
0af0: 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 2e 6c 65 6e  _projections.len
0b00: 67 74 68 20 3d 20 70 6f 69 6e 74 73 2e 6c 65 6e  gth = points.len
0b10: 67 74 68 3b 0d 0a 20 20 20 20 0d 0a 20 20 20 20  gth;..    ..    
0b20: 76 61 72 20 77 20 3d 20 63 61 6e 76 61 73 2e 77  var w = canvas.w
0b30: 69 64 74 68 3b 0d 0a 20 20 20 20 76 61 72 20 68  idth;..    var h
0b40: 20 3d 20 63 61 6e 76 61 73 2e 68 65 69 67 68 74   = canvas.height
0b50: 3b 0d 0a 09 76 61 72 20 77 5f 32 20 3d 20 77 2f  ;...var w_2 = w/
0b60: 32 3b 0d 0a 09 76 61 72 20 68 5f 32 20 3d 20 68  2;...var h_2 = h
0b70: 2f 32 3b 0d 0a 20 20 20 20 0d 0a 20 20 20 20 76  /2;..    ..    v
0b80: 61 72 20 73 63 61 6c 65 20 3d 20 7a 6f 6f 6d 5f  ar scale = zoom_
0b90: 73 63 61 6c 65 20 2a 20 4d 61 74 68 2e 6d 69 6e  scale * Math.min
0ba0: 28 77 2c 20 68 29 3b 0d 0a 09 0d 0a 09 76 61 72  (w, h);......var
0bb0: 20 76 30 30 20 3d 20 76 69 65 77 5f 74 72 61 6e   v00 = view_tran
0bc0: 73 66 6f 72 6d 5b 30 5d 5b 30 5d 3b 0d 0a 09 76  sform[0][0];...v
0bd0: 61 72 20 76 30 31 20 3d 20 76 69 65 77 5f 74 72  ar v01 = view_tr
0be0: 61 6e 73 66 6f 72 6d 5b 30 5d 5b 31 5d 3b 0d 0a  ansform[0][1];..
0bf0: 09 76 61 72 20 76 30 32 20 3d 20 76 69 65 77 5f  .var v02 = view_
0c00: 74 72 61 6e 73 66 6f 72 6d 5b 30 5d 5b 32 5d 3b  transform[0][2];
0c10: 0d 0a 09 76 61 72 20 76 31 30 20 3d 20 76 69 65  ...var v10 = vie
0c20: 77 5f 74 72 61 6e 73 66 6f 72 6d 5b 31 5d 5b 30  w_transform[1][0
0c30: 5d 3b 0d 0a 09 76 61 72 20 76 31 31 20 3d 20 76  ];...var v11 = v
0c40: 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b 31 5d  iew_transform[1]
0c50: 5b 31 5d 3b 0d 0a 09 76 61 72 20 76 31 32 20 3d  [1];...var v12 =
0c60: 20 76 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b   view_transform[
0c70: 31 5d 5b 32 5d 3b 0d 0a 09 76 61 72 20 76 32 30  1][2];...var v20
0c80: 20 3d 20 76 69 65 77 5f 74 72 61 6e 73 66 6f 72   = view_transfor
0c90: 6d 5b 32 5d 5b 30 5d 3b 0d 0a 09 76 61 72 20 76  m[2][0];...var v
0ca0: 32 31 20 3d 20 76 69 65 77 5f 74 72 61 6e 73 66  21 = view_transf
0cb0: 6f 72 6d 5b 32 5d 5b 31 5d 3b 0d 0a 09 76 61 72  orm[2][1];...var
0cc0: 20 76 32 32 20 3d 20 76 69 65 77 5f 74 72 61 6e   v22 = view_tran
0cd0: 73 66 6f 72 6d 5b 32 5d 5b 32 5d 3b 0d 0a 09 0d  sform[2][2];....
0ce0: 0a 20 20 20 20 0d 0a 09 66 6f 72 28 76 61 72 20  .    ...for(var 
0cf0: 69 20 3d 20 30 3b 20 69 20 3c 20 70 6f 69 6e 74  i = 0; i < point
0d00: 73 2e 6c 65 6e 67 74 68 3b 20 2b 2b 69 29 7b 0d  s.length; ++i){.
0d10: 0a 09 09 76 61 72 20 70 74 20 3d 20 70 6f 69 6e  ...var pt = poin
0d20: 74 73 5b 69 5d 3b 0d 0a 09 09 0d 0a 09 09 76 61  ts[i];........va
0d30: 72 20 78 20 3d 20 70 74 5b 30 5d 3b 0d 0a 09 09  r x = pt[0];....
0d40: 76 61 72 20 79 20 3d 20 70 74 5b 31 5d 3b 0d 0a  var y = pt[1];..
0d50: 09 09 76 61 72 20 7a 20 3d 20 70 74 5b 32 5d 3b  ..var z = pt[2];
0d60: 0d 0a 09 09 0d 0a 09 09 69 66 28 6f 72 69 67 69  ........if(origi
0d70: 6e 29 7b 0d 0a 09 20 20 20 20 20 20 20 20 20 78  n){...         x
0d80: 20 2d 3d 20 6f 72 69 67 69 6e 5b 30 5d 3b 0d 0a   -= origin[0];..
0d90: 09 09 09 20 79 20 2d 3d 20 6f 72 69 67 69 6e 5b  ... y -= origin[
0da0: 31 5d 3b 0d 0a 09 09 09 20 7a 20 2d 3d 20 6f 72  1];..... z -= or
0db0: 69 67 69 6e 5b 32 5d 3b 20 7d 0d 0a 09 09 0d 0a  igin[2]; }......
0dc0: 09 09 76 61 72 20 64 65 70 74 68 20 3d 20 78 2a  ..var depth = x*
0dd0: 76 32 30 20 2b 20 79 2a 76 32 31 20 2b 20 7a 2a  v20 + y*v21 + z*
0de0: 76 32 32 3b 0d 0a 09 09 76 61 72 20 73 63 61 6c  v22;....var scal
0df0: 65 32 20 3d 20 73 63 61 6c 65 20 2f 20 28 7a 6f  e2 = scale / (zo
0e00: 6f 6d 5f 64 69 73 74 20 2b 20 64 65 70 74 68 29  om_dist + depth)
0e10: 3b 0d 0a 09 09 0d 0a 09 09 69 66 28 21 70 6f 69  ;........if(!poi
0e20: 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b 69  nt_projections[i
0e30: 5d 29 20 70 6f 69 6e 74 5f 70 72 6f 6a 65 63 74  ]) point_project
0e40: 69 6f 6e 73 5b 69 5d 20 3d 20 5b 30 2c 20 30 5d  ions[i] = [0, 0]
0e50: 3b 0d 0a 09 09 0d 0a 09 09 76 61 72 20 70 6f 69  ;........var poi
0e60: 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 20 3d 20  nt_projection = 
0e70: 70 6f 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e  point_projection
0e80: 73 5b 69 5d 3b 0d 0a 09 09 0d 0a 09 09 70 6f 69  s[i];........poi
0e90: 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 5b 30 5d  nt_projection[0]
0ea0: 20 3d 20 73 63 61 6c 65 32 20 2a 20 28 78 2a 76   = scale2 * (x*v
0eb0: 30 30 20 2b 20 79 2a 76 30 31 20 2b 20 7a 2a 76  00 + y*v01 + z*v
0ec0: 30 32 29 20 2b 20 77 5f 32 3b 0d 0a 09 09 70 6f  02) + w_2;....po
0ed0: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 5b 31  int_projection[1
0ee0: 5d 20 3d 20 73 63 61 6c 65 32 20 2a 20 28 78 2a  ] = scale2 * (x*
0ef0: 76 31 30 20 2b 20 79 2a 76 31 31 20 2b 20 7a 2a  v10 + y*v11 + z*
0f00: 76 32 32 29 20 2b 20 68 5f 32 3b 20 7d 0d 0a 09  v22) + h_2; }...
0f10: 0d 0a 09 72 65 74 75 72 6e 20 70 6f 69 6e 74 5f  ...return point_
0f20: 70 72 6f 6a 65 63 74 69 6f 6e 73 3b 20 7d 0d 0a  projections; }..
0f30: 0d 0a 0d 0a 0d 0a 0d 0a 2f 2f 20 20 41 20 77 69  ........//  A wi
0f40: 72 65 66 72 61 6d 65 20 6d 6f 64 65 6c 20 61 6e  reframe model an
0f50: 64 20 61 6c 6c 20 74 68 65 20 63 6f 6e 74 72 6f  d all the contro
0f60: 6c 73 20 6e 65 65 64 65 64 20 74 6f 20 6d 6f 76  ls needed to mov
0f70: 65 20 74 68 65 20 63 61 6d 65 72 61 20 61 6e 64  e the camera and
0f80: 20 64 72 61 77 2e 0d 0a 2f 2f 20 20 64 65 73 70   draw...//  desp
0f90: 69 74 65 20 74 68 65 20 6e 61 6d 65 2c 20 69 74  ite the name, it
0fa0: 20 6d 61 79 20 61 6c 73 6f 20 69 6e 63 6c 75 64   may also includ
0fb0: 65 20 70 6f 6c 79 67 6f 6e 20 73 75 72 66 61 63  e polygon surfac
0fc0: 65 73 2e 0d 0a 66 75 6e 63 74 69 6f 6e 20 5f 5f  es...function __
0fd0: 57 69 72 65 66 72 61 6d 65 4d 6f 64 65 6c 28 29  WireframeModel()
0fe0: 7b 0d 0a 0d 0a 09 76 61 72 20 57 46 4d 4f 62 6a  {.....var WFMObj
0ff0: 20 3d 20 74 68 69 73 3b 0d 0a 09 0d 0a 09 76 61   = this;......va
1000: 72 20 76 69 65 77 5f 6f 72 69 67 69 6e 20 3d 20  r view_origin = 
1010: 5b 30 2c 20 30 2c 20 30 5d 3b 0d 0a 09 76 61 72  [0, 0, 0];...var
1020: 20 76 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 20   view_transform 
1030: 3d 20 5b 5b 31 2c 20 30 2c 20 30 5d 2c 0d 0a 09  = [[1, 0, 0],...
1040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1050: 20 20 20 20 20 20 5b 30 2c 20 31 2c 20 30 5d 2c        [0, 1, 0],
1060: 0d 0a 09 09 09 09 09 09 20 20 5b 30 2c 20 30 2c  ........  [0, 0,
1070: 20 31 5d 5d 3b 0d 0a 0d 0a 0d 0a 0d 0a 09 76 61   1]];.........va
1080: 72 20 70 6f 69 6e 74 73 20 3d 20 5b 5d 3b 20 2f  r points = []; /
1090: 2f 67 6c 6f 62 61 6c 0d 0a 09 76 61 72 20 70 6f  /global...var po
10a0: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 20  int_projections 
10b0: 3d 20 5b 5d 3b 0d 0a 09 2f 2f 76 61 72 20 73 6f  = [];...//var so
10c0: 6c 6f 5f 70 6f 69 6e 74 73 20 3d 20 7b 7d 3b 0d  lo_points = {};.
10d0: 0a 09 76 61 72 20 6c 69 6e 65 73 20 3d 20 5b 5d  ..var lines = []
10e0: 3b 0d 0a 09 76 61 72 20 7a 6f 6f 6d 5f 73 63 61  ;...var zoom_sca
10f0: 6c 65 20 3d 20 31 3b 0d 0a 09 76 61 72 20 7a 6f  le = 1;...var zo
1100: 6f 6d 5f 64 69 73 74 20 3d 20 31 3b 0d 0a 09 0d  om_dist = 1;....
1110: 0a 09 2f 2f 20 6a 75 73 74 20 62 65 63 61 75 73  ..// just becaus
1120: 65 20 74 68 65 73 65 20 61 63 74 75 61 6c 20 6f  e these actual o
1130: 62 6a 65 63 74 73 20 69 73 20 72 65 74 75 72 6e  bjects is return
1140: 65 64 0d 0a 09 2f 2f 20 64 6f 65 73 6e 27 74 20  ed...// doesn't 
1150: 6d 65 61 6e 20 79 6f 75 20 73 68 6f 75 6c 64 20  mean you should 
1160: 6d 6f 64 69 66 79 20 69 74 20 65 78 74 65 72 6e  modify it extern
1170: 61 6c 6c 79 20 69 66 20 79 6f 75 20 63 61 6e 20  ally if you can 
1180: 68 65 6c 70 20 69 74 2e 0d 0a 09 0d 0a 09 57 46  help it.......WF
1190: 4d 4f 62 6a 2e 67 65 74 50 6f 69 6e 74 73 20 3d  MObj.getPoints =
11a0: 20 66 75 6e 63 74 69 6f 6e 20 67 65 74 50 6f 69   function getPoi
11b0: 6e 74 73 28 29 7b 0d 0a 09 09 72 65 74 75 72 6e  nts(){....return
11c0: 20 70 6f 69 6e 74 73 3b 20 7d 0d 0a 09 09 0d 0a   points; }......
11d0: 09 57 46 4d 4f 62 6a 2e 67 65 74 50 6f 69 6e 74  .WFMObj.getPoint
11e0: 20 3d 20 66 75 6e 63 74 69 6f 6e 20 67 65 74 50   = function getP
11f0: 6f 69 6e 74 28 69 6e 64 65 78 29 7b 0d 0a 09 09  oint(index){....
1200: 72 65 74 75 72 6e 20 70 6f 69 6e 74 73 5b 69 6e  return points[in
1210: 64 65 78 5d 2e 73 6c 69 63 65 28 30 29 3b 20 7d  dex].slice(0); }
1220: 0d 0a 09 0d 0a 09 57 46 4d 4f 62 6a 2e 67 65 74  ......WFMObj.get
1230: 4c 69 6e 65 73 20 3d 20 66 75 6e 63 74 69 6f 6e  Lines = function
1240: 20 67 65 74 4c 69 6e 65 73 28 29 7b 0d 0a 09 09   getLines(){....
1250: 72 65 74 75 72 6e 20 6c 69 6e 65 73 3b 20 7d 0d  return lines; }.
1260: 0a 09 09 0d 0a 09 57 46 4d 4f 62 6a 2e 67 65 74  ......WFMObj.get
1270: 4c 69 6e 65 20 3d 20 66 75 6e 63 74 69 6f 6e 20  Line = function 
1280: 67 65 74 4c 69 6e 65 28 69 6e 64 65 78 29 7b 0d  getLine(index){.
1290: 0a 09 09 72 65 74 75 72 6e 20 6c 69 6e 65 73 5b  ...return lines[
12a0: 69 6e 64 65 78 5d 2e 73 6c 69 63 65 28 30 29 3b  index].slice(0);
12b0: 20 7d 0d 0a 09 0d 0a 09 57 46 4d 4f 62 6a 2e 67   }......WFMObj.g
12c0: 65 74 56 69 65 77 54 72 61 6e 73 66 6f 72 6d 20  etViewTransform 
12d0: 3d 20 66 75 6e 63 74 69 6f 6e 20 67 65 74 56 69  = function getVi
12e0: 65 77 54 72 61 6e 73 66 6f 72 6d 28 29 7b 0d 0a  ewTransform(){..
12f0: 09 09 72 65 74 75 72 6e 20 76 69 65 77 5f 74 72  ..return view_tr
1300: 61 6e 73 66 6f 72 6d 3b 20 7d 0d 0a 09 0d 0a 09  ansform; }......
1310: 0d 0a 09 0d 0a 09 57 46 4d 4f 62 6a 2e 61 64 64  ......WFMObj.add
1320: 50 6f 69 6e 74 20 3d 20 66 75 6e 63 74 69 6f 6e  Point = function
1330: 20 61 64 64 50 6f 69 6e 74 28 70 74 29 7b 0d 0a   addPoint(pt){..
1340: 09 09 0d 0a 09 09 2f 2f 20 20 43 68 65 63 6b 20  ......//  Check 
1350: 74 79 70 65 20 6f 66 20 70 61 73 73 65 64 20 6f  type of passed o
1360: 62 6a 65 63 74 2e 0d 0a 09 09 69 66 28 41 72 72  bject.....if(Arr
1370: 61 79 2e 69 73 41 72 72 61 79 20 26 26 20 21 41  ay.isArray && !A
1380: 72 72 61 79 2e 69 73 41 72 72 61 79 28 70 74 29  rray.isArray(pt)
1390: 29 7b 20 20 2f 2f 20 6f 6e 6c 79 20 63 68 65 63  ){  // only chec
13a0: 6b 20 69 66 20 41 72 72 61 79 2e 69 73 41 72 72  k if Array.isArr
13b0: 61 79 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 61  ay function is a
13c0: 76 61 69 6c 61 62 6c 65 0d 0a 09 09 09 74 68 72  vailable.....thr
13d0: 6f 77 20 22 70 74 20 6f 62 6a 65 63 74 20 69 73  ow "pt object is
13e0: 20 6e 6f 74 20 61 6e 20 61 72 72 61 79 22 3b 20   not an array"; 
13f0: 7d 0d 0a 09 09 09 0d 0a 09 09 69 66 28 70 74 2e  }.........if(pt.
1400: 6c 65 6e 67 74 68 20 21 3d 20 33 29 7b 0d 0a 09  length != 3){...
1410: 09 09 74 68 72 6f 77 20 22 70 74 20 61 72 72 61  ..throw "pt arra
1420: 79 20 6f 62 6a 65 63 74 20 6e 6f 74 20 6c 65 6e  y object not len
1430: 67 74 68 20 33 22 3b 20 7d 0d 0a 09 09 0d 0a 09  gth 3"; }.......
1440: 09 66 6f 72 28 76 61 72 20 69 20 3d 20 30 3b 20  .for(var i = 0; 
1450: 69 20 3c 20 33 3b 20 2b 2b 69 29 7b 0d 0a 09 09  i < 3; ++i){....
1460: 09 69 66 28 69 73 4e 61 4e 28 70 74 5b 69 5d 29  .if(isNaN(pt[i])
1470: 29 20 74 68 72 6f 77 20 22 70 74 20 6f 62 6a 65  ) throw "pt obje
1480: 63 74 20 61 72 72 61 79 20 64 6f 65 73 20 6e 6f  ct array does no
1490: 74 20 73 74 6f 72 65 20 61 20 6e 75 6d 62 65 72  t store a number
14a0: 20 61 74 20 69 6e 64 65 78 20 22 20 2b 20 69 3b   at index " + i;
14b0: 20 7d 0d 0a 09 09 09 0d 0a 09 09 70 6f 69 6e 74   }.........point
14c0: 73 2e 70 75 73 68 28 70 74 29 3b 0d 0a 09 09 72  s.push(pt);....r
14d0: 65 74 75 72 6e 20 70 6f 69 6e 74 73 2e 6c 65 6e  eturn points.len
14e0: 67 74 68 20 2d 20 31 3b 20 7d 0d 0a 09 0d 0a 09  gth - 1; }......
14f0: 0d 0a 09 0d 0a 09 57 46 4d 4f 62 6a 2e 61 64 64  ......WFMObj.add
1500: 4c 69 6e 65 20 3d 20 66 75 6e 63 74 69 6f 6e 20  Line = function 
1510: 61 64 64 4c 69 6e 65 28 6c 69 6e 65 29 7b 0d 0a  addLine(line){..
1520: 09 09 69 66 28 41 72 72 61 79 2e 69 73 41 72 72  ..if(Array.isArr
1530: 61 79 20 26 26 20 21 41 72 72 61 79 2e 69 73 41  ay && !Array.isA
1540: 72 72 61 79 28 6c 69 6e 65 29 29 7b 0d 0a 09 09  rray(line)){....
1550: 09 74 68 72 6f 77 20 22 6c 69 6e 65 20 6f 62 6a  .throw "line obj
1560: 65 63 74 20 69 73 20 6e 6f 74 20 61 6e 20 61 72  ect is not an ar
1570: 72 61 79 22 20 7d 0d 0a 09 09 0d 0a 09 09 69 66  ray" }........if
1580: 28 6c 69 6e 65 2e 6c 65 6e 67 74 68 20 21 3d 20  (line.length != 
1590: 32 29 7b 0d 0a 09 09 09 74 68 72 6f 77 20 22 6c  2){.....throw "l
15a0: 69 6e 65 20 6f 62 6a 65 63 74 20 6d 75 73 74 20  ine object must 
15b0: 62 65 20 62 65 74 77 65 65 6e 20 32 20 70 6f 69  be between 2 poi
15c0: 6e 74 73 2e 20 20 6c 69 6e 65 20 6f 62 6a 65 63  nts.  line objec
15d0: 74 20 68 61 73 20 6c 65 6e 67 74 68 3a 20 22 20  t has length: " 
15e0: 2b 20 6c 69 6e 65 2e 6c 65 6e 67 74 68 3b 20 7d  + line.length; }
15f0: 0d 0a 09 09 0d 0a 09 09 66 6f 72 28 76 61 72 20  ........for(var 
1600: 69 20 3d 20 30 3b 20 69 20 3c 20 32 3b 20 2b 2b  i = 0; i < 2; ++
1610: 69 29 7b 0d 0a 09 09 09 76 61 72 20 70 74 69 6e  i){.....var ptin
1620: 64 65 78 20 3d 20 6c 69 6e 65 5b 69 5d 3b 0d 0a  dex = line[i];..
1630: 09 09 09 69 66 28 69 73 4e 61 4e 28 70 74 69 6e  ...if(isNaN(ptin
1640: 64 65 78 29 20 7c 7c 20 4d 61 74 68 2e 66 6c 6f  dex) || Math.flo
1650: 6f 72 28 70 74 69 6e 64 65 78 29 20 21 3d 20 70  or(ptindex) != p
1660: 74 69 6e 64 65 78 29 7b 0d 0a 09 09 09 09 74 68  tindex){......th
1670: 72 6f 77 20 22 70 74 20 72 65 66 20 61 74 20 69  row "pt ref at i
1680: 6e 64 65 78 20 22 20 2b 20 69 20 2b 20 22 20 6f  ndex " + i + " o
1690: 66 20 6c 69 6e 65 20 77 61 73 20 6e 6f 74 20 61  f line was not a
16a0: 6e 20 69 6e 74 65 67 65 72 3a 20 22 20 2b 20 70  n integer: " + p
16b0: 74 69 6e 64 65 78 3b 20 7d 0d 0a 09 09 09 0d 0a  tindex; }.......
16c0: 09 09 09 69 66 28 70 74 69 6e 64 65 78 20 3c 20  ...if(ptindex < 
16d0: 30 20 7c 7c 20 70 74 69 6e 64 65 78 20 3e 3d 20  0 || ptindex >= 
16e0: 70 6f 69 6e 74 73 2e 6c 65 6e 67 74 68 29 7b 0d  points.length){.
16f0: 0a 09 09 09 09 74 68 72 6f 77 20 22 70 74 20 72  .....throw "pt r
1700: 65 66 20 61 74 20 69 6e 64 65 78 20 22 20 2b 20  ef at index " + 
1710: 69 20 2b 20 22 20 6f 66 20 6c 69 6e 65 20 77 61  i + " of line wa
1720: 73 20 6e 6f 74 20 69 6e 20 62 6f 75 6e 64 73 3a  s not in bounds:
1730: 20 22 20 2b 20 70 74 69 6e 64 65 78 3b 20 7d 7d   " + ptindex; }}
1740: 0d 0a 09 09 0d 0a 09 09 6c 69 6e 65 73 2e 70 75  ........lines.pu
1750: 73 68 28 6c 69 6e 65 29 3b 0d 0a 09 09 72 65 74  sh(line);....ret
1760: 75 72 6e 20 6c 69 6e 65 73 2e 6c 65 6e 67 74 68  urn lines.length
1770: 20 2d 20 31 3b 20 7d 0d 0a 0d 0a 09 09 0d 0a 09   - 1; }.........
1780: 57 46 4d 4f 62 6a 2e 64 72 61 77 20 3d 20 66 75  WFMObj.draw = fu
1790: 6e 63 74 69 6f 6e 20 64 72 61 77 28 63 61 6e 76  nction draw(canv
17a0: 61 73 29 7b 0d 0a 09 09 76 61 72 20 63 74 78 20  as){....var ctx 
17b0: 3d 20 63 61 6e 76 61 73 2e 67 65 74 43 6f 6e 74  = canvas.getCont
17c0: 65 78 74 28 22 32 64 22 29 3b 0d 0a 09 09 0d 0a  ext("2d");......
17d0: 09 09 76 61 72 20 76 69 65 77 20 3d 20 7b 7d 3b  ..var view = {};
17e0: 0d 0a 09 09 76 69 65 77 2e 74 72 61 6e 73 66 6f  ....view.transfo
17f0: 72 6d 20 3d 20 76 69 65 77 5f 74 72 61 6e 73 66  rm = view_transf
1800: 6f 72 6d 3b 0d 0a 09 09 76 69 65 77 2e 6f 72 69  orm;....view.ori
1810: 67 69 6e 20 3d 20 76 69 65 77 5f 6f 72 69 67 69  gin = view_origi
1820: 6e 3b 0d 0a 09 09 76 69 65 77 2e 7a 6f 6f 6d 5f  n;....view.zoom_
1830: 73 63 61 6c 65 20 3d 20 7a 6f 6f 6d 5f 73 63 61  scale = zoom_sca
1840: 6c 65 3b 0d 0a 09 09 76 69 65 77 2e 7a 6f 6f 6d  le;....view.zoom
1850: 5f 64 69 73 74 20 3d 20 7a 6f 6f 6d 5f 64 69 73  _dist = zoom_dis
1860: 74 3b 0d 0a 09 09 0d 0a 09 09 70 72 6f 6a 65 63  t;........projec
1870: 74 5f 61 6c 6c 28 63 61 6e 76 61 73 2c 20 70 6f  t_all(canvas, po
1880: 69 6e 74 73 2c 20 70 6f 69 6e 74 5f 70 72 6f 6a  ints, point_proj
1890: 65 63 74 69 6f 6e 73 2c 20 76 69 65 77 29 3b 0d  ections, view);.
18a0: 0a 09 09 2f 2f 20 70 72 6f 6a 65 63 74 5f 61 6c  ...// project_al
18b0: 6c 28 29 0d 0a 09 09 0d 0a 09 09 66 6f 72 28 76  l()........for(v
18c0: 61 72 20 69 20 3d 20 30 3b 20 69 20 3c 20 70 6f  ar i = 0; i < po
18d0: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 2e  int_projections.
18e0: 6c 65 6e 67 74 68 3b 20 2b 2b 69 29 7b 0d 0a 09  length; ++i){...
18f0: 09 09 76 61 72 20 70 6f 69 6e 74 5f 70 72 6f 6a  ..var point_proj
1900: 65 63 74 69 6f 6e 20 3d 20 70 6f 69 6e 74 5f 70  ection = point_p
1910: 72 6f 6a 65 63 74 69 6f 6e 73 5b 69 5d 3b 0d 0a  rojections[i];..
1920: 09 09 09 69 66 28 70 6f 69 6e 74 5f 70 72 6f 6a  ...if(point_proj
1930: 65 63 74 69 6f 6e 29 20 63 74 78 2e 66 69 6c 6c  ection) ctx.fill
1940: 52 65 63 74 28 70 6f 69 6e 74 5f 70 72 6f 6a 65  Rect(point_proje
1950: 63 74 69 6f 6e 5b 30 5d 20 2d 20 31 2c 20 70 6f  ction[0] - 1, po
1960: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 5b 31  int_projection[1
1970: 5d 20 2d 20 31 2c 20 32 2c 20 32 29 3b 20 7d 0d  ] - 1, 2, 2); }.
1980: 0a 09 7d 0d 0a 7d 0d 0a 0d 0a 2f 2f 20 20 75 73  ..}..}....//  us
1990: 65 20 63 6f 6e 73 74 72 75 63 74 6f 72 20 61 73  e constructor as
19a0: 20 67 6c 6f 62 61 6c 20 6e 61 6d 65 73 70 61 63   global namespac
19b0: 65 20 6f 62 6a 65 63 74 2e 0d 0a 57 69 72 65 66  e object...Wiref
19c0: 72 61 6d 65 4d 6f 64 65 6c 20 3d 20 5f 5f 57 69  rameModel = __Wi
19d0: 72 65 66 72 61 6d 65 4d 6f 64 65 6c 3b 0d 0a 0d  reframeModel;...
19e0: 0a 0d 0a 7d 29 28 29 3b 0d 0a 0d 0a 2f 2a 0d 0a  ...})();..../*..
19f0: 0d 0a 76 61 72 20 70 6f 69 6e 74 5f 70 72 6f 6a  ..var point_proj
1a00: 65 63 74 69 6f 6e 73 20 3d 20 5b 5d 3b 0d 0a 0d  ections = [];...
1a10: 0a 0d 0a 76 61 72 20 6c 69 6e 65 5f 6d 69 64 70  ...var line_midp
1a20: 6f 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73  oint_projections
1a30: 20 3d 20 5b 5d 3b 0d 0a 0d 0a 0d 0a 76 61 72 20   = [];......var 
1a40: 68 69 67 68 6c 69 67 68 74 5f 6f 62 6a 65 63 74  highlight_object
1a50: 20 3d 20 6e 75 6c 6c 3b 0d 0a 76 61 72 20 6d 6f   = null;..var mo
1a60: 75 73 65 5f 64 72 61 67 67 69 6e 67 20 3d 20 66  use_dragging = f
1a70: 61 6c 73 65 3b 0d 0a 76 61 72 20 6c 61 73 74 5f  alse;..var last_
1a80: 6d 6f 75 73 65 5f 64 6f 77 6e 20 3d 20 6e 75 6c  mouse_down = nul
1a90: 6c 3b 0d 0a 76 61 72 20 6d 6f 75 73 65 5f 6c 6f  l;..var mouse_lo
1aa0: 63 20 3d 20 6e 75 6c 6c 3b 0d 0a 0d 0a 0d 0a 0d  c = null;.......
1ab0: 0a 76 61 72 20 7a 6f 6f 6d 5f 73 63 61 6c 65 20  .var zoom_scale 
1ac0: 3d 20 32 2e 36 36 37 3b 20 20 2f 2f 20 73 63 61  = 2.667;  // sca
1ad0: 6c 61 72 20 7a 6f 6f 6d 20 70 72 6f 70 65 72 74  lar zoom propert
1ae0: 79 2e 0d 0a 76 61 72 20 7a 6f 6f 6d 5f 64 69 73  y...var zoom_dis
1af0: 74 20 3d 20 31 3b 0d 0a 0d 0a 0d 0a 20 20 20 20  t = 1;......    
1b00: 0d 0a 66 75 6e 63 74 69 6f 6e 20 6d 6f 76 65 43  ..function moveC
1b10: 61 6d 65 72 61 28 6f 66 66 73 65 74 2c 20 63 61  amera(offset, ca
1b20: 6d 65 72 61 63 65 6e 74 72 69 63 29 7b 0d 0a 20  meracentric){.. 
1b30: 20 20 20 69 66 28 63 61 6d 65 72 61 63 65 6e 74     if(cameracent
1b40: 72 69 63 29 20 6f 66 66 73 65 74 20 3d 20 6d 61  ric) offset = ma
1b50: 74 72 69 78 5f 6d 75 6c 74 28 76 69 65 77 5f 74  trix_mult(view_t
1b60: 72 61 6e 73 66 6f 72 6d 2c 20 5b 6f 66 66 73 65  ransform, [offse
1b70: 74 5d 29 5b 30 5d 3b 0d 0a 20 20 20 20 2f 2f 61  t])[0];..    //a
1b80: 6c 65 72 74 28 22 6f 66 66 73 65 74 3a 20 22 20  lert("offset: " 
1b90: 2b 20 6f 66 66 73 65 74 29 3b 0d 0a 20 20 20 20  + offset);..    
1ba0: 76 65 63 74 6f 72 5f 61 64 64 28 6f 72 69 67 69  vector_add(origi
1bb0: 6e 2c 20 6f 66 66 73 65 74 2c 20 6f 72 69 67 69  n, offset, origi
1bc0: 6e 29 3b 20 7d 0d 0a 09 0d 0a 09 0d 0a 09 0d 0a  n); }...........
1bd0: 09 0d 0a 20 20 20 0d 0a 0d 0a 20 20 20 0d 0a 0d  ...   ....   ...
1be0: 0a 20 20 20 0d 0a 2f 2f 20 20 72 65 6d 6f 76 65  .   ..//  remove
1bf0: 73 20 64 65 6c 65 74 65 64 20 70 6f 69 6e 74 73  s deleted points
1c00: 20 61 6e 64 20 6c 69 6e 65 73 0d 0a 2f 2f 20 20   and lines..//  
1c10: 77 6f 72 6b 73 20 77 69 74 68 20 67 6c 6f 62 61  works with globa
1c20: 6c 20 6f 62 6a 65 63 74 73 2e 0d 0a 0d 0a 66 75  l objects.....fu
1c30: 6e 63 74 69 6f 6e 20 63 6c 65 61 6e 75 70 44 65  nction cleanupDe
1c40: 6c 65 74 65 64 50 6f 69 6e 74 73 28 29 7b 0d 0a  letedPoints(){..
1c50: 20 20 20 20 76 61 72 20 6e 65 77 70 6f 69 6e 74      var newpoint
1c60: 73 20 3d 20 5b 5d 3b 0d 0a 20 20 20 20 76 61 72  s = [];..    var
1c70: 20 6e 65 77 6c 69 6e 65 73 20 3d 20 5b 5d 3b 0d   newlines = [];.
1c80: 0a 20 20 20 20 76 61 72 20 70 6f 69 6e 74 6d 61  .    var pointma
1c90: 70 20 3d 20 7b 7d 3b 0d 0a 20 20 20 20 0d 0a 20  p = {};..    .. 
1ca0: 20 20 20 76 61 72 20 6a 20 3d 20 30 3b 0d 0a 20     var j = 0;.. 
1cb0: 20 20 20 0d 0a 20 20 20 20 66 6f 72 28 76 61 72     ..    for(var
1cc0: 20 69 20 3d 20 30 3b 20 69 20 3c 20 70 6f 69 6e   i = 0; i < poin
1cd0: 74 73 2e 6c 65 6e 67 74 68 3b 20 2b 2b 69 29 7b  ts.length; ++i){
1ce0: 0d 0a 20 20 20 20 20 20 20 0d 0a 20 20 20 20 20  ..       ..     
1cf0: 20 20 69 66 28 70 6f 69 6e 74 73 5b 69 5d 29 7b    if(points[i]){
1d00: 0d 0a 20 20 20 20 20 20 20 20 20 20 20 6e 65 77  ..           new
1d10: 70 6f 69 6e 74 73 2e 70 75 73 68 28 70 6f 69 6e  points.push(poin
1d20: 74 73 5b 69 5d 29 3b 0d 0a 20 20 20 20 20 20 20  ts[i]);..       
1d30: 20 20 20 20 70 6f 69 6e 74 6d 61 70 5b 69 5d 20      pointmap[i] 
1d40: 3d 20 6a 3b 0d 0a 20 20 20 20 20 20 20 20 20 20  = j;..          
1d50: 20 2b 2b 6a 3b 20 7d 0d 0a 20 20 20 20 20 20 20   ++j; }..       
1d60: 20 20 20 20 0d 0a 20 20 20 20 20 20 20 65 6c 73      ..       els
1d70: 65 7b 0d 0a 20 20 20 20 20 20 20 20 20 20 20 70  e{..           p
1d80: 6f 69 6e 74 6d 61 70 5b 69 5d 20 3d 20 2d 31 3b  ointmap[i] = -1;
1d90: 20 7d 7d 0d 0a 20 20 20 20 0d 0a 20 20 20 20 0d   }}..    ..    .
1da0: 0a 20 20 20 20 66 6f 72 28 76 61 72 20 69 20 3d  .    for(var i =
1db0: 20 30 3b 20 69 20 3c 20 6c 69 6e 65 73 2e 6c 65   0; i < lines.le
1dc0: 6e 67 74 68 3b 20 2b 2b 69 29 7b 0d 0a 20 20 20  ngth; ++i){..   
1dd0: 20 20 20 20 20 69 66 28 21 6c 69 6e 65 73 5b 69       if(!lines[i
1de0: 5d 29 20 63 6f 6e 74 69 6e 75 65 3b 0d 0a 20 20  ]) continue;..  
1df0: 20 20 20 20 20 20 76 61 72 20 61 20 3d 20 6c 69        var a = li
1e00: 6e 65 73 5b 69 5d 5b 30 5d 3b 0d 0a 20 20 20 20  nes[i][0];..    
1e10: 20 20 20 20 76 61 72 20 62 20 3d 20 6c 69 6e 65      var b = line
1e20: 73 5b 69 5d 5b 31 5d 3b 0d 0a 20 20 20 20 20 20  s[i][1];..      
1e30: 20 20 0d 0a 20 20 20 20 20 20 20 20 69 66 28 70    ..        if(p
1e40: 6f 69 6e 74 6d 61 70 5b 61 5d 20 21 3d 20 2d 31  ointmap[a] != -1
1e50: 20 26 26 20 70 6f 69 6e 74 6d 61 70 5b 62 5d 20   && pointmap[b] 
1e60: 21 3d 20 2d 31 29 7b 0d 0a 20 20 20 20 20 20 20  != -1){..       
1e70: 20 20 20 20 20 6e 65 77 6c 69 6e 65 73 2e 70 75       newlines.pu
1e80: 73 68 28 5b 20 70 6f 69 6e 74 6d 61 70 5b 61 5d  sh([ pointmap[a]
1e90: 2c 20 70 6f 69 6e 74 6d 61 70 5b 62 5d 20 5d 29  , pointmap[b] ])
1ea0: 3b 20 7d 7d 0d 0a 20 20 20 20 0d 0a 20 20 20 20  ; }}..    ..    
1eb0: 70 6f 69 6e 74 73 20 3d 20 6e 65 77 70 6f 69 6e  points = newpoin
1ec0: 74 73 3b 0d 0a 20 20 20 20 6c 69 6e 65 73 20 3d  ts;..    lines =
1ed0: 20 6e 65 77 6c 69 6e 65 73 3b 20 7d 0d 0a 20 20   newlines; }..  
1ee0: 20 20 20 20 20 20 0d 0a 0d 0a 66 75 6e 63 74 69        ....functi
1ef0: 6f 6e 20 61 64 64 50 6f 69 6e 74 28 70 74 29 7b  on addPoint(pt){
1f00: 0d 0a 20 20 20 20 70 6f 69 6e 74 73 2e 70 75 73  ..    points.pus
1f10: 68 28 70 74 2e 73 6c 69 63 65 28 30 29 29 3b 0d  h(pt.slice(0));.
1f20: 0a 20 20 20 20 76 61 72 20 69 6e 64 65 78 20 3d  .    var index =
1f30: 20 70 6f 69 6e 74 73 2e 6c 65 6e 67 74 68 20 2d   points.length -
1f40: 20 31 3b 0d 0a 20 20 20 20 73 6f 6c 6f 5f 70 6f   1;..    solo_po
1f50: 69 6e 74 73 5b 69 6e 64 65 78 5d 20 3d 20 74 72  ints[index] = tr
1f60: 75 65 3b 0d 0a 20 20 20 20 72 65 74 75 72 6e 20  ue;..    return 
1f70: 69 6e 64 65 78 3b 20 7d 0d 0a 20 20 20 20 0d 0a  index; }..    ..
1f80: 20 20 20 20 0d 0a 66 75 6e 63 74 69 6f 6e 20 61      ..function a
1f90: 64 64 4c 69 6e 65 28 70 74 30 2c 20 70 74 31 29  ddLine(pt0, pt1)
1fa0: 7b 0d 0a 20 20 20 20 64 65 6c 65 74 65 20 73 6f  {..    delete so
1fb0: 6c 6f 5f 70 6f 69 6e 74 73 5b 70 74 30 5d 3b 0d  lo_points[pt0];.
1fc0: 0a 20 20 20 20 64 65 6c 65 74 65 20 73 6f 6c 6f  .    delete solo
1fd0: 5f 70 6f 69 6e 74 73 5b 70 74 31 5d 3b 0d 0a 20  _points[pt1];.. 
1fe0: 20 20 20 6c 69 6e 65 73 2e 70 75 73 68 28 5b 70     lines.push([p
1ff0: 74 30 2c 20 70 74 31 5d 29 3b 0d 0a 20 20 20 20  t0, pt1]);..    
2000: 72 65 74 75 72 6e 20 6c 69 6e 65 73 2e 6c 65 6e  return lines.len
2010: 67 74 68 20 2d 20 31 3b 20 7d 20 20 20 20 0d 0a  gth - 1; }    ..
2020: 0d 0a 0d 0a 0d 0a 66 75 6e 63 74 69 6f 6e 20 64  ......function d
2030: 72 61 77 28 63 61 6e 76 61 73 29 7b 0d 0a 20 20  raw(canvas){..  
2040: 20 20 76 61 72 20 63 74 78 20 3d 20 63 61 6e 76    var ctx = canv
2050: 61 73 2e 67 65 74 43 6f 6e 74 65 78 74 28 27 32  as.getContext('2
2060: 64 27 29 3b 0d 0a 20 20 20 20 76 61 72 20 77 20  d');..    var w 
2070: 3d 20 63 61 6e 76 61 73 2e 77 69 64 74 68 3b 0d  = canvas.width;.
2080: 0a 20 20 20 20 76 61 72 20 68 20 3d 20 63 61 6e  .    var h = can
2090: 76 61 73 2e 68 65 69 67 68 74 3b 0d 0a 20 20 20  vas.height;..   
20a0: 20 0d 0a 20 20 20 20 2f 2f 20 63 74 78 2e 66 69   ..    // ctx.fi
20b0: 6c 6c 53 74 79 6c 65 20 3d 20 22 72 67 62 61 28  llStyle = "rgba(
20c0: 31 30 30 2c 20 31 30 30 2c 20 31 30 30 2c 20 2e  100, 100, 100, .
20d0: 30 35 29 22 3b 0d 0a 20 20 20 20 0d 0a 20 20 20  05)";..    ..   
20e0: 20 0d 0a 20 20 20 20 63 74 78 2e 62 65 67 69 6e   ..    ctx.begin
20f0: 50 61 74 68 28 29 3b 0d 0a 20 20 20 20 0d 0a 20  Path();..    .. 
2100: 20 20 20 66 6f 72 28 76 61 72 20 69 20 3d 20 30     for(var i = 0
2110: 3b 20 69 20 3c 20 6c 69 6e 65 73 2e 6c 65 6e 67  ; i < lines.leng
2120: 74 68 3b 20 2b 2b 69 29 7b 0d 0a 20 20 20 20 20  th; ++i){..     
2130: 20 20 20 76 61 72 20 6c 69 6e 65 20 3d 20 6c 69     var line = li
2140: 6e 65 73 5b 69 5d 3b 0d 0a 20 20 20 20 20 20 20  nes[i];..       
2150: 20 69 66 28 21 6c 69 6e 65 29 20 63 6f 6e 74 69   if(!line) conti
2160: 6e 75 65 3b 0d 0a 20 20 20 20 20 20 20 20 2f 2f  nue;..        //
2170: 64 72 61 77 20 6c 69 6e 65 0d 0a 20 20 20 20 20  draw line..     
2180: 20 20 20 0d 0a 20 20 20 20 20 20 20 20 76 61 72     ..        var
2190: 20 70 74 30 20 3d 20 70 6f 69 6e 74 73 5b 6c 69   pt0 = points[li
21a0: 6e 65 5b 30 5d 5d 3b 0d 0a 20 20 20 20 20 20 20  ne[0]];..       
21b0: 20 76 61 72 20 70 74 31 20 3d 20 70 6f 69 6e 74   var pt1 = point
21c0: 73 5b 6c 69 6e 65 5b 31 5d 5d 3b 0d 0a 20 20 20  s[line[1]];..   
21d0: 20 20 20 20 20 20 20 20 20 0d 0a 20 20 20 20 20           ..     
21e0: 20 20 20 76 61 72 20 5f 70 74 30 20 3d 20 70 6f     var _pt0 = po
21f0: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b  int_projections[
2200: 6c 69 6e 65 5b 30 5d 5d 3b 0d 0a 20 20 20 20 20  line[0]];..     
2210: 20 20 20 76 61 72 20 5f 70 74 31 20 3d 20 70 6f     var _pt1 = po
2220: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b  int_projections[
2230: 6c 69 6e 65 5b 31 5d 5d 3b 0d 0a 20 20 20 20 20  line[1]];..     
2240: 20 20 20 0d 0a 20 20 20 20 20 20 20 20 2f 2f 20     ..        // 
2250: 20 66 69 6e 69 73 68 20 74 68 65 20 6c 69 6e 65   finish the line
2260: 20 65 76 65 6e 20 69 66 20 6f 6e 65 20 70 6f 69   even if one poi
2270: 6e 74 20 69 73 20 6f 6e 20 77 72 6f 6e 67 20 73  nt is on wrong s
2280: 69 64 65 20 6f 66 20 76 69 65 77 65 72 2e 0d 0a  ide of viewer...
2290: 20 20 20 20 20 20 20 20 69 66 28 21 5f 70 74 30          if(!_pt0
22a0: 20 26 26 20 5f 70 74 31 29 7b 0d 0a 20 20 20 20   && _pt1){..    
22b0: 20 20 20 20 20 20 20 20 5f 70 74 30 20 3d 20 70          _pt0 = p
22c0: 72 6f 6a 65 63 74 28 63 61 6e 76 61 73 2c 20 70  roject(canvas, p
22d0: 74 30 2c 20 76 69 65 77 5f 74 72 61 6e 73 66 6f  t0, view_transfo
22e0: 72 6d 2c 20 6f 72 69 67 69 6e 2c 20 70 74 31 29  rm, origin, pt1)
22f0: 3b 20 7d 0d 0a 20 20 20 20 20 20 20 20 65 6c 73  ; }..        els
2300: 65 20 69 66 28 5f 70 74 30 20 26 26 20 21 5f 70  e if(_pt0 && !_p
2310: 74 31 29 7b 0d 0a 20 20 20 20 20 20 20 20 20 20  t1){..          
2320: 20 20 5f 70 74 31 20 3d 20 70 72 6f 6a 65 63 74    _pt1 = project
2330: 28 63 61 6e 76 61 73 2c 20 70 74 31 2c 20 76 69  (canvas, pt1, vi
2340: 65 77 5f 74 72 61 6e 73 66 6f 72 6d 2c 20 6f 72  ew_transform, or
2350: 69 67 69 6e 2c 20 70 74 30 29 3b 20 7d 0d 0a 20  igin, pt0); }.. 
2360: 20 20 20 20 20 20 20 20 20 20 20 0d 0a 20 20 20             ..   
2370: 20 20 20 20 20 69 66 28 21 5f 70 74 30 20 7c 7c       if(!_pt0 ||
2380: 20 21 5f 70 74 31 29 20 63 6f 6e 74 69 6e 75 65   !_pt1) continue
2390: 3b 0d 0a 20 20 20 20 20 20 20 20 0d 0a 20 20 20  ;..        ..   
23a0: 20 20 20 20 20 76 61 72 20 78 30 20 3d 20 5f 70       var x0 = _p
23b0: 74 30 5b 30 5d 3b 0d 0a 20 20 20 20 20 20 20 20  t0[0];..        
23c0: 76 61 72 20 79 30 20 3d 20 5f 70 74 30 5b 31 5d  var y0 = _pt0[1]
23d0: 3b 0d 0a 0d 0a 20 20 20 20 20 20 20 20 76 61 72  ;....        var
23e0: 20 78 31 20 3d 20 5f 70 74 31 5b 30 5d 3b 0d 0a   x1 = _pt1[0];..
23f0: 20 20 20 20 20 20 20 20 76 61 72 20 79 31 20 3d          var y1 =
2400: 20 5f 70 74 31 5b 31 5d 3b 0d 0a 20 20 20 20 20   _pt1[1];..     
2410: 20 20 20 0d 0a 20 20 20 20 20 20 20 20 63 74 78     ..        ctx
2420: 2e 6d 6f 76 65 54 6f 28 78 30 2c 20 79 30 29 3b  .moveTo(x0, y0);
2430: 0d 0a 20 20 20 20 20 20 20 20 63 74 78 2e 6c 69  ..        ctx.li
2440: 6e 65 54 6f 28 78 31 2c 20 79 31 29 3b 20 7d 0d  neTo(x1, y1); }.
2450: 0a 20 20 20 20 0d 0a 20 20 20 20 63 74 78 2e 63  .    ..    ctx.c
2460: 6c 65 61 72 52 65 63 74 28 30 2c 20 30 2c 20 77  learRect(0, 0, w
2470: 2c 20 68 29 3b 0d 0a 09 0d 0a 20 20 20 20 0d 0a  , h);.....    ..
2480: 09 63 74 78 2e 73 74 72 6f 6b 65 53 74 79 6c 65  .ctx.strokeStyle
2490: 20 3d 20 22 72 67 62 61 28 30 2c 20 30 2c 20 30   = "rgba(0, 0, 0
24a0: 2c 20 30 2e 39 29 22 3b 0d 0a 20 20 20 20 63 74  , 0.9)";..    ct
24b0: 78 2e 73 74 72 6f 6b 65 28 29 3b 0d 0a 20 20 20  x.stroke();..   
24c0: 20 0d 0a 09 63 74 78 2e 66 69 6c 6c 53 74 79 6c   ...ctx.fillStyl
24d0: 65 20 3d 20 22 72 67 62 61 28 30 2c 20 30 2c 20  e = "rgba(0, 0, 
24e0: 30 2c 20 30 2e 39 29 22 3b 0d 0a 09 0d 0a 20 20  0, 0.9)";.....  
24f0: 20 20 66 6f 72 28 76 61 72 20 6b 20 69 6e 20 73    for(var k in s
2500: 6f 6c 6f 5f 70 6f 69 6e 74 73 29 7b 0d 0a 20 20  olo_points){..  
2510: 20 20 20 20 20 76 61 72 20 70 74 20 3d 20 70 6f       var pt = po
2520: 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b  int_projections[
2530: 6b 5d 3b 0d 0a 20 20 20 20 20 20 20 69 66 28 70  k];..       if(p
2540: 74 29 20 63 74 78 2e 66 69 6c 6c 52 65 63 74 28  t) ctx.fillRect(
2550: 70 74 5b 30 5d 20 2d 20 32 2c 20 70 74 5b 31 5d  pt[0] - 2, pt[1]
2560: 20 2d 20 32 2c 20 34 2c 20 34 29 3b 20 7d 0d 0a   - 2, 4, 4); }..
2570: 20 20 20 20 20 20 20 20 0d 0a 09 2f 2f 0d 0a 09          ...//...
2580: 2f 2f 20 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e  //  The followin
2590: 67 20 64 72 61 77 69 6e 67 20 6f 66 20 61 78 65  g drawing of axe
25a0: 73 20 69 73 20 74 6f 20 68 65 6c 70 20 70 72 6f  s is to help pro
25b0: 76 69 64 65 20 61 6e 20 70 65 72 73 70 65 63 74  vide an perspect
25c0: 69 76 65 0d 0a 09 2f 2f 20 20 54 68 65 20 6e 75  ive...//  The nu
25d0: 61 6e 63 65 73 20 6f 66 20 74 68 69 73 20 64 72  ances of this dr
25e0: 61 77 20 62 65 68 61 76 69 6f 72 20 61 72 65 20  aw behavior are 
25f0: 63 72 65 61 74 65 64 20 74 6f 20 70 72 6f 76 69  created to provi
2600: 64 65 20 76 69 73 75 61 6c 20 63 75 65 73 20 66  de visual cues f
2610: 6f 72 20 69 6e 74 65 72 70 72 65 74 69 6e 67 20  or interpreting 
2620: 70 65 72 73 70 65 63 74 69 76 65 20 61 6e 64 20  perspective and 
2630: 64 65 70 74 68 2e 0d 0a 09 2f 2f 20 20 0d 0a 09  depth....//  ...
2640: 2f 2f 20 20 42 65 63 61 75 73 65 20 77 65 20 75  //  Because we u
2650: 73 65 20 61 20 32 64 20 63 61 6e 76 61 73 20 6c  se a 2d canvas l
2660: 69 62 72 61 72 79 20 66 6f 72 20 74 68 65 20 64  ibrary for the d
2670: 72 61 77 69 6e 67 20 74 68 65 20 72 65 73 74 20  rawing the rest 
2680: 6f 66 20 74 68 65 20 70 6f 69 6e 74 73 2f 73 68  of the points/sh
2690: 61 70 65 73 20 61 66 74 65 72 20 70 72 6f 6a 65  apes after proje
26a0: 63 74 69 6f 6e 2c 20 74 68 65 73 65 20 76 69 73  ction, these vis
26b0: 75 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  ual information 
26c0: 6e 75 61 6e 63 65 73 20 61 72 65 20 69 6d 70 6f  nuances are impo
26d0: 72 74 61 6e 74 2e 0d 0a 09 2f 2f 0d 0a 0d 0a 09  rtant....//.....
26e0: 2f 2f 20 61 78 69 73 20 6c 69 6e 65 73 20 61 6e  // axis lines an
26f0: 64 20 64 6f 74 73 0d 0a 09 0d 0a 20 20 20 20 76  d dots.....    v
2700: 61 72 20 66 61 78 69 73 5f 70 74 20 3d 20 70 72  ar faxis_pt = pr
2710: 6f 6a 65 63 74 28 63 61 6e 76 61 73 2c 20 76 65  oject(canvas, ve
2720: 63 74 6f 72 5f 61 64 64 28 6f 72 69 67 69 6e 2c  ctor_add(origin,
2730: 20 5b 30 2c 20 30 2c 20 46 4f 52 57 41 52 44 5f   [0, 0, FORWARD_
2740: 41 58 49 53 5f 4c 45 4e 5d 29 2c 20 76 69 65 77  AXIS_LEN]), view
2750: 5f 74 72 61 6e 73 66 6f 72 6d 2c 20 6f 72 69 67  _transform, orig
2760: 69 6e 29 3b 0d 0a 09 76 61 72 20 76 61 78 69 73  in);...var vaxis
2770: 5f 70 74 20 3d 20 70 72 6f 6a 65 63 74 28 63 61  _pt = project(ca
2780: 6e 76 61 73 2c 20 76 65 63 74 6f 72 5f 61 64 64  nvas, vector_add
2790: 28 6f 72 69 67 69 6e 2c 20 5b 30 2c 20 2d 56 45  (origin, [0, -VE
27a0: 52 54 49 43 41 4c 5f 41 58 49 53 5f 4c 45 4e 2c  RTICAL_AXIS_LEN,
27b0: 20 30 5d 29 2c 20 76 69 65 77 5f 74 72 61 6e 73   0]), view_trans
27c0: 66 6f 72 6d 2c 20 6f 72 69 67 69 6e 29 3b 0d 0a  form, origin);..
27d0: 09 0d 0a 09 63 74 78 2e 66 69 6c 6c 53 74 79 6c  ....ctx.fillStyl
27e0: 65 20 3d 20 41 58 49 53 5f 50 4f 49 4e 54 5f 43  e = AXIS_POINT_C
27f0: 4f 4c 4f 52 3b 0d 0a 09 0d 0a 09 76 61 72 20 66  OLOR;......var f
2800: 64 6f 74 20 3d 20 76 65 63 74 6f 72 5f 64 6f 74  dot = vector_dot
2810: 28 76 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b  (view_transform[
2820: 32 5d 2c 20 5b 30 2c 20 30 2c 20 31 5d 29 3b 0d  2], [0, 0, 1]);.
2830: 0a 09 0d 0a 09 76 61 72 20 61 20 3d 20 4d 49 4e  .....var a = MIN
2840: 5f 41 58 49 53 5f 50 4f 49 4e 54 5f 52 41 44 49  _AXIS_POINT_RADI
2850: 55 53 3b 20 20 2f 2f 72 61 6e 64 6f 6d 20 6c 65  US;  //random le
2860: 74 74 65 72 73 20 66 6f 72 20 69 6e 74 65 72 6d  tters for interm
2870: 65 64 69 61 74 65 20 63 6f 6d 70 75 74 61 74 69  ediate computati
2880: 6f 6e 73 0d 0a 09 76 61 72 20 62 20 3d 20 4d 41  ons...var b = MA
2890: 58 5f 41 58 49 53 5f 50 4f 49 4e 54 5f 52 41 44  X_AXIS_POINT_RAD
28a0: 49 55 53 3b 0d 0a 09 76 61 72 20 63 20 3d 20 28  IUS;...var c = (
28b0: 61 2b 62 29 2f 32 3b 0d 0a 09 76 61 72 20 64 20  a+b)/2;...var d 
28c0: 3d 20 28 62 2d 61 29 2f 32 3b 0d 0a 09 0d 0a 09  = (b-a)/2;......
28d0: 76 61 72 20 66 72 20 3d 20 63 20 2d 20 64 20 2a  var fr = c - d *
28e0: 20 66 64 6f 74 3b 0d 0a 09 76 61 72 20 76 64 6f   fdot;...var vdo
28f0: 74 20 3d 20 76 65 63 74 6f 72 5f 64 6f 74 28 76  t = vector_dot(v
2900: 69 65 77 5f 74 72 61 6e 73 66 6f 72 6d 5b 32 5d  iew_transform[2]
2910: 2c 20 5b 30 2c 20 2d 31 2c 20 30 5d 29 3b 0d 0a  , [0, -1, 0]);..
2920: 09 76 61 72 20 76 72 20 3d 20 63 20 2d 20 64 20  .var vr = c - d 
2930: 2a 20 76 64 6f 74 3b 0d 0a 09 0d 0a 09 63 74 78  * vdot;......ctx
2940: 2e 6c 69 6e 65 57 69 64 74 68 20 3d 20 41 58 49  .lineWidth = AXI
2950: 53 5f 4c 49 4e 45 5f 57 49 44 54 48 3b 0d 0a 09  S_LINE_WIDTH;...
2960: 63 74 78 2e 62 65 67 69 6e 50 61 74 68 28 29 3b  ctx.beginPath();
2970: 0d 0a 09 0d 0a 09 69 66 28 66 64 6f 74 20 3e 3d  ......if(fdot >=
2980: 30 20 26 26 20 66 61 78 69 73 5f 70 74 29 7b 20  0 && faxis_pt){ 
2990: 2f 2f 20 6f 63 63 6c 75 64 65 20 74 68 69 73 20  // occlude this 
29a0: 61 78 69 73 2c 20 64 72 61 77 20 66 69 72 73 74  axis, draw first
29b0: 0d 0a 09 09 63 74 78 2e 6d 6f 76 65 54 6f 28 77  ....ctx.moveTo(w
29c0: 2f 32 2c 20 68 2f 32 29 3b 0d 0a 09 09 63 74 78  /2, h/2);....ctx
29d0: 2e 6c 69 6e 65 54 6f 28 66 61 78 69 73 5f 70 74  .lineTo(faxis_pt
29e0: 5b 30 5d 2c 20 66 61 78 69 73 5f 70 74 5b 31 5d  [0], faxis_pt[1]
29f0: 29 3b 09 0d 0a 09 09 63 74 78 2e 66 69 6c 6c 52  );.....ctx.fillR
2a00: 65 63 74 28 66 61 78 69 73 5f 70 74 5b 30 5d 20  ect(faxis_pt[0] 
2a10: 2d 20 66 72 2c 20 66 61 78 69 73 5f 70 74 5b 31  - fr, faxis_pt[1
2a20: 5d 20 2d 20 66 72 2c 20 32 2a 66 72 2c 20 32 2a  ] - fr, 2*fr, 2*
2a30: 66 72 29 3b 20 7d 0d 0a 09 09 0d 0a 09 69 66 28  fr); }.......if(
2a40: 76 64 6f 74 20 3e 3d 30 20 26 26 20 76 61 78 69  vdot >=0 && vaxi
2a50: 73 5f 70 74 29 7b 20 2f 2f 20 6f 63 63 6c 75 64  s_pt){ // occlud
2a60: 65 20 74 68 69 73 20 61 78 69 73 2c 20 64 72 61  e this axis, dra
2a70: 77 20 66 69 72 73 74 0d 0a 09 09 63 74 78 2e 6d  w first....ctx.m
2a80: 6f 76 65 54 6f 28 77 2f 32 2c 20 68 2f 32 29 3b  oveTo(w/2, h/2);
2a90: 0d 0a 09 09 63 74 78 2e 6c 69 6e 65 54 6f 28 76  ....ctx.lineTo(v
2aa0: 61 78 69 73 5f 70 74 5b 30 5d 2c 20 76 61 78 69  axis_pt[0], vaxi
2ab0: 73 5f 70 74 5b 31 5d 29 3b 09 0d 0a 09 09 63 74  s_pt[1]);.....ct
2ac0: 78 2e 66 69 6c 6c 52 65 63 74 28 76 61 78 69 73  x.fillRect(vaxis
2ad0: 5f 70 74 5b 30 5d 20 2d 20 76 72 2c 20 76 61 78  _pt[0] - vr, vax
2ae0: 69 73 5f 70 74 5b 31 5d 20 2d 20 76 72 2c 20 32  is_pt[1] - vr, 2
2af0: 2a 76 72 2c 20 32 2a 76 72 29 3b 20 7d 0d 0a 09  *vr, 2*vr); }...
2b00: 0d 0a 09 63 74 78 2e 73 74 72 6f 6b 65 28 29 3b  ...ctx.stroke();
2b10: 0d 0a 09 0d 0a 09 09 0d 0a 09 2f 2f 20 64 72 61  ..........// dra
2b20: 77 20 63 65 6e 74 65 72 20 72 65 64 20 73 71 75  w center red squ
2b30: 61 72 65 0d 0a 09 63 74 78 2e 66 69 6c 6c 53 74  are...ctx.fillSt
2b40: 79 6c 65 20 3d 20 43 45 4e 54 45 52 5f 50 4f 49  yle = CENTER_POI
2b50: 4e 54 5f 43 4f 4c 4f 52 3b 0d 0a 09 76 61 72 20  NT_COLOR;...var 
2b60: 63 72 20 3d 20 43 45 4e 54 45 52 5f 50 4f 49 4e  cr = CENTER_POIN
2b70: 54 5f 52 41 44 49 55 53 3b 0d 0a 09 63 74 78 2e  T_RADIUS;...ctx.
2b80: 66 69 6c 6c 52 65 63 74 28 77 2f 32 20 2d 20 63  fillRect(w/2 - c
2b90: 72 2c 20 68 2f 32 20 2d 20 63 72 2c 20 32 2a 63  r, h/2 - cr, 2*c
2ba0: 72 2c 20 32 2a 63 72 29 3b 0d 0a 09 09 0d 0a 09  r, 2*cr);.......
2bb0: 63 74 78 2e 66 69 6c 6c 53 74 79 6c 65 20 3d 20  ctx.fillStyle = 
2bc0: 41 58 49 53 5f 50 4f 49 4e 54 5f 43 4f 4c 4f 52  AXIS_POINT_COLOR
2bd0: 3b 0d 0a 09 0d 0a 09 0d 0a 09 69 66 28 66 64 6f  ;.........if(fdo
2be0: 74 20 3c 20 30 20 26 26 20 66 61 78 69 73 5f 70  t < 0 && faxis_p
2bf0: 74 29 7b 0d 0a 09 09 63 74 78 2e 62 65 67 69 6e  t){....ctx.begin
2c00: 50 61 74 68 28 29 3b 0d 0a 09 09 63 74 78 2e 6d  Path();....ctx.m
2c10: 6f 76 65 54 6f 28 77 2f 32 2c 20 68 2f 32 29 3b  oveTo(w/2, h/2);
2c20: 0d 0a 09 09 63 74 78 2e 6c 69 6e 65 54 6f 28 66  ....ctx.lineTo(f
2c30: 61 78 69 73 5f 70 74 5b 30 5d 2c 20 66 61 78 69  axis_pt[0], faxi
2c40: 73 5f 70 74 5b 31 5d 29 3b 0d 0a 09 09 63 74 78  s_pt[1]);....ctx
2c50: 2e 73 74 72 6f 6b 65 28 29 3b 0d 0a 09 09 63 74  .stroke();....ct
2c60: 78 2e 66 69 6c 6c 52 65 63 74 28 66 61 78 69 73  x.fillRect(faxis
2c70: 5f 70 74 5b 30 5d 20 2d 20 66 72 2c 20 66 61 78  _pt[0] - fr, fax
2c80: 69 73 5f 70 74 5b 31 5d 20 2d 20 66 72 2c 20 32  is_pt[1] - fr, 2
2c90: 2a 66 72 2c 20 32 2a 66 72 29 3b 20 7d 0d 0a 09  *fr, 2*fr); }...
2ca0: 09 0d 0a 09 69 66 28 76 64 6f 74 20 3c 20 30 20  ....if(vdot < 0 
2cb0: 26 26 20 76 61 78 69 73 5f 70 74 29 7b 0d 0a 09  && vaxis_pt){...
2cc0: 09 63 74 78 2e 62 65 67 69 6e 50 61 74 68 28 29  .ctx.beginPath()
2cd0: 3b 0d 0a 09 09 63 74 78 2e 6d 6f 76 65 54 6f 28  ;....ctx.moveTo(
2ce0: 77 2f 32 2c 20 68 2f 32 29 3b 0d 0a 09 09 63 74  w/2, h/2);....ct
2cf0: 78 2e 6c 69 6e 65 54 6f 28 76 61 78 69 73 5f 70  x.lineTo(vaxis_p
2d00: 74 5b 30 5d 2c 20 76 61 78 69 73 5f 70 74 5b 31  t[0], vaxis_pt[1
2d10: 5d 29 3b 0d 0a 09 09 63 74 78 2e 73 74 72 6f 6b  ]);....ctx.strok
2d20: 65 28 29 3b 0d 0a 09 09 63 74 78 2e 66 69 6c 6c  e();....ctx.fill
2d30: 52 65 63 74 28 76 61 78 69 73 5f 70 74 5b 30 5d  Rect(vaxis_pt[0]
2d40: 20 2d 20 76 72 2c 20 76 61 78 69 73 5f 70 74 5b   - vr, vaxis_pt[
2d50: 31 5d 20 2d 20 76 72 2c 20 32 2a 76 72 2c 20 32  1] - vr, 2*vr, 2
2d60: 2a 76 72 29 3b 20 7d 0d 0a 09 0d 0a 0d 0a 09 2f  *vr); }......../
2d70: 2f 20 72 65 73 65 74 20 6c 69 6e 65 20 77 69 64  / reset line wid
2d80: 74 68 0d 0a 09 63 74 78 2e 6c 69 6e 65 57 69 64  th...ctx.lineWid
2d90: 74 68 20 3d 20 4c 49 4e 45 5f 57 49 44 54 48 3b  th = LINE_WIDTH;
2da0: 0d 0a 09 0d 0a 09 0d 0a 0d 0a 20 20 20 20 0d 0a  ..........    ..
2db0: 09 09 0d 0a 09 0d 0a 09 66 6f 72 28 76 61 72 20  ........for(var 
2dc0: 69 20 3d 20 30 3b 20 69 20 3c 20 73 65 6c 65 63  i = 0; i < selec
2dd0: 74 65 64 5f 70 6f 69 6e 74 73 2e 6c 65 6e 67 74  ted_points.lengt
2de0: 68 3b 20 2b 2b 69 29 7b 0d 0a 09 09 76 61 72 20  h; ++i){....var 
2df0: 70 74 3b 0d 0a 09 09 0d 0a 09 09 69 66 28 73 65  pt;........if(se
2e00: 6c 65 63 74 65 64 5f 70 6f 69 6e 74 73 5b 69 5d  lected_points[i]
2e10: 20 3d 3d 20 2d 31 29 0d 0a 09 09 09 70 74 20 3d   == -1).....pt =
2e20: 20 5b 77 2f 32 2c 20 68 2f 32 5d 3b 0d 0a 09 09   [w/2, h/2];....
2e30: 65 6c 73 65 20 70 74 20 3d 20 70 6f 69 6e 74 5f  else pt = point_
2e40: 70 72 6f 6a 65 63 74 69 6f 6e 73 5b 73 65 6c 65  projections[sele
2e50: 63 74 65 64 5f 70 6f 69 6e 74 73 5b 69 5d 5d 3b  cted_points[i]];
2e60: 0d 0a 09 09 0d 0a 09 09 63 74 78 2e 66 69 6c 6c  ........ctx.fill
2e70: 53 74 79 6c 65 20 3d 20 50 4f 49 4e 54 5f 43 4f  Style = POINT_CO
2e80: 4c 4f 52 3b 0d 0a 09 09 69 66 28 70 74 29 20 63  LOR;....if(pt) c
2e90: 74 78 2e 66 69 6c 6c 52 65 63 74 28 70 74 5b 30  tx.fillRect(pt[0
2ea0: 5d 20 2d 20 34 2c 20 70 74 5b 31 5d 20 2d 20 34  ] - 4, pt[1] - 4
2eb0: 2c 20 38 2c 20 38 29 3b 20 7d 0d 0a 09 0d 0a 09  , 8, 8); }......
2ec0: 0d 0a 09 69 66 28 68 69 67 68 6c 69 67 68 74 5f  ...if(highlight_
2ed0: 6f 62 6a 65 63 74 20 21 3d 3d 20 6e 75 6c 6c 29  object !== null)
2ee0: 7b 0d 0a 09 09 0d 0a 09 09 0d 0a 09 09 69 66 28  {............if(
2ef0: 68 69 67 68 6c 69 67 68 74 5f 6f 62 6a 65 63 74  highlight_object
2f00: 20 3c 20 70 6f 69 6e 74 5f 70 72 6f 6a 65 63 74   < point_project
2f10: 69 6f 6e 73 2e 6c 65 6e 67 74 68 29 7b 0d 0a 09  ions.length){...
2f20: 09 09 76 61 72 20 70 74 3b 0d 0a 09 09 09 69 66  ..var pt;.....if
2f30: 28 68 69 67 68 6c 69 67 68 74 5f 6f 62 6a 65 63  (highlight_objec
2f40: 74 20 3d 3d 20 2d 31 29 0d 0a 09 09 09 09 70 74  t == -1)......pt
2f50: 20 3d 20 5b 77 2f 32 2c 20 68 2f 32 5d 3b 0d 0a   = [w/2, h/2];..
2f60: 09 09 09 65 6c 73 65 20 70 74 20 3d 20 70 6f 69  ...else pt = poi
2f70: 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b 68  nt_projections[h
2f80: 69 67 68 6c 69 67 68 74 5f 6f 62 6a 65 63 74 5d  ighlight_object]
2f90: 3b 0d 0a 09 09 09 0d 0a 09 09 09 63 74 78 2e 66  ;..........ctx.f
2fa0: 69 6c 6c 53 74 79 6c 65 20 3d 20 22 72 67 62 61  illStyle = "rgba
2fb0: 28 35 30 2c 20 35 30 2c 20 35 30 2c 20 2e 36 29  (50, 50, 50, .6)
2fc0: 22 3b 20 20 20 20 0d 0a 09 09 09 63 74 78 2e 66  ";    .....ctx.f
2fd0: 69 6c 6c 52 65 63 74 28 70 74 5b 30 5d 20 2d 20  illRect(pt[0] - 
2fe0: 34 2c 20 70 74 5b 31 5d 20 2d 20 34 2c 20 38 2c  4, pt[1] - 4, 8,
2ff0: 20 38 29 3b 20 20 2f 2f 20 54 4f 44 4f 20 67 65   8);  // TODO ge
3000: 74 74 69 6e 67 20 61 20 65 72 72 6f 72 20 68 65  tting a error he
3010: 72 65 20 74 68 61 74 20 70 74 20 69 73 20 6e 75  re that pt is nu
3020: 6c 6c 20 0d 0a 09 09 09 64 6f 63 75 6d 65 6e 74  ll .....document
3030: 2e 62 6f 64 79 2e 73 74 79 6c 65 2e 63 75 72 73  .body.style.curs
3040: 6f 72 20 3d 20 22 68 61 6e 64 22 3b 20 7d 0d 0a  or = "hand"; }..
3050: 09 09 09 0d 0a 09 09 65 6c 73 65 20 69 66 28 68  .......else if(h
3060: 69 67 68 6c 69 67 68 74 5f 6f 62 6a 65 63 74 20  ighlight_object 
3070: 3c 20 70 6f 69 6e 74 5f 70 72 6f 6a 65 63 74 69  < point_projecti
3080: 6f 6e 73 2e 6c 65 6e 67 74 68 20 2b 20 6c 69 6e  ons.length + lin
3090: 65 5f 6d 69 64 70 6f 69 6e 74 5f 70 72 6f 6a 65  e_midpoint_proje
30a0: 63 74 69 6f 6e 73 2e 6c 65 6e 67 74 68 29 7b 0d  ctions.length){.
30b0: 0a 09 09 09 2f 2f 20 61 6c 65 72 74 28 22 64 72  ....// alert("dr
30c0: 61 77 69 6e 67 20 68 69 67 68 6c 69 67 68 74 65  awing highlighte
30d0: 64 20 6c 69 6e 65 22 29 3b 0d 0a 09 09 09 0d 0a  d line");.......
30e0: 09 09 09 76 61 72 20 6c 69 6e 65 20 3d 20 6c 69  ...var line = li
30f0: 6e 65 73 5b 68 69 67 68 6c 69 67 68 74 5f 6f 62  nes[highlight_ob
3100: 6a 65 63 74 20 2d 20 70 6f 69 6e 74 5f 70 72 6f  ject - point_pro
3110: 6a 65 63 74 69 6f 6e 73 2e 6c 65 6e 67 74 68 5d  jections.length]
3120: 3b 0d 0a 09 09 09 69 66 28 6c 69 6e 65 29 7b 0d  ;.....if(line){.
3130: 0a 09 09 09 09 76 61 72 20 70 74 31 20 3d 20 70  .....var pt1 = p
3140: 6f 69 6e 74 5f 70 72 6f 6a 65 63 74 69 6f 6e 73  oint_projections
3150: 5b 6c 69 6e 65 5b 30 5d 5d 3b 0d 0a 09 09 09 09  [line[0]];......
3160: 76 61 72 20 70 74 32 20 3d 20 70 6f 69 6e 74 5f  var pt2 = point_
3170: 70 72 6f 6a 65 63 74 69 6f 6e 73 5b 6c 69 6e 65  projections[line
3180: 5b 31 5d 5d 3b 0d 0a 09 09 09 09 0d 0a 09 09 09  [1]];...........
3190: 09 69 66 28 70 74 31 20 26 26 20 70 74 32 29 7b  .if(pt1 && pt2){
31a0: 0d 0a 09 09 09 09 0d 0a 09 09 09 09 09 63 74 78  .............ctx
31b0: 2e 62 65 67 69 6e 50 61 74 68 28 29 3b 0d 0a 09  .beginPath();...
31c0: 09 09 09 09 0d 0a 09 09 09 09 09 63 74 78 2e 6d  ...........ctx.m
31d0: 6f 76 65 54 6f 28 70 74 31 5b 30 5d 2c 20 70 74  oveTo(pt1[0], pt
31e0: 31 5b 31 5d 29 3b 0d 0a 09 09 09 09 09 63 74 78  1[1]);.......ctx
31f0: 2e 6c 69 6e 65 54 6f 28 70 74 32 5b 30 5d 2c 20  .lineTo(pt2[0], 
3200: 70 74 32 5b 31 5d 29 3b 0d 0a 09 09 09 09 09 63  pt2[1]);.......c
3210: 74 78 2e 6c 69 6e 65 57 69 64 74 68 20 3d 20 33  tx.lineWidth = 3
3220: 3b 0d 0a 09 09 09 09 09 63 74 78 2e 73 74 72 6f  ;.......ctx.stro
3230: 6b 65 28 29 3b 0d 0a 09 09 09 09 09 63 74 78 2e  ke();.......ctx.
3240: 6c 69 6e 65 57 69 64 74 68 20 3d 20 31 3b 20 7d  lineWidth = 1; }
3250: 7d 7d 0d 0a 09 09 09 0d 0a 09 09 65 6c 73 65 7b  }}.........else{
3260: 0d 0a 09 09 09 74 68 72 6f 77 20 22 68 69 67 68  .....throw "high
3270: 6c 69 67 68 74 20 6f 62 6a 65 63 74 20 69 6e 64  light object ind
3280: 65 78 20 74 6f 20 6c 61 72 67 65 22 3b 20 7d 7d  ex to large"; }}
3290: 0d 0a 09 09 0d 0a 09 65 6c 73 65 7b 0d 0a 09 09  .......else{....
32a0: 64 6f 63 75 6d 65 6e 74 2e 62 6f 64 79 2e 73 74  document.body.st
32b0: 79 6c 65 2e 63 75 72 73 6f 72 20 3d 20 22 63 72  yle.cursor = "cr
32c0: 6f 73 73 68 61 69 72 22 3b 20 7d 0d 0a 09 0d 0a  osshair"; }.....
32d0: 09 69 66 28 6d 6f 75 73 65 5f 64 72 61 67 67 69  .if(mouse_draggi
32e0: 6e 67 29 7b 0d 0a 09 0d 0a 09 09 69 66 28 73 65  ng){.......if(se
32f0: 6c 65 63 74 65 64 5f 70 6f 69 6e 74 73 2e 6c 65  lected_points.le
3300: 6e 67 74 68 20 26 26 20 21 67 65 74 4b 65 79 53  ngth && !getKeyS
3310: 74 61 74 65 28 31 36 29 29 7b 20 20 2f 2f 20 69  tate(16)){  // i
3320: 66 20 73 68 69 66 74 20 69 73 20 68 65 6c 64 2c  f shift is held,
3330: 20 77 65 20 61 72 65 20 73 65 6c 65 63 74 69 6e   we are selectin
3340: 67 20 6d 6f 72 65 20 70 6f 69 6e 74 73 2e 0d 0a  g more points...
3350: 09 09 09 69 66 28 6d 6f 75 73 65 5f 6c 6f 63 20  ...if(mouse_loc 
3360: 26 26 20 67 65 74 4b 65 79 53 74 61 74 65 28 31  && getKeyState(1
3370: 30 30 30 29 29 7b 0d 0a 09 09 09 09 63 74 78 2e  000)){......ctx.
3380: 62 65 67 69 6e 50 61 74 68 28 29 3b 0d 0a 09 09  beginPath();....
3390: 09 09 76 61 72 20 70 74 20 3d 20 70 6f 69 6e 74  ..var pt = point
33a0: 5f 70 72 6f 6a 65 63 74 69 6f 6e 73 5b 73 65 6c  _projections[sel
33b0: 65 63 74 65 64 5f 70 6f 69 6e 74 73 5b 30 5d 5d  ected_points[0]]
33c0: 3b 0d 0a 09 09 09 09 69 66 28 70 74 29 7b 0d 0a  ;......if(pt){..
33d0: 09 09 09 09 09 63 74 78 2e 6d 6f 76 65 54 6f 28  .....ctx.moveTo(
33e0: 6d 6f 75 73 65 5f 6c 6f 63 5b 30 5d 2c 20 6d 6f  mouse_loc[0], mo
33f0: 75 73 65 5f 6c 6f 63 5b 31 5d 29 3b 0d 0a 09 09  use_loc[1]);....
3400: 09 09 09 63 74 78 2e 6c 69 6e 65 54 6f 28 70 74  ...ctx.lineTo(pt
3410: 5b 30 5d 2c 20 70 74 5b 31 5d 29 3b 20 7d 0d 0a  [0], pt[1]); }..
3420: 09 09 09 09 63 74 78 2e 73 74 72 6f 6b 65 28 29  ....ctx.stroke()
3430: 3b 20 7d 7d 0d 0a 09 09 09 09 0d 0a 09 09 65 6c  ; }}..........el
3440: 73 65 20 69 66 28 6d 6f 75 73 65 5f 6c 6f 63 20  se if(mouse_loc 
3450: 26 26 20 6c 61 73 74 5f 6d 6f 75 73 65 5f 64 6f  && last_mouse_do
3460: 77 6e 29 7b 20 20 0d 0a 09 09 0d 0a 09 09 0d 0a  wn){  ..........
3470: 09 09 20 20 20 20 69 66 28 67 65 74 4b 65 79 53  ..    if(getKeyS
3480: 74 61 74 65 28 31 30 30 30 29 29 7b 20 20 20 20  tate(1000)){    
3490: 20 2f 2f 20 73 65 6c 65 63 74 20 70 6f 69 6e 74   // select point
34a0: 73 20 69 6e 73 69 64 65 20 73 71 75 61 72 65 0d  s inside square.
34b0: 0a 09 09 09 09 76 61 72 20 6d 69 6e 78 20 3d 20  .....var minx = 
34c0: 4d 61 74 68 2e 6d 69 6e 28 6d 6f 75 73 65 5f 6c  Math.min(mouse_l
34d0: 6f 63 5b 30 5d 2c 20 6c 61 73 74 5f 6d 6f 75 73  oc[0], last_mous
34e0: 65 5f 64 6f 77 6e 5b 30 5d 29 3b 0d 0a 09 09 09  e_down[0]);.....
34f0: 09 76 61 72 20 6d 61 78 78 20 3d 20 4d 61 74 68  .var maxx = Math
3500: 2e 6d 61 78 28 6d 6f 75 73 65 5f 6c 6f 63 5b 30  .max(mouse_loc[0
3510: 5d 2c 20 6c 61 73 74 5f 6d 6f 75 73 65 5f 64 6f  ], last_mouse_do
3520: 77 6e 5b 30 5d 29 3b 0d 0a 09 09 09 09 76 61 72  wn[0]);......var
3530: 20 6d 69 6e 79 20 3d 20 4d 61 74 68 2e 6d 69 6e   miny = Math.min
3540: 28 6d 6f 75 73 65 5f 6c 6f 63 5b 31 5d 2c 20 6c  (mouse_loc[1], l
3550: 61 73 74 5f 6d 6f 75 73 65 5f 64 6f 77 6e 5b 31  ast_mouse_down[1
3560: 5d 29 3b 0d 0a 09 09 09 09 76 61 72 20 6d 61 78  ]);......var max
3570: 79 20 3d 20 4d 61 74 68 2e 6d 61 78 28 6d 6f 75  y = Math.max(mou
3580: 73 65 5f 6c 6f 63 5b 31 5d 2c 20 6c 61 73 74 5f  se_loc[1], last_
3590: 6d 6f 75 73 65 5f 64 6f 77 6e 5b 31 5d 29 3b 0d  mouse_down[1]);.
35a0: 0a 09 09 09 09 63 74 78 2e 62 65 67 69 6e 50 61  .....ctx.beginPa
35b0: 74 68 28 29 3b 0d 0a 09 09 09 09 63 74 78 2e 72  th();......ctx.r
35c0: 65 63 74 28 6d 69 6e 78 2c 20 6d 69 6e 79 2c 20  ect(minx, miny, 
35d0: 6d 61 78 78 20 2d 20 6d 69 6e 78 2c 20 6d 61 78  maxx - minx, max
35e0: 79 20 2d 20 6d 69 6e 79 29 3b 0d 0a 09 09 09 09  y - miny);......
35f0: 63 74 78 2e 73 74 72 6f 6b 65 28 29 3b 20 7d 7d  ctx.stroke(); }}
3600: 0d 0a 09 7d 0d 0a 20 20 20 20 0d 0a 20 20 20 20  ...}..    ..    
3610: 63 74 78 2e 66 69 6c 6c 53 74 79 6c 65 20 3d 20  ctx.fillStyle = 
3620: 22 72 67 62 28 30 2c 30 2c 30 29 22 3b 0d 0a 09  "rgb(0,0,0)";...
3630: 77 72 69 74 65 4d 73 67 28 63 61 6e 76 61 73 2c  writeMsg(canvas,
3640: 20 6d 73 67 29 3b 20 7d 0d 0a 09 0d 0a 2a 2f 0d   msg); }.....*/.
3650: 0a 0d 0a                                         ...