Commit d0db0dca191c933df781831dcec15e5ab27d73db

Authored by tfmoraes
1 parent 179e4893

ENH: Improved the function that verifies if the user clicked in the line in the …

…clut widget raycasting
Showing 1 changed file with 26 additions and 11 deletions   Show diff stats
invesalius/gui/widgets/clut_raycasting.py
@@ -111,7 +111,6 @@ class CLUTRaycastingWidget(wx.Panel): @@ -111,7 +111,6 @@ class CLUTRaycastingWidget(wx.Panel):
111 return 111 return
112 curve = self._has_clicked_in_selection_curve((x, y)) 112 curve = self._has_clicked_in_selection_curve((x, y))
113 if curve is not None: 113 if curve is not None:
114 - print "Selecionou a curva", curve  
115 self.dragged = True 114 self.dragged = True
116 self.previous_wl = x 115 self.previous_wl = x
117 self.curve_dragged = curve 116 self.curve_dragged = curve
@@ -299,6 +298,23 @@ class CLUTRaycastingWidget(wx.Panel): @@ -299,6 +298,23 @@ class CLUTRaycastingWidget(wx.Panel):
299 return (i, j) 298 return (i, j)
300 return None 299 return None
301 300
  301 + def distance_from_point_line(self, p1, p2, pc):
  302 + """
  303 + Calculate the distance from point pc to a line formed by p1 and p2.
  304 + """
  305 + # Create a vector pc-p1 and p2-p1
  306 + A = numpy.array(pc) - numpy.array(p1)
  307 + B = numpy.array(p2) - numpy.array(p1)
  308 + # Calculate the size from those vectors
  309 + len_A = numpy.linalg.norm(A)
  310 + len_B = numpy.linalg.norm(B)
  311 + # calculate the angle (in radians) between those vector
  312 + theta = math.acos(numpy.dot(A, B) / (len_A * len_B))
  313 + # Using the sin from theta, calculate the adjacent leg, which is the
  314 + # distance from the point to the line
  315 + distance = math.sin(theta) * len_A
  316 + return distance
  317 +
302 def _has_clicked_in_selection_curve(self, position): 318 def _has_clicked_in_selection_curve(self, position):
303 x, y = position 319 x, y = position
304 for i, curve in enumerate(self.curves): 320 for i, curve in enumerate(self.curves):
@@ -306,20 +322,19 @@ class CLUTRaycastingWidget(wx.Panel): @@ -306,20 +322,19 @@ class CLUTRaycastingWidget(wx.Panel):
306 return i 322 return i
307 return None 323 return None
308 324
309 - def _has_clicked_in_line(self, position): 325 + def _has_clicked_in_line(self, clicked_point):
310 """ 326 """
311 Verify if was clicked in a line. If yes, it returns the insertion 327 Verify if was clicked in a line. If yes, it returns the insertion
312 - position in the point list. 328 + clicked_point in the point list.
313 """ 329 """
314 for n, curve in enumerate(self.curves): 330 for n, curve in enumerate(self.curves):
315 - p = bisect.bisect([node.x for node in curve.nodes], position[0])  
316 - print p  
317 - if p != 0 and p != len(curve.nodes):  
318 - x1, y1 = curve.nodes[p-1].x, curve.nodes[p-1].y  
319 - x2, y2 = position  
320 - x3, y3 = curve.nodes[p].x, curve.nodes[p].y  
321 - if int(float(x2 - x1) / (x3 - x2)) - int(float(y2 - y1) / (y3 - y2)) == 0:  
322 - return (n, p) 331 + position = bisect.bisect([node.x for node in curve.nodes],
  332 + clicked_point[0])
  333 + if position != 0 and position != len(curve.nodes):
  334 + p1 = curve.nodes[position-1].x, curve.nodes[position-1].y
  335 + p2 = curve.nodes[position].x, curve.nodes[position].y
  336 + if self.distance_from_point_line(p1, p2, clicked_point) <= 5:
  337 + return (n, position)
323 return None 338 return None
324 339
325 def _calculate_distance(self, p1, p2): 340 def _calculate_distance(self, p1, p2):