diff options
| -rw-r--r-- | public/assets/javascripts/rectangles/models/rect.js | 6 | ||||
| -rw-r--r-- | public/assets/javascripts/rectangles/models/surface.js | 9 | ||||
| -rw-r--r-- | public/assets/javascripts/rectangles/models/vec2.js | 5 | ||||
| -rw-r--r-- | public/assets/test/intersect.html | 15 | ||||
| -rw-r--r-- | public/assets/test/intersect2.html | 218 |
5 files changed, 248 insertions, 5 deletions
diff --git a/public/assets/javascripts/rectangles/models/rect.js b/public/assets/javascripts/rectangles/models/rect.js index 00f2c55..c667cf5 100644 --- a/public/assets/javascripts/rectangles/models/rect.js +++ b/public/assets/javascripts/rectangles/models/rect.js @@ -169,6 +169,12 @@ var s = "[" + this.x.toString() + " " + this.y.toString() + "] " + sides return s } + Rect.prototype.exactString = function(){ + var sides = sidesToString(this.sides) + var s = "[" + this.x.exactString() + " " + this.y.exactString() + "] " + sides + return s + } + Rect.prototype.serialize = function(){ return { x: this.x.serialize(), y: this.y.serialize() } } diff --git a/public/assets/javascripts/rectangles/models/surface.js b/public/assets/javascripts/rectangles/models/surface.js index 3a6c449..fc4aae4 100644 --- a/public/assets/javascripts/rectangles/models/surface.js +++ b/public/assets/javascripts/rectangles/models/surface.js @@ -154,6 +154,15 @@ } return -1 } + Surface.prototype.face_for_x = function(x, min_i){ + min_i = min_i || 0 + for (var i = min_i; i < this.faces.length; i++) { + if (this.faces[i].x.contains(x)) { + return this.faces[i] + } + } + return null + } Surface.prototype.bounds_at_index_with_dimensions = function(index, dimensions){ var faces = this.faces diff --git a/public/assets/javascripts/rectangles/models/vec2.js b/public/assets/javascripts/rectangles/models/vec2.js index 49613c3..f28df54 100644 --- a/public/assets/javascripts/rectangles/models/vec2.js +++ b/public/assets/javascripts/rectangles/models/vec2.js @@ -200,7 +200,10 @@ } vec2.prototype.toString = function(){ - return "[" + ~~this.a + " " + ~~this.b + "]" + return "[" + round(this.a) + " " + round(this.b) + "]" + } + vec2.prototype.exactString = function(){ + return "[" + this.a + " " + this.b + "]" } vec2.prototype.serialize = function(){ return [ ~~this.a, ~~this.b ] diff --git a/public/assets/test/intersect.html b/public/assets/test/intersect.html index 5e16f2e..4e5b0bb 100644 --- a/public/assets/test/intersect.html +++ b/public/assets/test/intersect.html @@ -1,4 +1,5 @@ <canvas id="canvas"></canvas> +<div id="hud"></div> <script src="/assets/javascripts/util.js"></script> <script src="/assets/javascripts/vendor/tube.js"></script> @@ -73,16 +74,21 @@ function draw () { var collinear = is_collinear( intersect, vec_b ) var long_enough_to_intersect = 0 <= t && t <= 1 + var msg if (long_enough_to_intersect && collinear) { ctx.fillStyle = "#f00" + msg = "through" } else if (collinear) { ctx.fillStyle = "#0f0" + msg = "to" } else { ctx.fillStyle = "#000" + msg = "off" } + hud.innerHTML = [intersect.exactString(), vec_b.exactString(), msg].join("<br>") drawPoint(intersect) } @@ -105,19 +111,20 @@ function perp (va, vb) { } function is_collinear (p, vec) { var on_x, on_y + var pa = round(p.a), pb = round(p.b) if (vec.x.a < vec.y.a) { - on_x = vec.x.a <= p.a && p.a <= vec.y.a + on_x = vec.x.a <= pa && pa <= vec.y.a } else { - on_x = vec.x.a >= p.a && p.a >= vec.y.a + on_x = vec.x.a >= pa && pa >= vec.y.a } if (vec.x.b < vec.y.b) { - on_y = vec.x.b <= p.b && p.b <= vec.y.b + on_y = vec.x.b <= pb && pb <= vec.y.b } else { - on_y = vec.x.b >= p.b && p.b >= vec.y.b + on_y = vec.x.b >= pb && pb >= vec.y.b } return !! (on_x && on_y) diff --git a/public/assets/test/intersect2.html b/public/assets/test/intersect2.html new file mode 100644 index 0000000..fade288 --- /dev/null +++ b/public/assets/test/intersect2.html @@ -0,0 +1,218 @@ +<style> +body,html{margin:0;padding:0;} +#hud { position: absolute; top: 0; left: 0; pointer-events: none; } +</style> +<canvas id="canvas"></canvas> +<div id="hud"></div> + +<script src="/assets/javascripts/util.js"></script> +<script src="/assets/javascripts/vendor/tube.js"></script> +<script src="/assets/javascripts/vendor/bower_components/jquery/dist/jquery.min.js"></script> +<script src="/assets/javascripts/vendor/bower_components/lodash/dist/lodash.min.js"></script> +<script src="/assets/javascripts/mx/mx.js"></script> +<script src="/assets/javascripts/mx/extensions/mx.scene.js"></script> +<script src="/assets/javascripts/rectangles/util/constants.js"></script> +<script src="/assets/javascripts/rectangles/util/mouse.js"></script> +<script src="/assets/javascripts/rectangles/util/sort.js"></script> +<script src="/assets/javascripts/rectangles/util/uid.js"></script> +<script src="/assets/javascripts/rectangles/models/vec2.js"></script> +<script src="/assets/javascripts/rectangles/models/rect.js"></script> +<script src="/assets/javascripts/rectangles/models/room.js"></script> +<script src="/assets/javascripts/rectangles/models/surface.js"></script> +<script src="/assets/javascripts/rectangles/models/wall.js"></script> +<script src="/assets/javascripts/rectangles/models/floor.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/_rooms.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/_walls.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/clipper.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/builder.js"></script> +<script src="/assets/javascripts/rectangles/engine/rooms/grouper.js"></script> +<script src="/assets/javascripts/vendor/canvasutilities.js"></script> +<script> + +var ctx = canvas.getContext('2d') +var scene = new MX.Scene() + +var w = canvas.width = window.innerWidth +var h = canvas.height = window.innerHeight + +var cursor = new Rect( 150, 250, 150, 250 ) +var wall_vec = new Rect ( 0, 0, 0, 0 ) +var points = [ cursor.x, cursor.y ] + +var origins = new Rect() +origins.x = cursor.x +origins.y = wall_vec.x + +var radius = 1 + +var rect = new Rect( new vec2(100,400), new vec2(100,400) ) +var east = new Rect( new vec2(200,600), new vec2(100,400) ) +var corner = new Rect( new vec2(300,700), new vec2(300,700) ) +var peninsula = new Rect( new vec2(400,600), new vec2(600,800) ) +var peninsula2 = new Rect( new vec2(650,750), new vec2(350,450) ) + +var rect_room = new Room({ id: "rect", rect: rect, height: 2 }) +var east_room = new Room({ id: "east", rect: east, height: 2 }) +var corner_room = new Room({ id: "corner", rect: corner, height: 2 }) +var peninsula_room = new Room({ id: "peninsula", rect: peninsula, height: 3 }) +var peninsula2_room = new Room({ id: "peninsula2", rect: peninsula2, height: 3 }) + +Rooms.add( rect_room ) +Rooms.add( east_room ) +Rooms.add( corner_room ) +Rooms.add( peninsula_room ) +Rooms.add( peninsula2_room ) + +Rooms.clipper.update() +Rooms.builder.build() +Rooms.grouper.build() + +var r = 4 + +var intersect = new vec2 () + +var dragging = false, dragging_a, dragging_b +var delta = new vec2( 0, 0 ) + +var mymouse = new mouse({ + el: canvas, + down: function(e, cursor){ + points.some(function(p){ + if (-cursor.x.a > p.a - r && -cursor.x.a < p.a + r && + cursor.y.a > p.b - r && cursor.y.a < p.b + r) { + dragging_a = p.a + dragging_b = p.b + dragging = p + return true + } + }) + }, + drag: function(e, cursor){ + if (! dragging) return + delta = cursor.delta() + delta.a = - delta.a + dragging.a = dragging_a + delta.a + dragging.b = dragging_b + delta.b + }, + up: function(e, cursor, new_cursor){ + delta.zero() + dragging.dragging = false + dragging = false + }, +}) + +function draw () { + ctx.fillStyle = "#fff" + ctx.fillRect(0,0,w,h) + + Rooms.forEach(function(room, i){ + ctx.fillStyle = "#eee" + ctx.fillRect(room.rect.x.a, room.rect.y.a, room.rect.width(), room.rect.height()) + }) + + ctx.fillStyle = "#333" + points.forEach(drawPoint) + + drawLine(cursor.x, cursor.y, "#f00") + hud.innerHTML = "" + Walls.list.forEach(function(wall, i){ + if (wall.side & LEFT_RIGHT) { + wall_vec.x.a = wall.edge + wall_vec.x.b = wall.vec.a + wall_vec.y.a = wall.edge + wall_vec.y.b = wall.vec.b + } + else { + wall_vec.x.a = wall.vec.a + wall_vec.x.b = wall.edge + wall_vec.y.a = wall.vec.b + wall_vec.y.b = wall.edge + } + drawLine(wall_vec.x, wall_vec.y, "#888", true) + drawLine(origins.x, origins.y, "rgba(0,0,0,0.1)") + + var t = perp(origins, wall_vec) / ( perp(cursor, wall_vec) || 0.0000001 ) + intersect.a = cursor.x.a + ( cursor.y.a - cursor.x.a ) * t + intersect.b = cursor.x.b + ( cursor.y.b - cursor.x.b ) * t + + var collinear = is_collinear( intersect, wall_vec ) + var long_enough_to_intersect = 0 <= t && t <= 1 + var actually_intersects = false + var intersecting_face + var msg + + if (long_enough_to_intersect && collinear) { + if (wall.side & LEFT_RIGHT) { + intersecting_face = wall.surface.face_for_x(intersect.b) + } + else { + intersecting_face = wall.surface.face_for_x(intersect.a) + } + actually_intersects = !! (intersecting_face && intersecting_face.y.a == 0) + } + + if (actually_intersects) { + ctx.fillStyle = "#f00" + msg = "through" + } + else if (collinear) { + ctx.fillStyle = "#0f0" + msg = "to" + } + else { + ctx.fillStyle = "rgba(0,0,0,0.1)" + msg = "off" + } + + drawPoint(intersect) + if (intersecting_face) { + hud.innerHTML += intersecting_face.y.a + "<br>" + } + }) + +} +function drawLine (pa, pb, color, headless) { + ctx.fillStyle = color + ctx.strokeStyle = color + var x1 = pa.a + var y1 = pa.b + var x2 = pb.a + var y2 = pb.b + drawArrow(ctx, x1, y1, x2, y2, 3, headless ? 0 : 1) +} +function drawPoint (p) { + var x = p.a - r + var y = p.b - r + ctx.fillRect(x, y, r*2, r*2) +} +function perp (va, vb) { + return (va.y.a - va.x.a) * (vb.y.b - vb.x.b) - (va.y.b - va.x.b) * (vb.y.a - vb.x.a) +} +function is_collinear (p, vec) { + var on_x, on_y + var pa = round(p.a), pb = round(p.b) + + if (vec.x.a < vec.y.a) { + on_x = vec.x.a <= pa && pa <= vec.y.a + } + else { + on_x = vec.x.a >= pa && pa >= vec.y.a + } + + if (vec.x.b < vec.y.b) { + on_y = vec.x.b <= pb && pb <= vec.y.b + } + else { + on_y = vec.x.b >= pb && pb >= vec.y.b + } + + return !! (on_x && on_y) +} + +function animate(){ + requestAnimationFrame(animate) + draw() +} +animate() + +</script> |
