Skip to content

Commit

Permalink
Merge pull request #260 from zxcalc/multigraph-self-loop
Browse files Browse the repository at this point in the history
Multigraph self loop support
  • Loading branch information
RazinShaikh authored Jun 27, 2024
2 parents 9288a9a + 740f98c commit b4bd8ab
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 11 deletions.
24 changes: 17 additions & 7 deletions zxlive/eitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,21 @@ def refresh(self) -> None:
self.setPen(QPen(pen))

path = QPainterPath()
control_point = calculate_control_point(self.s_item.pos(), self.t_item.pos(), self.curve_distance)
path.moveTo(self.s_item.pos())
path.quadTo(control_point, self.t_item.pos())
if self.s_item == self.t_item: # self-loop
cd = self.curve_distance
cd = cd + 0.5 if cd >= 0 else cd - 0.5
s_pos = self.s_item.pos()
path.moveTo(s_pos)
path.cubicTo(s_pos + QPointF(1, -1) * cd * SCALE,
s_pos + QPointF(-1, -1) * cd * SCALE,
s_pos)
curve_midpoint = s_pos + QPointF(0, -0.75) * cd * SCALE
else:
control_point = calculate_control_point(self.s_item.pos(), self.t_item.pos(), self.curve_distance)
path.moveTo(self.s_item.pos())
path.quadTo(control_point, self.t_item.pos())
curve_midpoint = self.s_item.pos() * 0.25 + control_point * 0.5 + self.t_item.pos() * 0.25
self.setPath(path)

curve_midpoint = self.s_item.pos() * 0.25 + control_point * 0.5 + self.t_item.pos() * 0.25
self.selection_node.setPos(curve_midpoint.x(), curve_midpoint.y())
self.selection_node.setVisible(self.isSelected())

Expand Down Expand Up @@ -142,10 +151,11 @@ def refresh(self) -> None:
path.lineTo(self.mouse_pos)
self.setPath(path)

def calculate_control_point(source_pos, target_pos, curve_distance):
def calculate_control_point(source_pos: QPointF, target_pos: QPointF, curve_distance: float):
"""Calculate the control point for the curve"""
direction = target_pos - source_pos
direction /= sqrt(direction.x()**2 + direction.y()**2) # Normalize the direction
norm = sqrt(direction.x()**2 + direction.y()**2)
direction = direction / norm
perpendicular = QPointF(-direction.y(), direction.x())
midpoint = (source_pos + target_pos) / 2
offset = perpendicular * curve_distance * SCALE
Expand Down
5 changes: 1 addition & 4 deletions zxlive/graphscene.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,6 @@ def add_edge(self, e: QGraphicsSceneMouseEvent) -> None:
assert self._drag is not None
self.removeItem(self._drag)
for it in self.items(e.scenePos(), deviceTransform=QTransform()):
# TODO: Think about if we want to allow self loops here?
# For example, if had edge is selected this would mean that
# right clicking adds pi to the phase...
if isinstance(it, VItem) and it != self._drag.start:
if isinstance(it, VItem):
self.edge_added.emit(self._drag.start.v, it.v)
self._drag = None

0 comments on commit b4bd8ab

Please sign in to comment.