// Generated by CoffeeScript 1.10.0 (function() { var closest, drag, get_closest, height, lines_data, lines_layer, perpendicular, points_data, points_layer, redraw, result_layer, svg, width; get_closest = function(A, B, P) { var C, a_to_b, a_to_p, atb2, atp_dot_atb, maxx, maxy, minx, miny, ref, ref1, t; a_to_p = [P.x - A.x, P.y - A.y]; a_to_b = [B.x - A.x, B.y - A.y]; atb2 = a_to_b[0] * a_to_b[0] + a_to_b[1] * a_to_b[1]; atp_dot_atb = a_to_p[0] * a_to_b[0] + a_to_p[1] * a_to_b[1]; t = atp_dot_atb / atb2; C = { x: A.x + a_to_b[0] * t, y: A.y + a_to_b[1] * t }; minx = Math.min(A.x, B.x); maxx = Math.max(A.x, B.x); miny = Math.min(A.y, B.y); maxy = Math.max(A.y, B.y); if ((minx <= (ref = C.x) && ref <= maxx) && (miny <= (ref1 = C.y) && ref1 <= maxy)) { return C; } else { return null; } }; points_data = [ { x: -200, y: 200 }, { x: 200, y: -200 }, { x: 200, y: 200 } ]; lines_data = [ { start: points_data[0], end: points_data[1] } ]; svg = d3.select('svg'); width = svg.node().getBoundingClientRect().width; height = svg.node().getBoundingClientRect().height; svg.attr({ viewBox: (-width / 2) + " " + (-height / 2) + " " + width + " " + height }); drag = d3.behavior.drag().origin(function(d) { return d; }); drag.on('drag', function(d) { d.x = d3.event.x; d.y = d3.event.y; return redraw(); }); lines_layer = svg.append('g'); points_layer = svg.append('g'); result_layer = svg.append('g'); closest = result_layer.append('circle').attr({ "class": 'closest', r: 4 }); perpendicular = lines_layer.append('line').attr({ "class": 'perpendicular' }); redraw = function() { var closest_data, lines, points; lines = lines_layer.selectAll('.line').data(lines_data); lines.enter().append('line').attr({ "class": 'line' }); lines.attr({ x1: function(l) { return l.start.x; }, y1: function(l) { return l.start.y; }, x2: function(l) { return l.end.x; }, y2: function(l) { return l.end.y; } }); points = points_layer.selectAll('.point').data(points_data); points.enter().append('circle').call(drag).attr({ "class": 'point', r: 8 }); points.attr({ cx: function(p) { return p.x; }, cy: function(p) { return p.y; } }); closest_data = get_closest(points_data[0], points_data[1], points_data[2]); closest.attr({ cx: closest_data != null ? closest_data.x : 0, cy: closest_data != null ? closest_data.y : 0, display: closest_data != null ? 'inline' : 'none' }); return perpendicular.attr({ x1: points_data[2].x, y1: points_data[2].y, x2: closest_data != null ? closest_data.x : 0, y2: closest_data != null ? closest_data.y : 0, display: closest_data != null ? 'inline' : 'none' }); }; redraw(); }).call(this);