def closest_pt_params_to_ray(self, ray): "" p2, v2 = ray.params # note: at first I wrote self.params() (using method not attr) p1, v1 = self.params # do some math, solve for k in p1 + k * v1 = that point (remember that the vecs can be of any length): # way 1: express p2-p1 as a weighted sum of v1, v2, cross(v1,v2), then take the v1 term in that sum and add it to p1. # way 2: There must be a NumPy function that would just do this in about one step... # way 3: or maybe we can mess around with dot(v1,v2) sort of like in corner_analyzer in demo_polygon... # way 4: or we could google for "closest points on two lines" or so... # way 5: or we could call it the intersection of self with the plane containing p2, and directions v2 and the cross prod, # and use a formula in VQT. Yes, that may not be self-contained but it's fastest to code! v1n = norm(v1) v2n = norm(v2) perp0 = cross(v1n, v2n) if vlen(perp0) < 0.01: ##k btw what if the lines are parallel, in what way should we fail? # and for that matter what if they are *almost* parallel so that we're too sensitive -- do we use an env param # to decide whether to fail in that case too? If we're an Instance we could do that from self.env... #e print "closest_pt_params_to_ray: too sensitive, returning None" ###### teach caller to handle this; let 0.01 be option return None perpn = norm(perp0) perpperp = cross(perpn,v2n) inter = planeXline(p2, perpperp, p1, v1n) # intersect plane (as plane point and normal) with line (as point and vector) if inter is None: print "inter is None (unexpected); data:",p1,v1,p2,v2,perp0 return None # inter is the retval for a variant which just wants the closest point itself, i.e. closest_pt_to_ray return dot(inter - p1, v1n) / vlen(v1)
def closest_pt_params_to_ray(self, ray): "" p2, v2 = ray.params # note: at first I wrote self.params() (using method not attr) p1, v1 = self.params # do some math, solve for k in p1 + k * v1 = that point (remember that the vecs can be of any length): # way 1: express p2-p1 as a weighted sum of v1, v2, cross(v1,v2), then take the v1 term in that sum and add it to p1. # way 2: There must be a NumPy function that would just do this in about one step... # way 3: or maybe we can mess around with dot(v1,v2) sort of like in corner_analyzer in demo_polygon... # way 4: or we could google for "closest points on two lines" or so... # way 5: or we could call it the intersection of self with the plane containing p2, and directions v2 and the cross prod, # and use a formula in VQT. Yes, that may not be self-contained but it's fastest to code! v1n = norm(v1) v2n = norm(v2) perp0 = cross(v1n, v2n) if vlen(perp0) < 0.01: ##k btw what if the lines are parallel, in what way should we fail? # and for that matter what if they are *almost* parallel so that we're too sensitive -- do we use an env param # to decide whether to fail in that case too? If we're an Instance we could do that from self.env... #e print "closest_pt_params_to_ray: too sensitive, returning None" ###### teach caller to handle this; let 0.01 be option return None perpn = norm(perp0) perpperp = cross(perpn, v2n) inter = planeXline( p2, perpperp, p1, v1n ) # intersect plane (as plane point and normal) with line (as point and vector) if inter is None: print "inter is None (unexpected); data:", p1, v1, p2, v2, perp0 return None # inter is the retval for a variant which just wants the closest point itself, i.e. closest_pt_to_ray return dot(inter - p1, v1n) / vlen(v1)
def getHandlePoint(self, hdl, event): p1, p2 = self.glpane.mousepoints(event) rayPoint = p2 rayVector = norm(p2 - p1) ptOnHandle = hdl.center handleNorm = hdl.glpane.lineOfSight hdl_intersection = planeXline(ptOnHandle, handleNorm, rayPoint, rayVector) handlePoint = hdl_intersection return handlePoint
def getHandlePoint(self, hdl, event): p1, p2 = self.glpane.mousepoints(event) rayPoint = p2 rayVector = norm(p2-p1) ptOnHandle = hdl.center handleNorm = hdl.glpane.lineOfSight hdl_intersection = planeXline(ptOnHandle, handleNorm, rayPoint, rayVector) handlePoint = hdl_intersection return handlePoint
def getHandlePoint(self, hdl, event): #First compute the intersection point of the mouseray with the plane #This will be our first self.handle_MovePt upon left down. #This value is further used in handleLeftDrag. -- Ninad 20070531 p1, p2 = self.glpane.mousepoints(event) linePoint = p2 lineVector = norm(p2 - p1) planeAxis = self.getaxis() planeNorm = norm(planeAxis) planePoint = self.center #Find out intersection of the mouseray with the plane. intersection = planeXline(planePoint, planeNorm, linePoint, lineVector) if intersection is None: intersection = ptonline(planePoint, linePoint, lineVector) handlePoint = intersection return handlePoint