diff options
| -rw-r--r-- | rect.js | 92 | ||||
| -rw-r--r-- | rectangles.html | 42 | ||||
| -rw-r--r-- | tree.js | 6 | ||||
| -rw-r--r-- | vec2.js | 14 |
4 files changed, 122 insertions, 32 deletions
@@ -1,3 +1,5 @@ +var FRONT = 0x1, BACK = 0x2, LEFT = 0x4, RIGHT = 0x8 + function rect (x0,y0,x1,y1){ if (x0 instanceof vec2) { this.x = x0 @@ -12,6 +14,9 @@ function rect (x0,y0,x1,y1){ this.y = new vec2(y0,y1) } this.translation = new vec2(0,0) + this.sides = FRONT | BACK | LEFT | RIGHT + this.focused = false + this.id = 0 } rect.prototype.clone = function(){ return new rect( this.x.clone(), this.y.clone() ) @@ -37,13 +42,30 @@ rect.prototype.intersects = function(r){ rect.prototype.width = function(){ return this.x.length() } rect.prototype.height = function(){ return this.y.length() } rect.prototype.fill = function(){ +// if (! this.sides) return this ctx.fillRect(this.x.a + this.translation.a, this.y.a + this.translation.b, this.x.length(), this.y.length()) + return this +} +rect.prototype.stroke_sides = function(){ + if (this.sides & FRONT) line(this.x.a, this.y.a, this.x.b, this.y.a) + if (this.sides & BACK) line(this.x.a, this.y.b, this.x.b, this.y.b) + if (this.sides & LEFT) line(this.x.a, this.y.a, this.x.a, this.y.b) + if (this.sides & RIGHT) line(this.x.b, this.y.a, this.x.b, this.y.b) + + function line(a,b,c,d){ + ctx.beginPath() + ctx.moveTo(a,b) + ctx.lineTo(c,d) + ctx.stroke() + } + return this } rect.prototype.stroke = function(){ ctx.beginPath() ctx.moveTo(this.x.a, this.y.a) ctx.lineTo(this.x.b, this.y.b) ctx.stroke() + return this } rect.prototype.perimeter = function(){ line( this.x.a, this.y.a, this.x.b, this.y.a, this.translation ) @@ -52,7 +74,14 @@ rect.prototype.perimeter = function(){ line( this.x.b, this.y.a, this.x.b, this.y.b, this.translation ) } rect.prototype.toString = function(){ - return "[" + this.x.toString() + " " + this.y.toString() + "]" + 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.id + " " + "[" + this.x.toString() + " " + this.y.toString() + "] " + sides + if (this.focused) return "<b>" + s + "</b>" + return s } rect.prototype.quantize = function(n){ this.x.quantize(n) @@ -60,13 +89,16 @@ rect.prototype.quantize = function(n){ } rect.prototype.reset = function(){ var copy = this.clone() - copy.sides = 0xf + copy.sides = FRONT | BACK | LEFT | RIGHT + copy.focused = this.focused + copy.id = this.id this.regions = [ copy ] } rect.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) @@ -77,59 +109,73 @@ rect.prototype.clipTo = function(r){ this.regions = regions } 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 )) - x_intervals.push( new vec2( r.x.a, 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 )) - x_intervals.push( new vec2( r.x.b, this.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 )) - x_intervals.push( new vec2( r.x.a, r.x.b )) - x_intervals.push( new vec2( r.x.b, this.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 )) + 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 )) - y_intervals.push( new vec2( r.y.a, 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 )) - y_intervals.push( new vec2( r.y.b, this.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 )) - y_intervals.push( new vec2( r.y.a, r.y.b )) - y_intervals.push( new vec2( r.y.b, this.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 )) + 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){ - splits.push(new rect(x,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 } -zz = false -document.body.addEventListener("click", function(){ zz = true })
\ No newline at end of file diff --git a/rectangles.html b/rectangles.html index 71f83c6..c8b3c82 100644 --- a/rectangles.html +++ b/rectangles.html @@ -31,6 +31,8 @@ body > div { <script type="text/javascript" src="vec2.js"></script> <script type="text/javascript"> +window.z = true; + (function(){ var color_palettes = { alpha: [ @@ -88,8 +90,8 @@ canvas.addEventListener("mousedown", function(e){ mouse.quantize(10) } - var intersects = rects.filter(function(r){ return r.contains(x,y) }) - console.log(intersects) + var intersects = rects.filter(function(r){ return r.focused = r.contains(x,y) }) + // console.log(intersects) if (intersects.length){ dragging = intersects[0] @@ -180,6 +182,7 @@ function solve_rects(){ rects = sort_rects() for (var i = 0; i < rects.length; i++) { + rects[i].id = i rects[i].reset() } regions = [] @@ -206,17 +209,46 @@ function solve_rects(){ // generate walls from surviving regions // generate ceiling-walls where ceiling has discontinuity + // regions = shuffle( regions.filter(function(r){ return !!r }) ) regions = regions.filter(function(r){ return !!r }) + +// var ty = new tree (regions[0].y.a, [regions[0]]) +// var tx = new tree (regions[0].x.a, ty) +// var ttx, tty +// +// for (var i = 1; i < regions.length; i++) { +// ttx = tx.add (regions[i].x.a, null) +// if (ttx.data) { +// tty = ttx.data.add (regions[i].y.a, null) +// // duplicate polygon? +// if (tty.data) { +// tty.data.forEach(function(yy){ +// if (yy.x.eq(regions[i].x) && yy.y.eq(regions[i].y) ) { +// yy.sides = 0 +// regions[i].sides = 0 +// } +// }) +// } +// else { +// tty.data = [regions[i]] +// } +// } +// else { +// ttx.data = new tree (regions[i].y.a, [regions[i]]) +// } +// } + z = false for (var i = 0; i < regions.length; i++) { ctx.fillStyle = colors[i % colors.length] - regions[i] && regions[i].fill() + regions[i].fill().stroke_sides() } document.getElementById("intersects").innerHTML = regions.join("<br>") } + function sort_rects(){ return rects.sort(function(a,b){ - if (a.x.a <= b.x.a) { + if (a.x.a < b.x.a) { return -1 } if (a.x.a > b.x.a) { @@ -263,5 +295,7 @@ function draw_mouse(){ } } +document.body.addEventListener("mousedown", function(){ z = true }) + </script> </html> @@ -11,9 +11,9 @@ tree.prototype.find = function(n){ } tree.prototype.add = function(n, data){ var closest = this.find(n) - if (n == closest.value) return - if (n < closest.value) closest.lo = new tree(n, data) - if (n > closest.value) closest.hi = new tree(n, data) + 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.toString = function(){ var s = ""; @@ -22,6 +22,9 @@ vec2.prototype.abs = function(){ 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 @@ -41,9 +44,16 @@ vec2.prototype.div = function(n){ vec2.prototype.contains = function(n){ return this.a <= n && n <= this.b } -// assumes (vec2)v falls to the right of (vec2)this vec2.prototype.intersects = function(v){ - return (this.b > v.a && this.b < v.b) || (v.b > this.a && v.b < this.b) + 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)) { |
