Rooms.clipper = new function(){ var base = this base.init = function(){ base.bind() base.update() } base.bind = function(){ map.ui.mouse.tube.on("up", function(){ base.update() }) } base.update = function(){ base.solve_rects() app.tube("clip") } var rooms, regions // Given a set of overlapping rooms, clip any intersections, then cull any duplicate polygons base.solve_rects = function(){ if (Rooms.list.length == 0) return base.reset_rects() base.clip_rects() base.cull_rects() Rooms.regions = sort_rects_by_position(regions) } // Reset the clipping/culling states of each of the rooms base.reset_rects = function(){ for (var i = 0; i < Rooms.list.length; i++) { Rooms.list[i].reset() } } // Compare each room to the rooms it overlaps, and subdivide base.clip_rects = function(){ var rooms = Rooms.sorted_by_position() regions = [] var left, right for (var i = 0; i < rooms.length; i++) { left = rooms[i] for (var j = i+1; j < rooms.length; j++) { right = rooms[j] if (left.rect.intersects(right.rect)) { left.clipTo(right.rect) right.clipTo(left.rect) left.intersects.push(right) right.intersects.push(left) } if (left.rect.x.b < right.rect.x.a) { break } } } for (var i = 0; i < rooms.length; i++) { rooms[i].regions = rooms[i].regions.filter(function(r){ return !!r }) regions = regions.concat(rooms[i].regions) } } // Find overlapping regions (of the same size) and dedupe base.cull_rects = function(){ regions = sort_rects_by_area( regions ) 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]]) } } } return base }