diff options
Diffstat (limited to 'assets/javascripts/rectangles/models')
| -rw-r--r-- | assets/javascripts/rectangles/models/rect.js | 131 | ||||
| -rw-r--r-- | assets/javascripts/rectangles/models/room.js | 39 | ||||
| -rw-r--r-- | assets/javascripts/rectangles/models/tree.js | 37 | ||||
| -rw-r--r-- | assets/javascripts/rectangles/models/vec2.js | 81 |
4 files changed, 288 insertions, 0 deletions
diff --git a/assets/javascripts/rectangles/models/rect.js b/assets/javascripts/rectangles/models/rect.js new file mode 100644 index 0000000..548e16a --- /dev/null +++ b/assets/javascripts/rectangles/models/rect.js @@ -0,0 +1,131 @@ +var FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8 + +window.rect = (function(){ + var rect = function (x0,y0,x1,y1){ + if (x0 instanceof vec2) { + this.x = x0 + this.y = y0 + } + else if (x1 === undefined) { + this.x = new vec2(x0,x0) + this.y = new vec2(y0,y0) + } + else { + this.x = new vec2(x0,x1) + this.y = new vec2(y0,y1) + } + this.translation = new vec2(0,0) + this.sides = FRONT | BACK | LEFT | RIGHT + } + rect.prototype.clone = function(){ + return new rect( this.x.clone(), this.y.clone() ) + } + rect.prototype.center = function(){ + return new vec2(this.x.midpoint(), this.y.midpoint()) + } + rect.prototype.area = function(){ + return this.x.length() * this.y.length() + } + rect.prototype.translate = function(translation){ + var translation = translation || this.translation + this.x.abs().add(translation.a) + this.y.abs().add(translation.b) + this.translation.a = this.translation.b = 0 + return this + } + rect.prototype.contains = function(x,y){ + return this.x.contains(x) && this.y.contains(y) + } + rect.prototype.intersects = function(r){ + return this.x.intersects(r.x) && this.y.intersects(r.y) + } + rect.prototype.width = function(){ return this.x.length() } + rect.prototype.height = function(){ return this.y.length() } + rect.prototype.toString = function(){ + var sides = "" + if (this.sides & FRONT) sides += "front " + if (this.sides & BACK) sides += "back " + if (this.sides & LEFT) sides += "left " + if (this.sides & RIGHT) sides += "right " + var s = "[" + this.x.toString() + " " + this.y.toString() + "] " + sides + return s + } + rect.prototype.quantize = function(n){ + this.x.quantize(n) + this.y.quantize(n) + } + 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 + } + + x_intervals.forEach(function(x){ + y_intervals.forEach(function(y){ + 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) + }) + }) + return splits + } + + return rect + +})() diff --git a/assets/javascripts/rectangles/models/room.js b/assets/javascripts/rectangles/models/room.js new file mode 100644 index 0000000..8c9d67d --- /dev/null +++ b/assets/javascripts/rectangles/models/room.js @@ -0,0 +1,39 @@ +window.room = (function(){ + + var room = function(opt){ + this.id = opt.id || clipper.rooms.length + this.rect = opt.rect + this.regions = [] + this.height = opt.height || 200 + this.focused = false + } + + room.prototype.toString = function(){ + return this.rect.toString() + } + + room.prototype.reset = function(){ + var copy = this.rect.clone() + copy.id = this.id + copy.sides = FRONT | BACK | LEFT | RIGHT + this.regions = [ copy ] + } + + room.prototype.clipTo = function(r){ + // for each of this rect's regions split the region if necessary + var regions = this.regions + var splits + + for (var i = 0, len = regions.length; i < len; i++) { + if (regions[i] && regions[i].intersects(r)) { + splits = regions[i].split(r) + regions = regions.concat(splits) + regions[i] = null + } + } + this.regions = regions + } + + return room + +})() diff --git a/assets/javascripts/rectangles/models/tree.js b/assets/javascripts/rectangles/models/tree.js new file mode 100644 index 0000000..577c41a --- /dev/null +++ b/assets/javascripts/rectangles/models/tree.js @@ -0,0 +1,37 @@ +var tree = function(n, data){ + this.lo = null + this.hi = null + this.value = n + this.data = data +} +tree.prototype.find = function(n){ + if (n == this.value) return this + if (n < this.value) return this.lo ? this.lo.find(n) : this + if (n > this.value) return this.hi ? this.hi.find(n) : this +} +tree.prototype.add = function(n, data){ + var closest = this.find(n) + if (n == closest.value) return closest + if (n < closest.value) return closest.lo = new tree(n, data) + if (n > closest.value) return closest.hi = new tree(n, data) +} +tree.prototype.toArray = function(){ + var a = [] + if (this.lo) a = a.concat(this.lo.toArray()) + a.push(this.data) + if (this.hi) a = a.concat(this.hi.toArray()) + return a +} +tree.prototype.toString = function(){ + var s = ""; + if (this.lo) s += this.lo.toString() + s += this.value + "," + if (this.hi) s += this.hi.toString() + return s +} +tree.prototype.depth = function(){ + if (this.lo && this.hi) return 1 + max(this.lo.depth(), this.hi.depth()) + else if (this.lo) return 1 + this.lo.depth() + else if (this.hi) return 1 + this.hi.depth() + else return 0 +} diff --git a/assets/javascripts/rectangles/models/vec2.js b/assets/javascripts/rectangles/models/vec2.js new file mode 100644 index 0000000..4e2ad36 --- /dev/null +++ b/assets/javascripts/rectangles/models/vec2.js @@ -0,0 +1,81 @@ +function vec2(a,b){ + this.a = a + this.b = b +} +vec2.prototype.magnitude = function(){ + return this.b-this.a +} +vec2.prototype.length = function(){ + return abs(this.b-this.a) +} +vec2.prototype.clone = function(){ + return new vec2(this.a, this.b) +} +vec2.prototype.abs = function(){ + if (this.b < this.a) { + this.a = this.a ^ this.b + this.b = this.a ^ this.b + this.a = this.a ^ this.b + } + return this +} +vec2.prototype.midpoint = function(){ + return lerp(0.5, this.a, this.b) +} +vec2.prototype.eq = function(v){ + return this.a == v.a && this.b == v.b +} +vec2.prototype.add = function(n){ + this.a += n + this.b += n +} +vec2.prototype.sub = function(n){ + this.a -= n + this.b -= n +} +vec2.prototype.mul = function(n){ + this.a *= n + this.b *= n +} +vec2.prototype.div = function(n){ + this.a /= n + this.b /= n +} +vec2.normalize = function(){ + var dim = max(this.a, this.b) + this.a = this.a/dim + this.b = this.b/dim +} +vec2.prototype.contains = function(n){ + return this.a <= n && n <= this.b +} +vec2.prototype.intersects = function(v){ + if (this.a < v.a) { + return (v.a < this.b && this.b <= v.b) || (this.a < v.b && v.b <= this.b) + } + else if (this.a == v.a) { + return true + } + else if (this.a > v.a) { + return (this.a < v.b && v.b <= this.b) || (v.a < this.b && this.b <= v.b) + } +} +vec2.prototype.union = function(v){ + if (this.intersects(v)) { + return new vec2( min(this.a,v.a), max(this.b, v.b) ) + } +} +vec2.prototype.intersection = function(v){ + if (this.intersects(v)) { + return new vec2( max(this.a,v.a), min(this.b, v.b) ) + } +} +vec2.prototype.toString = function(){ + return "[" + this.a + " " + this.b + "]" +} +vec2.prototype.quantize = function(n){ + n = n || 10 + this.a = quantize(this.a, n) + this.b = quantize(this.b, n) +} + |
