summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/rectangles/models/rect.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/javascripts/rectangles/models/rect.js')
-rw-r--r--public/assets/javascripts/rectangles/models/rect.js118
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
}