function dist_btwn_pts(pt1, pt2) { return Math.pow(Math.pow(pt1.x - pt2.x,2) + Math.pow(pt1.y - pt2.y,2) , 0.5); } function angle_btwn_lines(line1, line2){ var vector1 = {x: line1.x2 - line1.x1, y: line1.y2 - line1.y1}; var vector2 = {x: line2.x2 - line2.x1, y: line2.y2 - line2.y1}; var angle = (Math.atan2(vector2.y, vector2.x) - Math.atan2(vector1.y, vector1.x)); if (angle < 0) { angle = angle + 2 * Math.PI; } return angle; } function btwn(a, b1, b2) { var tol = 1e-6; if ((a >= b1 - tol) && (a <= b2 + tol)) { return true; } if ((a >= b2 - tol) && (a <= b1 + tol)) { return true; } return false; } function line_line_intersect(line1, line2) { var x1 = line1.x1, x2 = line1.x2, x3 = line2.x1, x4 = line2.x2; var y1 = line1.y1, y2 = line1.y2, y3 = line2.y1, y4 = line2.y2; var pt_denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); var pt_x_num = (x1*y2 - y1*x2) * (x3 - x4) - (x1 - x2) * (x3*y4 - y3*x4); var pt_y_num = (x1*y2 - y1*x2) * (y3 - y4) - (y1 - y2) * (x3*y4 - y3*x4); if (pt_denom == 0) { return "parallel"; } else { var pt = {'x': pt_x_num / pt_denom, 'y': pt_y_num / pt_denom}; if (btwn(pt.x, x1, x2) && btwn(pt.y, y1, y2) && btwn(pt.x, x3, x4) && btwn(pt.y, y3, y4)) { return pt; } else { return "not in range"; } } } function path_line_intersections(pathEl, line2, n_segments) { var pts = []; var int_line_segs = []; for (var i=0; i 0) { var distances = int_pts_and_segs.map(function(pt) { return dist_btwn_pts(start_pt, pt[0]); }); var min_pt = d3.zip(int_pts_and_segs,distances).sort(function(a,b){ return a[1] - b[1]; })[0][0]; return min_pt; } else { return 'none'; } } function compute_reflection(pt, angle, int_seg ) { var pt2 = {x: pt.x + int_seg.x2 - int_seg.x1, y: pt.y + int_seg.y2 - int_seg.y1} var rot_pt_x = pt.x + (pt2.x - pt.x) * Math.cos(angle) - (pt2.y - pt.y) * Math.sin(angle); var rot_pt_y = pt.y + (pt2.x - pt.x) * Math.sin(angle) + (pt2.y - pt.y) * Math.cos(angle); var l = dist_btwn_pts(pt, pt2); return { dx: (rot_pt_x - pt.x ) / l, dy: (rot_pt_y - pt.y) / l }; }