Ah ha. Finally found the bug in the math test page's UI.
authordsc <david.schoonover@gmail.com>
Tue, 9 Nov 2010 23:32:32 +0000 (15:32 -0800)
committerdsc <david.schoonover@gmail.com>
Tue, 9 Nov 2010 23:32:32 +0000 (15:32 -0800)
17 files changed:
bin/deploy.sh
index.php
src/Y/y-array.js
src/portal/layer.js
src/portal/math/line.js
src/portal/math/math.js
src/portal/math/vec.js
src/portal/shape.js
src/portal/util/loc.js
src/tanks/game/level.js [new file with mode: 0644]
src/tanks/game/map.js
src/tanks/lttl.js
src/tanks/thing/bullet.js
src/tanks/util/grid.js
src/tanks/util/pathmap.js
test/math/index.php
test/math/math.test.js

index 4a6a94f..5251783 100755 (executable)
@@ -4,31 +4,19 @@ function halp () {
     cat >&2 <<-HALP
 The Littlest Deployer of Battletanks
 
-Usage:     $( basename $0 ) [options] 
-
-Deploys Simoon files.
-
-Options:
-    -h              Displays this help.
+Usage:     $( basename $0 ) [exclude...]
 HALP
 }
 
 SHIFT=0
 function incshift () { SHIFT=$(( $SHIFT + ${1:-1} )); }
-function join () { seps="$IFS"; IFS="$1"; shift; echo "$*"; IFS="$seps"; }
 function fail () { echo "PREDICTABLE FAILURE. $1" >&2; exit 1; }
 
 for opt in $*; do
-    egrep -xq -e '--?h(e(lp?)?)?' && { halp; exit 0; }
+    echo $opt | egrep -xq -e '--?h(e(lp?)?)?' && { halp; exit 0; }
 done
