def get_xyz_mouse_click(event, ax): """ Get coordinates clicked by user """ if ax.M is None: return {} xd, yd = event.xdata, event.ydata p = (xd, yd) edges = ax.tunit_edges() ldists = [(proj3d._line2d_seg_dist(p0, p1, p), i) for \ i, (p0, p1) in enumerate(edges)] ldists.sort() # nearest edge edgei = ldists[0][1] p0, p1 = edges[edgei] # scale the z value to match x0, y0, z0 = p0 x1, y1, z1 = p1 d0 = sqrt(pow(x0 - xd, 2) + pow(y0 - yd, 2)) d1 = sqrt(pow(x1 - xd, 2) + pow(y1 - yd, 2)) dt = d0 + d1 z = d1 / dt * z0 + d0 / dt * z1 x, y, z = proj3d.inv_transform(xd, yd, z, ax.M) return x, y, z
def test_lines_dists(): fig, ax = plt.subplots(figsize=(4, 6), subplot_kw=dict(aspect='equal')) xs = (0, 30) ys = (20, 150) ax.plot(xs, ys) p0, p1 = zip(xs, ys) xs = (0, 0, 20, 30) ys = (100, 150, 30, 200) ax.scatter(xs, ys) dist = proj3d._line2d_seg_dist(p0, p1, (xs[0], ys[0])) dist = proj3d._line2d_seg_dist(p0, p1, np.array((xs, ys))) for x, y, d in zip(xs, ys, dist): c = Circle((x, y), d, fill=0) ax.add_patch(c) ax.set_xlim(-50, 150) ax.set_ylim(0, 300)