def redraw_link(self, instance=None, value=None): root = App.get_running_app().root if root is not None: root.canvas.after.remove_group(str(self.uid)) if self.linked_to_object is not None: # find out the vectors for the keyboard (in objects (its) co-ordinates) a = Vector(*self.center) b = Vector(a[0], a[1]+10) v = b-a vup = v.rotate(self.rotation) #vl = vup.rotate(90) # rotation is anti-clockwise #vr = vup.rotate(-90) # rotation is anti-clockwise vup = vup.normalize() #vl = vl.normalize() #vr = vr.normalize() center = a up_half = vup*self.size[1]/2*self.scale #left_half = vl*self.size[0]/2*self.scale #right_half = -left_half # positions representing the object, have to use vectors, as otherwise pos, etc. gives back the bounding box instead top_center = center + up_half #top_left = center + left_half + up_half #top_right = center + right_half + up_half #bottom_left = center + left_half - up_half #bottom_right = center + right_half - up_half # figure out the vectors for the linked object (in object co-ordinates) la = Vector(*self.linked_to_object.center) lb = Vector(la[0], la[1]+10) lv = lb-la lvup = lv.rotate(self.linked_to_object.rotation) lvl = lvup.rotate(90) # rotation is anti-clockwise #lvr = lvup.rotate(-90) # rotation is anti-clockwise lvup = lvup.normalize() lvl = lvl.normalize() #lvr = lvr.normalize() lcenter = la lup_half = lvup*self.linked_to_object.size[1]/2*self.linked_to_object.scale lleft_half = lvl*self.linked_to_object.size[0]/2*self.linked_to_object.scale lright_half = -lleft_half # positions representing the object, have to use vectors, as otherwise pos, etc. gives back the bounding box instead #ltop_center = lcenter + lup_half #lbottom_center = lcenter - lup_half #lleft_center = lcenter + lleft_half #lright_center = lcenter + lright_half ltop_left = lcenter + lleft_half + lup_half ltop_right = lcenter + lright_half + lup_half lbottom_left = lcenter + lleft_half - lup_half lbottom_right = lcenter + lright_half - lup_half wk_top_center = self.to_window(*top_center) wl_center = self.linked_to_object.to_window(*lcenter) # this is where you can do the code for the intersection testing wl_top_left = self.linked_to_object.to_window(*ltop_left) wl_top_right = self.linked_to_object.to_window(*ltop_right) wl_bottom_left = self.linked_to_object.to_window(*lbottom_left) wl_bottom_right = self.linked_to_object.to_window(*lbottom_right) # quit when we find the first intersection, else quit when at the end shouldDraw = False while True: # bottom line intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_left, wl_bottom_right) if intersects and collinear=="not-collinear": x2, y2 = position shouldDraw = True break # top line intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_top_left, wl_top_right) if intersects and collinear=="not-collinear": x2, y2 = position shouldDraw = True break # right side intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_right, wl_top_right) if intersects and collinear=="not-collinear": x2, y2 = position shouldDraw = True break # left side intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_left, wl_top_left) if intersects and collinear=="not-collinear": x2, y2 = position shouldDraw = True break # default get out of the loop break # only draw, if we have a point to draw to if shouldDraw is True: x1, y1 = wk_top_center if self.draw_arrow_head_on_link is False: with root.canvas.after: Color(*self.link_colour) # main line Line(points=(x1, y1, x2, y2), width=self.link_width, group=str(self.uid)) Color(1,1,1,.1) # main line Line(points=(x1, y1, x2, y2), width=self.link_width/3.0, group=str(self.uid)) else: _a = Vector(x1, y1) _b = Vector(x2, y2) _v = _b-_a _vl = _v.rotate(140) _vl = _vl.normalize() _vr = _v.rotate(-140) _vr = _vr.normalize() end_point_left = _b+_vl*20 end_point_right = _b+_vr*20 with root.canvas.after: Color(*self.link_colour) # main line Line(points=(x1, y1, x2, y2), width=self.link_width, group=str(self.uid)) # left end point Line(points=(end_point_left.x, end_point_left.y, x2, y2), width=self.link_width, group=str(self.uid)) # right end point Line(points=(end_point_right.x, end_point_right.y, x2, y2), width=self.link_width, group=str(self.uid)) Color(1,1,1,.1) # main line Line(points=(x1, y1, x2, y2), width=self.link_width/3.0, group=str(self.uid)) # left end point Line(points=(end_point_left.x, end_point_left.y, x2, y2), width=self.link_width/3.0, group=str(self.uid)) # right end point Line(points=(end_point_right.x, end_point_right.y, x2, y2), width=self.link_width/3.0, group=str(self.uid)) # refresh the scene, which adds the line disconnect button self.refresh()