-# while getopts "b:" opt; do
-#     case $opt in
-#         b ) B=$OPTARG; incshift 2 ;;
-#     esac
-# done
-# shift $SHIFT
-
-rsync -Cavz --delete --exclude=tmp ./* less.ly:lessly/hacking/tanks/
-
 
+EXCLUDE="--exclude=$(join ' --exclude=' 'tmp' $*)"
+echo "rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/"
+rsync -Cavz --delete $EXCLUDE ./* less.ly:lessly/hacking/tanks/
 
index 2a76380..330dc95 100644 (file)
--- a/index.php
+++ b/index.php
@@ -48,18 +48,20 @@ $scripts = array(
     "src/portal/math/vec.js",
     "src/portal/math/line.js",
     
+    "src/portal/util/loc.js",
     "src/portal/util/quadtree.js",
     "src/portal/util/rbtree.js",
+    
     "src/portal/util/eventloop.js",
     "src/portal/util/fps.js",
     "src/portal/util/cooldown.js",
-    "src/portal/util/loc.js",
     
     "src/tanks/globals.js",
     "src/tanks/util/calc.js",
     "src/tanks/util/grid.js",
     "src/tanks/util/pathmap.js",
     
+    "src/tanks/game/level.js",
     "src/tanks/game/game.js",
     "src/tanks/game/map.js",
     
index de7a26c..7e9b140 100644 (file)
@@ -27,8 +27,10 @@ function array_remove(v){
 
 YArray.prototype.unique = array_unique;
 function array_unique(){
-    // Executes in the context of the new array
     return this.filter(function(v, i){
+        // Executes in the context of the new array, so
+        // `this.indexOf` is checking what we've already
+        // collected.
         return (this.indexOf(v) === -1);
     });
 }
index db019dd..b3a2f7f 100644 (file)
@@ -321,6 +321,53 @@ Layer = new Y.Class('Layer', {
     
     
     
+    
+    
+    
+    
+    /// Iterators ///
+    
+    invoke : function invoke(name){
+        var args = Y(arguments,1);
+        
+        this[name].apply(this, args);
+        this.children.invoke.apply(this.children, ['invoke', name].concat(args));
+        return this;
+    },
+    
+    setAll : function setAll(k,v){
+        this[k] = v;
+        this.children.invoke('setAll', k,v);
+        return this;
+    },
+    
+    /**
+     * Reduce "up", across this and parents, inner to outer:
+     *      acc = fn.call(context || node, acc, node)
+     */
+    reduceup : function reduceup(acc, fn, context){
+        // if ( Y.isFunction(fn) )
+        //     acc = fn.call(context || this, acc, this);
+        // else
+        //     acc = this[fn].call(context || this, acc, this);
+        acc = fn.call(context || this, acc, this);
+        return ( this.parent ? this.parent.reduceup(acc, fn, context) : acc );
+    },
+    
+    /**
+     * Reduce "down", across this and children, depth-first:
+     *      acc = fn.call(context || node, acc, node)
+     */
+    reduce : function reduce(acc, fn, context){
+        acc = fn.call(context || this, acc, this);
+        return this.children.reduce(acc, fn, context);
+    },
+    
+    
+    
+    
+    
+    
     /// Drawing Functions ///
     
     /**
@@ -352,25 +399,23 @@ Layer = new Y.Class('Layer', {
         ctx.clearRect(-w,-h, 2*w,2*h);
         ctx.translate(neg.x, neg.y);
         
-        // ctx.rotate(this.absRotation);
-        // ctx.translate(-this.originX, -this.originY);
-        
-        // ctx.scale(this.absScaleX, this.absScaleY);
-        
         // Set context attributes
+        var alwaysClear = !!this.alwaysClear;
         CONTEXT_ATTRS.forEach(function(name){
-            if (self[name] === undefined)
-                delete ctx[name];
-            else
+            if (self[name] !== undefined)
                 ctx[name] = self[name];
+            else if (alwaysClear)
+                delete ctx[name];
         });
         
+        // ctx.rotate(this.absRotation);
+        // ctx.translate(-this.originX, -this.originY);
+        // ctx.scale(this.absScaleX, this.absScaleY);
+        
         return this;
     },
     
-    /**
-     * To be implemented by subclasses.
-     */
+    /** To be implemented by subclasses. */
     drawShape : function drawShape(ctx){ return this; },
     
     _closePath : function _closePath(ctx){
@@ -411,60 +456,13 @@ Layer = new Y.Class('Layer', {
     
     
     
-    
-    
-    
-    /// Iterators ///
-    
-    invoke : function invoke(name){
-        var args = Y(arguments,1);
-        
-        this[name].apply(this, args);
-        this.children.invoke.apply(this.children, ['invoke', name].concat(args));
-        return this;
-    },
-    
-    setAll : function setAll(k,v){
-        this[k] = v;
-        this.children.invoke('setAll', k,v);
-        return this;
-    },
-    
-    /**
-     * Reduce "up", across this and parents, inner to outer:
-     *      acc = fn.call(context || node, acc, node)
-     */
-    reduceup : function reduceup(acc, fn, context){
-        // if ( Y.isFunction(fn) )
-        //     acc = fn.call(context || this, acc, this);
-        // else
-        //     acc = this[fn].call(context || this, acc, this);
-        acc = fn.call(context || this, acc, this);
-        return ( this.parent ? this.parent.reduceup(acc, fn, context) : acc );
-    },
-    
-    /**
-     * Reduce "down", across this and children, depth-first:
-     *      acc = fn.call(context || node, acc, node)
-     */
-    reduce : function reduce(acc, fn, context){
-        acc = fn.call(context || this, acc, this);
-        return this.children.reduce(acc, fn, context);
-    },
-    
-    
-    
     /// Misc ///
-    
     toString : function toString(){
         var pos = (this.layer ? this.position() : {top:NaN, left:NaN});
         return this.className+'['+pos.left+','+pos.top+']( children='+this.children.size()+' )';
     }
 });
 
-
-// Helpers for building the class
-
 function makeDelegate(name, dirties, prop){
     prop = prop || 'layer';
     return function(){
@@ -489,8 +487,4 @@ $(function(){
         .appendTo('head');
 });
 
-
-
-
-
 })(jQuery);
index b774a96..abe1250 100644 (file)
@@ -12,8 +12,8 @@ COS_HALF_PI = Math.cos(HALF_PI);
 math.Line = new Y.Class('Line', math.Vec, {
     
     init : function init(x1,y1, x2,y2, tdist){
-        this.x1 = x1; this.y1 = y1; this.p1 = new math.Vec(x1,y1);
-        this.x2 = x2; this.y2 = y2; this.p2 = new math.Vec(x2,y2);
+        this.x1 = x1; this.y1 = y1;
+        this.x2 = x2; this.y2 = y2;
         
         var xdelta = x2-x1, ydelta = y2-y1
         ,    m = this.slope  =  ydelta/xdelta
@@ -22,9 +22,13 @@ math.Line = new Y.Class('Line', math.Vec, {
         ;
         math.Vec.init.call(this, xdelta, ydelta);
         
+        this.p1 = new math.Vec(x1,y1);
+        this.p2 = new math.Vec(x2,y2);
+        
         this.theta = Math.atan2(ydelta, xdelta);
         this._cos  = Math.cos(this.theta);
         this._sin  = Math.sin(this.theta);
+        
         this.setTScale(tdist);
     },
     
index 99b71fd..bb8a8a1 100644 (file)
@@ -10,7 +10,7 @@ math = {
     reflect : function reflect(v, line){
         var dot   = math.Vec.dot
         ,   basev = math.Vec.difference(v, line.p1);
-        return line.clone()
+        return new math.Vec(line.x, line.y)
             .scale(2 * dot(basev,line) / dot(line,line))
             .subtract(basev)
             .add(line.p1);
index 995f1c1..33cf4f2 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * A 2-dimensional vector.
  */
-math.Vec = new Y.Class('Vec', {
+math.Vec = new Y.Class('Vec', [], {
     
     init : function init(x, y){
         if ( Array.isArray(x) ) {
@@ -9,8 +9,9 @@ math.Vec = new Y.Class('Vec', {
             x = x[0];
         }
         
-        this.x = x;
-        this.y = y;
+        this.length = 2;
+        this.x = this[0] = x;
+        this.y = this[1] = y;
     },
     
     equals : function equals(b){
@@ -62,7 +63,7 @@ math.Vec = new Y.Class('Vec', {
     },
     
     toString : function toString(){
-        return 'Vec('+this.x.toFixed(3)+','+this.y.toFixed(3)+')';
+        return '['+this.x.toFixed(3)+', '+this.y.toFixed(3)+']';
     }
     
 });
index 1f1b109..a31817b 100644 (file)
@@ -1,5 +1,8 @@
 Shape = new Y.Class('Shape', Layer, {
     _cssClasses : 'portal layer shape',
+    fillStyle   : 'rgba(231,48,117, 1)',
+    strokeStyle : 'transparent',
+    lineWidth   : 0,
     
     _calcDimension : function _calcDimension(which, values){
         values.unshift(0);
@@ -52,6 +55,7 @@ Circle = new Y.Class('Circle', Shape, {
         var r  = this.radius;
         ctx.arc(0,0, r, 0, Math.PI*2, false);
         ctx.fill();
+        ctx.stroke();
     }
     
 });
@@ -125,9 +129,10 @@ Line = new Y.Class('Line', Shape, {
     },
     
     fixSize : function fixSize(){
-        var p = this.parent
-        ,   w = this.canvasWidth, h = this.canvasHeight
-        ,   pw = p.canvasWidth,   ph = p.canvasHeight ;
+        var p  = this.parent
+        ,   pw = p.canvasWidth,    ph = p.canvasHeight
+        ,   w  = this.canvasWidth, h  = this.canvasHeight
+        ;
         
         if (w !== pw) {
             this.width(pw);
@@ -144,7 +149,8 @@ Line = new Y.Class('Line', Shape, {
         this.fixSize();
         var x1,y1, x2,y2
         ,   line = this.line, p1 = line.p1, p2 = line.p2
-        ,   w = this.canvasWidth, h = this.canvasHeight;
+        ,   w = this.canvasWidth, h = this.canvasHeight
+        ;
         
         x1 = 0; y1 = line.calcY(x1);
         if (y1 < 0) {
@@ -162,8 +168,8 @@ Line = new Y.Class('Line', Shape, {
         ctx.closePath();
         
         // Show definition points
-        this.point(p1.x,p1.y, '#4596FF');
-        this.point(p2.x,p2.y, '#4596FF');
+        this.point(p1.x,p1.y, 'rgba(69,150,255,0.4)');
+        this.point(p2.x,p2.y, 'rgba(69,150,255,0.4)');
     },
     
     
index d170dc8..659a6d8 100644 (file)
@@ -1,5 +1,5 @@
 // [x,y]
-Loc = new Y.Class('Loc', [], {
+Loc = new Y.Class('Loc', math.Vec, {
     
     init : function init(x, y){
         if ( Array.isArray(x) ) {
@@ -26,10 +26,6 @@ Loc = new Y.Class('Loc', [], {
     },
     attr : Y.attr.methodize(),
     
-    equals : function equals(loc){
-        return (this.x === loc.x) && (this.y === loc.y);
-    },
-    
     clone : function clone(){
         return new Loc(this.x, this.y);
     },
@@ -67,8 +63,8 @@ Loc = new Y.Class('Loc', [], {
     
     toString : function toString(){
         var x = this.x, y = this.y;
-        x = Y.isNumber(x) ? Math.round(x,2) : x;
-        y = Y.isNumber(y) ? Math.round(y,2) : y;
+        x = Y.isNumber(x) ? x.toFixed(2) : x;
+        y = Y.isNumber(y) ? y.toFixed(2) : y;
         return '('+x+','+y+')';
     }
     
@@ -106,23 +102,25 @@ Y(Loc).extend({
 Loc.Rect = new Y.Class('Rect', [], {
     init : function init(x1,y1, x2,y2){
         if (x1 instanceof Loc && y1 instanceof Loc) {
-            var top    = x1,
-                bottom = y1;
-        } else {
-            var top    = new Loc(x1,y1),
-                bottom = new Loc(x2,y2);
+            y2 = y1.y; x2 = y1.x;
+            y1 = x1.y; x1 = x1.x;
         }
-        this.left  = this.top    = top;
-        this.right = this.bottom = bottom;
         
         this.length = 4;
-        x1 = this.x1 = this[0] = this.x = top.x;
-        y1 = this.y1 = this[1] = this.y = top.y;
-        x2 = this.x2 = this[2] = bottom.x;
-        y2 = this.y2 = this[3] = bottom.y;
+        this.x1 = this[0] = this.x = x1;
+        this.y1 = this[1] = this.y = y1;
+        this.x2 = this[2] = x2;
+        this.y2 = this[3] = y2;
         
         this.width  = x2 - x1;
         this.height = y2 - y1;
+        
+        this.sides = {
+            top    : new math.Line(x1,y1, x2,y1),
+            bottom : new math.Line(x1,y2, x2,y2),
+            left   : new math.Line(x1,y1, x1,y2),
+            right  : new math.Line(x2,y1, x2,y2)
+        };
     },
     
     set : function set(k, v, def){
@@ -141,31 +139,6 @@ Loc.Rect = new Y.Class('Rect', [], {
     
     attr : Y.attr.methodize(),
     
-    top : function top(x1,y1){
-        if ( x1 !== undefined && y1 !== undefined )
-            return new Loc(this.x1, this.y1);
-        else
-            return this.attr({ 'x1':x1, 'y1': y1 });
-    },
-    bottom : function bottom(x2,y2){
-        if ( x2 !== undefined && y2 !== undefined )
-            return new Loc(this.x2, this.y2);
-        else
-            return this.attr({ 'x2':x2, 'y2': y2 });
-    },
-    left : function left(x1,y1){
-        if ( x1 !== undefined && y1 !== undefined )
-            return new Loc(this.x1, this.y1);
-        else
-            return this.attr({ 'x1':x1, 'y1': y1 });
-    },
-    right : function right(x2,y2){
-        if ( x2 !== undefined && y2 !== undefined )
-            return new Loc(this.x2, this.y2);
-        else
-            return this.attr({ 'x2':x2, 'y2': y2 });
-    },
-    
     moveTo : function moveTo(x,y){
         return new Loc.Rect(x,y, x+this.width,y+this.height);
     },
diff --git a/src/tanks/game/level.js b/src/tanks/game/level.js
new file mode 100644 (file)
index 0000000..0105e5c
--- /dev/null
@@ -0,0 +1,35 @@
+Wall = new Y.Class('Wall', Rect, {
+    fillStyle : 'rgba(255,255,255, 0.25)',
+    blocking : true,
+    
+    init : function init(x,y, w,h){
+        Rect.init.call(this, w,h);
+        
+        var x1 = x,   y1 = y
+        ,   x2 = x+w, y2 = y+h;
+        this.boundingBox = new Loc.Rect(x1,y1, x2,y2);
+        this.position(x,y);
+    }
+    
+});
+
+Level = new Y.Class('Level', Rect, {
+    
+    init : function init(game, w,h){
+        this.game = game;
+        this.pathmap = game.pathmap;
+        Rect.init.call(this, w,h);
+    },
+    
+    append : function append(children){
+        Y(arguments).forEach(function(child){
+            var bb = child.boundingBox;
+            if (child.blocking && bb)
+                child.region = this.pathmap.set(bb.x1,bb.y1, bb.x2,bb.y2, child);
+        }, this);
+        return Layer.prototype.append.apply(this, arguments);
+    },
+    
+    drawShape : Y.op.nop
+    
+});
\ No newline at end of file
index 3abf13c..a6dc4f7 100644 (file)
@@ -2,24 +2,24 @@
 Y(Game.prototype).extend({
     
     initMap : function initMap(){
-        var self = this;
+        // var self = this;
+        
+        this.byId = {};
+        this.units    = new Y.YArray();
+        this.bullets  = new Y.YArray();
+        this.blockers = new Y.YArray();
         
         this.pathmap = new PathMap(0,0, COLUMNS*REF_SIZE, ROWS*REF_SIZE, CAPACITY);
         
-        var root = this.root = this.grid = 
+        var root = 
+        this.root = 
+        this.grid = 
             new Grid(COLUMNS,ROWS, CELL_SIZE)
                 .appendTo(this.viewport);
         this.level =
-            new Layer()
-                .width(  root.layerWidth  )
-                .height( root.layerHeight )
+            new Level(this, root.layerWidth, root.layerHeight )
                 .appendTo(this.root);
         
-        this.byId = {};
-        this.units    = new Y.YArray();
-        this.bullets  = new Y.YArray();
-        this.blockers = new Y.YArray();
-        
         // Agent.addEventListener('create', function(evt){
         //     self.addAgent(evt.instance);
         // });
@@ -156,5 +156,3 @@ Y(Game.prototype).extend({
     }
     
 });
-
-
index 6cf21de..2ce4ee3 100644 (file)
@@ -3,10 +3,24 @@ jQuery(function($){
 v = $('#viewport');
 LBT = new Game();
 
+var sq = REF_SIZE
+,   wall = new Wall(6*sq,1*sq, 1*sq,4*sq);
+LBT.level.append(wall);
+
+
 T = new Tank(0);
 LBT.addUnit(T, 1,2);
+T.shape.hide();
+
+B = new Bullet(T, 5*REF_SIZE,5*REF_SIZE);
+LBT.addUnit(B);
+B.render( LBT.level );
+
+B = new Bullet(T, 25,25);
+LBT.addUnit(B);
+B.render( LBT.level );
 
-B = new Bullet(T, 3*REF_SIZE,3*REF_SIZE);
+B = new Bullet(T, 1*REF_SIZE,3*REF_SIZE);
 LBT.addUnit(B);
 B.render( LBT.level );
 
index 4855582..af51a27 100644 (file)
@@ -41,29 +41,34 @@ Bullet = new Y.Class('Bullet', Thing, {
     
     move : function move(){
         var p, wall, p2 = this.trajectory.p2
-        ,   level = this.game.grid, walls = level.walls
+        ,   level = this.game.level, walls = level.walls
         ,   w = level.layerWidth, h = level.layerHeight
         ,   trj = this.trajectory
-        ,   to  = this.trajectory.pcalc(this.elapsed);
+        ,   to  = this.trajectory.pcalc(this.elapsed)
+        ,   test = this.game.pathmap.attemptMove(this, trj, to)
+        ;
         
         // Do we need to reflect because we've hit a wall?
-        if (to.x <= 0 || to.x >= w || to.y <= 0 || to.y >= h) {
-            if (to.x <= 0) {
-                wall = walls.left;
-                to = trj.pointX(0);
-            
-            } else if (to.x >= w) {
-                wall = walls.right;
-                to = trj.pointX(w);
-            
-            } else if (to.y <= 0) {
-                wall = walls.top;
-                to = trj.pointY(0);
-            
-            } else if (to.y >= h) {
-                wall = walls.bottom;
-                to = trj.pointY(h);
-            }
+        // if (to.x <= 0 || to.x >= w || to.y <= 0 || to.y >= h) {
+        //     if (to.x <= 0) {
+        //         wall = walls.left;
+        //         to = trj.pointX(0);
+        //     
+        //     } else if (to.x >= w) {
+        //         wall = walls.right;
+        //         to = trj.pointX(w);
+        //     
+        //     } else if (to.y <= 0) {
+        //         wall = walls.top;
+        //         to = trj.pointY(0);
+        //     
+        //     } else if (to.y >= h) {
+        //         wall = walls.bottom;
+        //         to = trj.pointY(h);
+        //     }
+        if (!test.ok) {
+            to = test.to;
+            wall = test.line;
             
             p = math.reflect(p2, wall.tangent(to));
             
@@ -99,12 +104,16 @@ Bullet = new Y.Class('Bullet', Thing, {
         
         var t = this.trajectory;
         this.tline = Line.fromPoints(t.x1,t.y1, t.x2,t.y2)
-            .attr('strokeStyle', 'rgba(255,246,174, 0.5)')
+            .attr('strokeStyle', 'rgba(255,246,174, 0.05)')
             .appendTo( parent );
         
-        this.shape = new Circle(2.5)
+        this.shape = new Circle(3)
             .position(this.loc.x, this.loc.y)
-            .attr('fillStyle', '#FFF6AE')
+            .attr({
+                'fillStyle'   : '#EC5B38',
+                'strokeStyle' : 'transparent',
+                'lineWidth'   : 0
+            })
             .appendTo( parent );
         
         return this;
index c3b6862..22cf5c1 100644 (file)
@@ -9,15 +9,6 @@ Grid = new Y.Class('Grid', Rect, {
         this.rows = rows;
         this.size = size;
         Rect.init.call(this, cols*size, rows*size);
-        
-        var w = this.canvasWidth
-        ,   h = this.canvasHeight;
-        this.walls = {
-            top    : new math.Line(0,0, w,0),
-            bottom : new math.Line(0,h, w,h),
-            left   : new math.Line(0,0, 0,h),
-            right  : new math.Line(w,0, w,h)
-        };
     },
     
     drawShape : function drawShape(ctx){
index 9e3726f..5f5f8df 100644 (file)
@@ -1,5 +1,72 @@
 PathMap = new Y.Class('PathMap', QuadTree, {
     
+    init : function init(game, x1,y1, x2,y2, capacity) {
+        QuadTree.init.call(this, x1,y1, x2,y2, capacity);
+        
+        var w = this.width, h = this.height;
+        this.game = game;
+        this.walls = {
+            top    : new math.Line(0,0, w,0),
+            bottom : new math.Line(0,h, w,h),
+            left   : new math.Line(0,0, 0,h),
+            right  : new math.Line(w,0, w,h)
+        };
+        
+    },
+    
+    
+    attemptMove : function attemptMove(obj, trj, to){
+        var line, bb = obj.boundingBox
+        ,   w  = bb.width,      h  = bb.height
+        ,   x1 = to.x,          y1 = to.y
+        ,   x2 = x1+w,          y2 = y1+h
+        ,   maxW = this.width,  maxH = this.height
+        ;
+        
+        // Check for collision with the walls
+        if (x1 <= 0 || x2 >= maxW || y1 <= 0 || y2 >= maxH){
+            if (x1 <= 0) {
+                line = this.walls.left;
+                to = trj.pointX(w/2);
+            
+            } else if (x2 >= maxW) {
+                line = this.walls.right;
+                to = trj.pointX(maxW-w/2);
+            
+            } else if (y1 <= 0) {
+                line = this.walls.top;
+                to = trj.pointY(h/2);
+            
+            } else if (y2 >= maxH) {
+                line = this.walls.bottom;
+                to = trj.pointY(maxH-h/2);
+            }
+        }
+        
+        var blocker = this.get(x1,y1, x2,y2).remove(obj).shift();
+        if ( blocker ) {
+            var B = blocker.boundingBox;
+            if (bb.x2 < B.x1 && x2 >= B.x1) {
+                line = B.sides.left;
+                to = trj.pointX(B.x1-w/2);
+            } else if (bb.x1 > B.x2 && x1 <= B.x2) {
+                line = B.sides.right;
+                to = trj.pointX(B.x2+w/2);
+            } else if (bb.y2 < B.y1 && y2 >= B.y1) {
+                line = B.sides.top;
+                to = trj.pointX(B.y1-h/2);
+            } else if (bb.y1 > B.y2 && y1 <= B.y2) {
+                line = B.sides.bottom;
+                to = trj.pointX(B.y2+h/2);
+            }
+        }
+        
+        return { 'ok':!line, 'to':to, 'line':line };
+    },
+    
+    
+    
+    
     overlay : function overlay(gridEl){
         var w = this.width  *SCALE
         ,   h = this.height *SCALE
index 3fc9c2e..da6937a 100644 (file)
@@ -2,8 +2,10 @@
 <html>
 <head>
 <title>math</title>
-<script type="text/javascript">document.write('<base href="http://'+window.location.host+'/">');</script>
-<link rel="stylesheet" href="css/reset.css" type="text/css" media="screen">
+<?php
+//<script type="text/javascript">document.write('<base href="http://'+window.location.host+'/">');</script>
+?>
+<link rel="stylesheet" href="../../css/reset.css" type="text/css" media="screen">
 <style type="text/css" media="screen">
 
 html, body { width:100%; height:100%;
@@ -15,6 +17,7 @@ ul, ol, li { list-style: none ! important; margin:0; padding:0; }
 .rounded { border-radius:1em; -moz-border-radius:1em; -webkit-border-radius:1em; }
 
 #plot { position:relative; top:1em; width:1000px; height:600px; margin:0 auto; background-color:#fff; }
+#plot .circle { z-index:5; }
 
 </style>
 </head>
@@ -33,26 +36,25 @@ $scripts = array(
     // "http://static.ukijs.org/pkg/0.3.8/uki-more.js",
     
     "src/lessly/future.js",
-    
     "src/Y/y.js.php",
     "src/Y/modules/y.event.js",
     
     "src/evt/evt.class.js",
     
+    "src/portal/math/math.js",
+    "src/portal/math/vec.js",
+    "src/portal/math/line.js",
+    
     "src/portal/util/loc.js",
     "src/portal/layer.js",
     "src/portal/shape.js",
     "src/tanks/util/grid.js",
     
-    "src/portal/math/math.js",
-    "src/portal/math/vec.js",
-    "src/portal/math/line.js",
-    
     "test/math/math.test.js"
 );
 
 function js($src) {
-    echo "    <script src=\"$src\" type=\"text/javascript\"></script>\n";
+    echo "    <script src=\"../../$src\" type=\"text/javascript\"></script>\n";
 }
 
 foreach ($scripts as $s) js($s);
index 0fbf015..5fb18eb 100644 (file)
@@ -7,10 +7,10 @@ plot = $('#plot');
 
 w = plot.width();  w2 = w/2;
 h = plot.height(); h2 = h/2;
-W = w/PPU; W2 = W/2;
-H = h/PPU; H2 = H/2;
+COLS = w/PPU; COLS2 = COLS/2;
+ROWS = h/PPU; H2 = ROWS/2;
 
-grid = new Grid( W, H, PPU ).appendTo(plot);
+grid = new Grid( COLS, ROWS, PPU ).appendTo(plot);
 grid.lineWidth = 1.0;
 grid.strokeStyle = '#E0E0E0'; //'#EEEEEE'; //
 grid.draw();
@@ -20,7 +20,6 @@ ctx = grid.ctx;
 drawLine(-w,-h2, w,-h2, '#CCCCCC', 2.0);
 drawLine(w2,-h,  w2,h, '#CCCCCC', 2.0);
 
-
 P = new Layer()
     .width(w).height(h)
     .appendTo(grid);
@@ -31,12 +30,7 @@ ctx.scale(PPU, PPU);
 
 points = Y([]);
 line = mkLine(0,0, 2.3125,1);
-addPoint(-5,2);
-
-drawAngle(line.theta);
-
-tanLine = line.tangent(line.p2);
-drawLine(-W, tanLine.calcY(-W), W, tanLine.calcY(W), 'rgba(226,127,8, 0.5)');
+rv = addPoint(-5,2);
 
 dragging = false;
 P.layer.bind('click', function(evt){
@@ -69,15 +63,21 @@ function mvLine(pn, x,y){
     ,   y2 = (pn === 2 ? y : line.y2)
     ;
     mkLine(x1,y1, x2,y2);
-    redraw();
 }
 
 function redraw(color){
     color = color || 'rgba(231,48,117, 0.5)';
     var pts = points.clone();
     clear();
-    drawLine(-W, line.calcY(-W), W, line.calcY(W), color);
+    
+    // drawAngle(line.theta);
+    drawLine(-COLS, line.calcY(-COLS), COLS, line.calcY(COLS), color);
+    drawLine(-COLS, tanLine.calcY(-COLS), COLS, tanLine.calcY(COLS), 'rgba(226,127,8, 0.5)');
+    
     P.append(p1, p2);
+    bindPoint(p1, 1);
+    bindPoint(p2, 2);
+    
     pts.forEach(addPoint);
 }
 
@@ -100,6 +100,7 @@ function addPoint(x,y){
     var rv = math.reflect(c.vec,line)
     ,   rc = c.reflected = drawPoint(rv, null, '#F25522');
     points.push(c);
+    return rv;
 }
 
 function mkLine(x1,y1, x2,y2, color, pcolor){
@@ -108,19 +109,25 @@ function mkLine(x1,y1, x2,y2, color, pcolor){
     
     color  = color  || 'rgba(231,48,117, 0.5)';
     pcolor = pcolor || 'rgba(69,150,255, 1)';
-    var line = new math.Line(x1,y1, x2,y2);
-    drawLine(-W, line.calcY(-W), W, line.calcY(W), color);
+    
+    line = new math.Line(x1,y1, x2,y2);
+    tanLine = line.tangent(line.p2);
+    
+    // drawLine(-COLS, line.calcY(-COLS), COLS, line.calcY(COLS), color);
     
     p1 = drawPoint(line.x1, line.y1, pcolor);
-    p1.layer.bind('mousedown', function(){
+    p2 = drawPoint(line.x2, line.y2, pcolor);
+    redraw();
+    
+    return line;
+}
+
+function bindPoint(pt, pn){
+    pt.layer.bind('mousedown', function(){
         dragging = true;
         function onMove(evt){
             var r = 3.75, v = convertLoc(evt);
-            mvLine(1, v.x,v.y);
-            
-            // _p1.appendTo(P);
-            // p1.position(w2-r + v.x*PPU, h2-r - v.y*PPU)
-            
+            mvLine(pn, v.x,v.y);
             return false;
         }
         P.layer.bind('mousemove', onMove);
@@ -128,18 +135,15 @@ function mkLine(x1,y1, x2,y2, color, pcolor){
             dragging = false;
             P.layer.unbind('mousemove', onMove);
             P.layer.unbind('mouseup', arguments.callee);
-            // _p1.remove();
             return false;
         });
         return false;
     });
-    
-    p2 = drawPoint(line.x2, line.y2, pcolor);
-    return (window.line = line);
+    return pt;
 }
 
 function drawLine(x1,y1, x2,y2, color, width){
-    try {
+    // try {
         ctx.beginPath();
         ctx.lineWidth = width || PX;
         ctx.strokeStyle = color || '#000000';
@@ -147,9 +151,9 @@ function drawLine(x1,y1, x2,y2, color, width){
         ctx.lineTo(x2, -y2);
         ctx.stroke();
         ctx.closePath();
-    } catch (e) {
-        console.log('drawLine error:', e, '(',x1,y1,')', '(',x2,y2,')');
-    }
+    // } catch (e) {
+    //     console.log('drawLine error:', e, '(',x1,y1,')', '(',x2,y2,')');
+    // }
 }
 
 function drawPoint(x,y, color, r){
@@ -162,10 +166,14 @@ function drawPoint(x,y, color, r){
         var v = new math.Vec(x,y);
     
     var c = new Circle(r)
-        .position(w2-r + x*PPU, h2-r - y*PPU)
-        .attr({ 'fillStyle': color || 'rgba(0,0,0,0.5)' })
+        .position(w2 + x*PPU, h2 - y*PPU)
+        .attr({
+            'strokeStyle' : '',
+            'fillStyle'   : color || 'rgba(0,0,0,0.5)'
+        })
         .appendTo(P)
         .draw();
+    
     c.vec = v;
     c.layer.attr('title', '('+x+','+y+')');
     return c;
@@ -174,6 +182,7 @@ function drawPoint(x,y, color, r){
 function drawAngle(theta, radius){
     radius = radius || 3;
     ctx.beginPath();
+    ctx.strokeStyle = '';
     ctx.fillStyle = 'rgba(36,71,146, 0.25)';
     ctx.moveTo(0,0);
     ctx.lineTo(radius,0);