diff options
| author | Jules Laplace <jules@okfoc.us> | 2015-04-28 20:22:39 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2015-04-28 20:22:39 -0400 |
| commit | 6438a70116adf0516407a55606d859a5c85083d6 (patch) | |
| tree | f65e70d55c3fc2849b355023dac2a58a9ad5c5ff | |
| parent | c0e5a31151dcdbf2b08707fba9008d003d87cd4f (diff) | |
finding closest point and segment
| -rw-r--r-- | public/assets/javascripts/rectangles/engine/map/ui_ortho.js | 10 | ||||
| -rw-r--r-- | public/assets/test/ortho2.html | 4 | ||||
| -rw-r--r-- | public/assets/test/ortho3.html | 135 |
3 files changed, 131 insertions, 18 deletions
diff --git a/public/assets/javascripts/rectangles/engine/map/ui_ortho.js b/public/assets/javascripts/rectangles/engine/map/ui_ortho.js index 0c501ad..2177aaa 100644 --- a/public/assets/javascripts/rectangles/engine/map/ui_ortho.js +++ b/public/assets/javascripts/rectangles/engine/map/ui_ortho.js @@ -30,13 +30,13 @@ Map.UI.Ortho = function(map){ }) var currentTool = "polyline" - base.setTool = function(s){ - currentTool = s + base.add_tool = function(name, tool){ + base.tools[name] = tool } - base.tools = { - polyline: new PolylineTool, - position: new PositionTool, + base.set_tool = function(s){ + currentTool = s } + base.tools = {} base.wheel = new wheel({ el: map.el, diff --git a/public/assets/test/ortho2.html b/public/assets/test/ortho2.html index 49e0308..013c75b 100644 --- a/public/assets/test/ortho2.html +++ b/public/assets/test/ortho2.html @@ -158,6 +158,10 @@ map = new Map ({ height: window.innerHeight, zoom: -2, }) +map.ui.add_tool("arrow", new ArrowTool) +map.ui.add_tool("polyline", new PolylineTool) +map.ui.add_tool("position", new PositionTool) + $(window).resize(function(){ scene.width = window.innerWidth/2 map.canvas.width = map.dimensions.a = window.innerWidth/2 diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html index a41eb8b..467cbec 100644 --- a/public/assets/test/ortho3.html +++ b/public/assets/test/ortho3.html @@ -41,7 +41,7 @@ body { </div> <div class="hud ortho-hud"> - <span class="ion-navigate active" data-role="arrow-mode"></span> + <span class="ion-navigate" data-role="arrow-mode"></span> <span class="ion-ios-pulse active" data-role="polyline-mode"></span> <span class="ion-ios-grid-view-outline" data-role="ortho-polyline-mode"></span> </div> @@ -86,6 +86,32 @@ var MapTool = Fiber.extend(function(base){ return exports }) +var ArrowTool = MapTool.extend(function(base){ + var exports = {} + + exports.move = function(e, cursor){ + last_point.a = cursor.x.a + last_point.b = cursor.y.a + var p + for (var i = 0; i < shapes.length; i++) { + p = shapes[i].hasPointNear(last_point) + if (p) break; + } + + if (p) { + document.body.style.cursor = "pointer" + last_point.assign(line.points[0]) + cursor.x.a = cursor.x.b = last_point.a + cursor.y.a = cursor.y.b = last_point.b + } + else { + document.body.style.cursor = "crosshair" + } + } + + return exports +}) + var PositionTool = MapTool.extend(function(base){ var exports = { down: function(e, cursor){ @@ -127,7 +153,7 @@ var PolylineTool = MapTool.extend(function (base) { // compare to initial point var p = new vec2( cursor.x.a, cursor.y.a ) if (placing) { - if (line.points.length > 2 && line.points[0].distanceTo( p ) < 10/map.zoom) { + if (line.canCloseWith(p)) { line.points.push( line.points[0].clone() ) line.build() placing = false @@ -143,8 +169,9 @@ var PolylineTool = MapTool.extend(function (base) { } } exports.move = function(e, cursor){ - last_point = new vec2( cursor.x.a, cursor.y.a ) - if (placing && line.points.length > 1 && line.points[0].distanceTo( last_point ) < 10/map.zoom) { + last_point.a = cursor.x.a + last_point.b = cursor.y.a + if (placing && line.canCloseWith(last_point)) { document.body.style.cursor = "pointer" last_point.assign(line.points[0]) cursor.x.a = cursor.x.b = last_point.a @@ -157,6 +184,11 @@ var PolylineTool = MapTool.extend(function (base) { return exports }) +var OrthoPolylineTool = MapTool.extend(function (base) { + +}) + + var Polyline = Fiber.extend(function(base){ var exports = {} @@ -170,6 +202,58 @@ var Polyline = Fiber.extend(function(base){ this.points.push( p ) this.mx_points.push( new MX.Point(p) ) } + + exports.canCloseWith = function(p){ + return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom) + } + + exports.hasPointNear = function(p){ + var point + for (var i = 0; i < this.points.length; i++){ + point = this.points[i] + console.log(point.distanceTo( p )) + if (point.distanceTo( p ) < 10/map.zoom) { + return point + } + } + return null + } + + exports.hasSegmentNear = function(p, min_dist){ + var p1, p2, d1, d2, sum, rat + var dx, dy, new_x, new_y, x, y, closest_distance = min_dist || Infinity + var closest_i = -1 + var points = this.points + for (var i = 1; i < points.length; i++) { + d1 = p1.a - p2.a + d2 = p1.b - p2.b + sum = d1*d1 + d2*d2 + rat = ((p.a - p1.a) * d1 + (p.b - p1.b) * d2) / sum + rat = rat < 0 ? 0 : rat < 1 ? rat : 1 + new_x = p1.a + rat * d1 + new_y = p1.b + rat * d2 + dx = new_x - p.a + dy = new_y - p.b + sum2 = sqrt(dx*dx+dy*dy) + if (sum2 < closest_distance) { + x = new_x + y = new_y + closest_distance = sum2 + closest_i = i + } + } + if (closest_i == -1) return null + return { + x: x, + y: y, + distance: closest_distance, + index: closest_i, + } + } + + exports.getSegment = function(i){ + return [ points[i], points[i+1] ] + } exports.draw = function(ctx){ var points = this.points @@ -208,6 +292,9 @@ var Polyline = Fiber.extend(function(base){ this.closed = true shapes.push(this) } + exports.rebuild = function(){ + this.mx.rebuild() + } exports.reset = function(){ this.mx_points.forEach(function(mx){ scene.remove(mx) }) this.points.length = 0 @@ -218,17 +305,28 @@ var Polyline = Fiber.extend(function(base){ MX.Polyline = MX.Object3D.extend({ init: function(polyline){ - var faces = [], points = polyline.points + this.faces = [] + this.points = polyline.points + for (var i = 1; i < this.points.length; i++) { + var mx = new MX.Object3D() + var head = this.points[i-1] + var tail = this.points[i] + face = this.move_face(mx, head, tail) + this.faces.push(face) + scene.add(mx) + } + }, + + rebuild: function(){ for (var i = 1; i < points.length; i++) { + var mx = this.faces[i-1] var head = points[i-1] var tail = points[i] - face = this.add_face(head, tail) - faces.push(face) + this.move_face(mx, head, tail) } }, - add_face: function (head, tail){ - var mx = new MX.Object3D() + move_face: function (mx, head, tail){ var mid_x = (head.a + tail.a) var mid_z = (head.b + tail.b) var len = head.distanceTo( tail ) @@ -243,8 +341,6 @@ MX.Polyline = MX.Object3D.extend({ }) var hue = abs(round( angle / PI * 90 + 300)) mx.el.style.backgroundColor = 'hsl(' + [hue, "100%", "50%"] + ')' - scene.add(mx) - return mx } }) @@ -276,6 +372,11 @@ map = new Map ({ height: window.innerHeight, zoom: -2, }) +map.ui.add_tool("arrow", new ArrowTool) +map.ui.add_tool("polyline", new PolylineTool) +map.ui.add_tool("ortho-polyline", new OrthoPolylineTool) +map.ui.add_tool("position", new PositionTool) + $(window).resize(function(){ scene.width = window.innerWidth/2 map.canvas.width = map.dimensions.a = window.innerWidth/2 @@ -286,7 +387,7 @@ var placing = false var line var shapes = [] var ctx = map.draw.ctx -var last_point +var last_point = new vec2 (0,0) $("#url").on("input", function(){ floorplan.load({ src: this.value }) @@ -300,6 +401,7 @@ var Toolbar = Fiber.extend(function(base){ this.tools = {} } exports.add = function(role, fn){ + var self = this this.tools[role] = fn $("[data-role=" + role + "]", self.rapper).click(function(){ $(".active", self.rapper).removeClass('active') @@ -327,7 +429,14 @@ PerspectiveToolbar.add("keyboard-mode", function(){ }) var OrthographicToolbar = new Toolbar (".ortho-hud") -OrthographicToolbar.add("", function(){ +OrthographicToolbar.add("arrow-mode", function(){ + map.ui.set_tool("arrow") +}) +OrthographicToolbar.add("polyline-mode", function(){ + map.ui.set_tool("polyline") +}) +OrthographicToolbar.add("ortho-polyline-mode", function(){ + map.ui.set_tool("ortho-polyline") }) document.addEventListener('DOMContentLoaded', build) |
