def crosses(self, other): """ Returns True if this wire and the |other| wire intersect, False otherwise. """ assert isinstance(other, Wire), 'other must be a Wire' return intersect((self.loc_1, self.loc_2), (other.loc_1, other.loc_2)) != False
def create_wire(canvas, x1, y1, x2, y2, other_wires, directed=True, color=WIRE_COLOR): """ Draws a piece of a wire on the |canvas| pointing from (|x1|, |y1|) to (|x2|, |y2|). The two end points must define a horizontal or vertical line. If the piece intersects any of the |other_wires|, marks the intersections. If |directed| is True, the drawn piece will have an arrow. Returns a list of the canvas ids of the lines the wire is composed of. """ assert isinstance(canvas, Canvas), 'canvas must be a Canvas' assert x1 == x2 or y1 == y2, 'wire piece must be horizontal or vertical' parts = [] if x1 == x2 and y1 == y2: return parts intersection_points = [] for wire in other_wires: for i in xrange(len(wire.path) - 1): intersection = intersect(((x1, y1), (x2, y2)), (wire.path[i], wire.path[i + 1])) if intersection not in (False, 'collinear', (x1, y1), (x2, y2)): intersection_points.append(intersection) intersection_points.sort(key=lambda (x, y): (x - x1) / (x2 - x1) if x1 != x2 else (y - y1) / (y2 - y1)) last_point = (x1, y1) if intersection_points: h = ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5 dx = WIRE_INTERSECT_MARKER_SIZE * (x2 - x1) / h dy = WIRE_INTERSECT_MARKER_SIZE * (y2 - y1) / h for (x, y) in intersection_points: _x, _y = x - dx, y - dy x_, y_ = x + dx, y + dy xm, ym = _x + dx - sqrt(3) * dy, _y + sqrt(3) * dx + dy parts.append(canvas.create_line(last_point, (_x, _y), fill=color, width=WIRE_WIDTH)) parts.append(canvas.create_line(_x, _y, xm, ym, x_, y_, fill=color, width=WIRE_WIDTH, smooth=True)) last_point = (x_, y_) parts.append(canvas.create_line(last_point, (x2, y2), fill=color, width=WIRE_WIDTH)) if directed: wire_angle = atan2(y2 - y1, x2 - x1) arrow_angle_1 = wire_angle + 3 * pi / 4 parts.append(canvas.create_line(x2, y2, x2 + WIRE_ARROW_LENGTH * cos(arrow_angle_1), y2 + WIRE_ARROW_LENGTH * sin(arrow_angle_1), fill=color, width=WIRE_WIDTH)) arrow_angle_2 = wire_angle + 5 * pi / 4 parts.append(canvas.create_line(x2, y2, x2 + WIRE_ARROW_LENGTH * cos(arrow_angle_2), y2 + WIRE_ARROW_LENGTH * sin(arrow_angle_2), fill=color, width=WIRE_WIDTH)) return parts