diff options
Diffstat (limited to 'public/assets/javascripts/rectangles/models/rect.js')
| -rw-r--r-- | public/assets/javascripts/rectangles/models/rect.js | 118 |
1 files changed, 60 insertions, 58 deletions
diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index 315adef..590440a 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -1,5 +1,25 @@ (function(){ + var vec2 + if ('window' in this) { + vec2 = window.vec2 + } + else { + vec2 = require('./vec2') + FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8, FLOOR = 0x10, CEILING = 0x20 + TOP = CEILING, BOTTOM = FLOOR + function sidesToString(sides){ + var s = "" + if (sides & FRONT) s += "front " + if (sides & BACK) s += "back " + if (sides & LEFT) s += "left " + if (sides & RIGHT) s += "right " + if (sides & TOP) s += "top " + if (sides & BOTTOM) s += "bottom " + return s + } + } + var Rect = function (x0,y0,x1,y1){ if (x0 instanceof vec2) { this.x = x0 @@ -74,8 +94,18 @@ Rect.prototype.containsDisc = function(x,y,r){ return this.x.containsDisc(x,r) && this.y.containsDisc(y,r) } + Rect.prototype.overlaps = function(rect){ + return this.x.overlaps(rect.x) && this.y.overlaps(rect.y) + } Rect.prototype.intersects = function(r){ - return this.x.intersects(r.x) && this.y.intersects(r.y) + var corner_intersect = (this.x.b === r.x.a && this.y.b === r.y.a) + return this.x.intersects(r.x) && this.y.intersects(r.y) && ! corner_intersect + } + Rect.prototype.adjacent = function(r){ + return this.x.adjacent(r.x) && this.y.adjacent(r.y) + } + Rect.prototype.eq = function(r){ + return this.x.eq(r.x) && this.y.eq(r.y) } Rect.prototype.nearEdge = function (x, y, r) { var edges = 0 @@ -111,79 +141,51 @@ Rect.prototype.split = function(r){ var rz = this var splits = [] - var split_contains = 0 - var x_intervals = [], y_intervals = [] var sides = this.sides - // Split vertically - if (this.x.contains(r.x.a) && r.x.contains(this.x.b)) { - x_intervals.push([ new vec2( this.x.a, r.x.a ), LEFT ]) - x_intervals.push([ new vec2( r.x.a, this.x.b ), RIGHT ]) - split_contains |= RIGHT - } - - else if (r.x.contains(this.x.a) && this.x.contains(r.x.b)) { - x_intervals.push([ new vec2( this.x.a, r.x.b ), LEFT ]) - x_intervals.push([ new vec2( r.x.b, this.x.b ), RIGHT ]) - split_contains |= LEFT - } - - else if (this.x.contains(r.x.a) && this.x.contains(r.x.b)) { - x_intervals.push([ new vec2( this.x.a, r.x.a ), LEFT ]) - x_intervals.push([ new vec2( r.x.a, r.x.b ), 0 ]) - x_intervals.push([ new vec2( r.x.b, this.x.b ), RIGHT ]) - split_contains |= LEFT | RIGHT - } - - else { // if (r.x.contains(this.x.a) && r.x.contains(r.x.b)) { - x_intervals.push([ new vec2( this.x.a, this.x.b ), LEFT | RIGHT ]) - split_contains |= LEFT | RIGHT - } - - // Split horizontally - if (this.y.contains(r.y.a) && r.y.contains(this.y.b)) { - y_intervals.push([ new vec2( this.y.a, r.y.a ), FRONT ]) - y_intervals.push([ new vec2( r.y.a, this.y.b ), BACK ]) - split_contains |= BACK - } - - else if (r.y.contains(this.y.a) && this.y.contains(r.y.b)) { - y_intervals.push([ new vec2( this.y.a, r.y.b ), FRONT ]) - y_intervals.push([ new vec2( r.y.b, this.y.b ), BACK ]) - split_contains |= FRONT - } - - else if (this.y.contains(r.y.a) && this.y.contains(r.y.b)) { - y_intervals.push([ new vec2( this.y.a, r.y.a ), FRONT ]) - y_intervals.push([ new vec2( r.y.a, r.y.b ), 0 ]) - y_intervals.push([ new vec2( r.y.b, this.y.b ), BACK ]) - split_contains |= FRONT | BACK - } - - else { // if (r.y.contains(this.y.a) && this.y.contains(r.y.b)) { - y_intervals.push([ new vec2( this.y.a, this.y.b ), FRONT | BACK ]) - split_contains |= FRONT | BACK - } + // bisect (or trisect) two overlapping rectangles + var x_intervals = this.x.split( r.x, LEFT, RIGHT ) + var y_intervals = this.y.split( r.y, FRONT, BACK ) - x_intervals.forEach(function(x){ - y_intervals.forEach(function(y){ + // generate rectangular regions by crossing the two sets of vectors + x_intervals.forEach(function(x, i){ + y_intervals.forEach(function(y, i){ var rn = new Rect(x[0], y[0]) rn.id = rz.id rn.sides = ((x[1] | y[1]) & sides) - if (r.intersects(rn)) { - rn.sides = 0 - } rn.focused = rz.focused splits.push(rn) + + // cull extra walls from overlapping regions + if (r.x.contains(rn.x.a) && r.x.contains(rn.x.b)) { + if (rz.y.a == rn.y.a && r.y.containsCenter(rn.y.a)) { // top edges + rn.sides &= ~ FRONT + } + if (rz.y.b == rn.y.b && r.y.containsCenter(rn.y.b)) { // bottom edges + rn.sides &= ~ BACK + } + } + + if (r.y.contains(rn.y.a) && r.y.contains(rn.y.b)) { + if (rz.x.a == rn.x.a && r.x.containsCenter(rn.x.a)) { // left edges + rn.sides &= ~ LEFT + } + + if (rz.x.b == rn.x.b && r.x.containsCenter(rn.x.b) ) { // right edges + rn.sides &= ~ RIGHT + } + } + }) }) + return splits } if ('window' in this) { window.Rect = Rect } - else if ('module' in this) { + else { module.exports = Rect } |
