summaryrefslogtreecommitdiff
path: root/assets/javascripts/rectangles/clipper.js
diff options
context:
space:
mode:
Diffstat (limited to 'assets/javascripts/rectangles/clipper.js')
-rw-r--r--assets/javascripts/rectangles/clipper.js173
1 files changed, 173 insertions, 0 deletions
diff --git a/assets/javascripts/rectangles/clipper.js b/assets/javascripts/rectangles/clipper.js
new file mode 100644
index 0000000..bd0c521
--- /dev/null
+++ b/assets/javascripts/rectangles/clipper.js
@@ -0,0 +1,173 @@
+window.ctx = window.w = window.h = null;
+
+var clipper = new function(){
+ var base = this
+ var canvas = document.createElement("canvas")
+ var ctx = window.ctx = canvas.getContext("2d")
+ var w = window.w = canvas.width = 500
+ var h = window.h = canvas.height = 500
+ var regions = []
+ document.querySelector("#map").appendChild(canvas)
+
+ base.init = function (){
+ bind()
+ animate()
+ }
+ function animate(){
+ requestAnimationFrame(animate)
+ clear_canvas()
+
+ if (modified) {
+ solve_rects()
+ builder.tube("clipper:update")
+ }
+ draw_ruler()
+ draw_regions(base.regions)
+ draw_mouse(mouse)
+ z = false
+ }
+
+ var rects = base.rects = []
+
+ this.creating = false
+ this.dragging = false
+
+ var modified = true
+ var mouse = new rect(0,0,0,0)
+
+ function bind(){
+ canvas.addEventListener("mousedown", function(e){
+ var x = e.pageX, y = e.pageY
+ mouse = new rect (x,y)
+ if (e.shiftKey) {
+ mouse.quantize(10)
+ }
+
+ var intersects = rects.filter(function(r){ return r.focused = r.contains(x,y) })
+ // console.log(intersects)
+
+ if (intersects.length){
+ clipper.dragging = intersects[0]
+ }
+ else {
+ clipper.creating = true
+ }
+ if (e.shiftKey && clipper.dragging) {
+ clipper.dragging.quantize(10)
+ }
+ })
+ canvas.addEventListener("mousemove", function(e){
+ var x, y
+ if (e.shiftKey) {
+ x = quantize( e.pageX, 10 )
+ y = quantize( e.pageY, 10 )
+ }
+ else {
+ x = e.pageX
+ y = e.pageY
+ }
+
+ mouse.x.b = x
+ mouse.y.b = y
+
+ if (clipper.dragging) {
+ clipper.dragging.translation.a = mouse.x.magnitude()
+ clipper.dragging.translation.b = mouse.y.magnitude()
+ }
+ else if (clipper.creating) {
+ mouse.x.b = x
+ mouse.y.b = y
+ }
+ else {
+ mouse.x.a = mouse.x.b
+ mouse.y.a = mouse.y.b
+ }
+ })
+ document.addEventListener("mouseup", function(e){
+ if (clipper.creating) {
+ if (mouse.height() != 0 && mouse.width() != 0) {
+ rects.push(mouse.translate())
+ }
+ }
+ if (clipper.dragging) {
+ clipper.dragging.translate()
+ }
+ mouse = new rect(e.pageX, e.pageY)
+ clipper.creating = clipper.dragging = false
+ modified = true
+ })
+ }
+
+ function solve_rects(){
+ var rects = sort_rects_by_position(base.rects)
+
+ for (var i = 0; i < rects.length; i++) {
+ rects[i].id = i
+ rects[i].reset()
+ }
+ var regions = []
+
+ var left, right
+ for (var i = 0; i < rects.length; i++) {
+ left = rects[i]
+ for (var j = i+1; j < rects.length; j++) {
+ right = rects[j]
+ if (left.intersects(right)) {
+ left.clipTo(right)
+ right.clipTo(left)
+ }
+ if (left.x.b < right.x.a) {
+ break
+ }
+ }
+ }
+ for (var i = 0; i < rects.length; i++) {
+ regions = regions.concat(rects[i].regions)
+ }
+
+ regions = sort_rects_by_area( 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, ii){
+ if (yy.intersects(regions[i])) {
+ if (yy.area() > regions[i].area()) {
+ regions[i].dupe = true
+ }
+ else {
+ yy.dupe = true
+ tty.data[ii] = regions[i]
+ }
+ }
+ })
+ }
+ else {
+ tty.data = [regions[i]]
+ }
+ }
+ else {
+ ttx.data = new tree (regions[i].y.a, [regions[i]])
+ }
+ }
+
+ base.regions = sort_rects_by_position(regions)
+
+ modified = false
+ // document.getElementById("intersects").innerHTML = sort_rects_by_position(regions).join("<br>")
+ }
+
+ // generate floor and ceiling for some regions
+ // generate walls from surviving regions
+ // generate ceiling-walls where ceiling has discontinuity
+
+ return base
+}
+