Wiresheet: make the last wire turn 1.5 grid before the target arrow
The final vertical run into an input slot now stands at least 1.5 * GRID_SIZE in front of the box, so the arrowhead sits on a straight run instead of on the bend. Column gaps in tidy layout widen to match. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -8,7 +8,7 @@ so later rebinding would only ever be seen by the module that did it.
|
||||
import configparser
|
||||
import os
|
||||
|
||||
VERSION = "0.0.0.148"
|
||||
VERSION = "0.0.0.149"
|
||||
PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties")
|
||||
DEFAULT_GRID_SIZE = 10
|
||||
DEFAULT_ADD_TIMESTAMP = True
|
||||
|
||||
+28
-13
@@ -33,6 +33,10 @@ WIRE_LANE_GAP = 6
|
||||
# knobs, the same way a link leaving the sheet is.
|
||||
WIRE_STANDOFF_MAX = 60
|
||||
|
||||
# The last turn before a target slot is kept this many grid squares back from the box,
|
||||
# so the arrowhead always sits on a straight run of its own instead of on the bend.
|
||||
ARRIVE_TURN_GRIDS = 1.5
|
||||
|
||||
# Two different wires running horizontally at the same height are indistinguishable, so
|
||||
# a free horizontal lane is nudged until it clears any other wire's by this much. The
|
||||
# short stubs joining a slot cannot move -- they have to meet their pin -- so a fan-out
|
||||
@@ -315,6 +319,11 @@ def vertical_run_clearance(cx, y1, y2, boxes):
|
||||
return nearest
|
||||
|
||||
|
||||
def arrive_turn():
|
||||
"""How far in front of a target box the wire makes its last turn, at 1:1."""
|
||||
return max(WIRE_HUG, ARRIVE_TURN_GRIDS * app_state.GRID_SIZE)
|
||||
|
||||
|
||||
def channel_candidates(src_box, dst_box, boxes, low, high):
|
||||
"""Vertical channel positions to try, best first.
|
||||
|
||||
@@ -322,7 +331,7 @@ def channel_candidates(src_box, dst_box, boxes, low, high):
|
||||
that a vertical line stays within WIRE_HUG of a component. The midpoint of the gap
|
||||
is kept only as a last resort, for when every hug position is blocked.
|
||||
"""
|
||||
ordered = [src_box[2] + WIRE_HUG, dst_box[0] - WIRE_HUG]
|
||||
ordered = [src_box[2] + WIRE_HUG, dst_box[0] - arrive_turn()]
|
||||
for bx1, _, bx2, _ in boxes:
|
||||
ordered.append(bx2 + WIRE_HUG)
|
||||
ordered.append(bx1 - WIRE_HUG)
|
||||
@@ -362,18 +371,22 @@ def free_lane(cx, run_lo, run_hi, boxes, taken, low, high, max_steps=8):
|
||||
return None
|
||||
|
||||
|
||||
def hug_lane(edge_x, side, run_lo, run_hi, boxes, claimed, max_offset=WIRE_HUG):
|
||||
def hug_lane(edge_x, side, run_lo, run_hi, boxes, claimed, max_offset=WIRE_HUG,
|
||||
min_offset=WIRE_MIN_CLEAR):
|
||||
"""Lane for a run pinned to one box edge, starting WIRE_MIN_CLEAR out from it.
|
||||
|
||||
`side` is +1 for a run leaving a box's right edge, -1 for one entering its left
|
||||
edge. Offsets inside the hug band are offered first, furthest out of the band
|
||||
first so the run keeps clear of its own box; only when every one of those is taken
|
||||
does it reach past WIRE_HUG, out to `max_offset`. Returns None when nothing up to
|
||||
that limit clears both the boxes and the runs already placed.
|
||||
that limit clears both the boxes and the runs already placed. `min_offset` raises
|
||||
the floor, and the hug position with it, for a run that must stand further off.
|
||||
"""
|
||||
offsets = list(range(WIRE_HUG, WIRE_MIN_CLEAR - 1, -1))
|
||||
if max_offset > WIRE_HUG:
|
||||
offsets += list(range(WIRE_HUG + 1, int(max_offset) + 1))
|
||||
floor = max(WIRE_MIN_CLEAR, int(math.ceil(min_offset)))
|
||||
hug = max(WIRE_HUG, floor)
|
||||
offsets = list(range(hug, floor - 1, -1))
|
||||
if max_offset > hug:
|
||||
offsets += list(range(hug + 1, int(max_offset) + 1))
|
||||
|
||||
for offset in offsets:
|
||||
lane = edge_x + side * offset
|
||||
@@ -437,7 +450,8 @@ def route_link_path(src_box, src_y, dst_box, dst_y, boxes, taken=None,
|
||||
start = (src_box[2], src_y)
|
||||
end = (dst_box[0], dst_y)
|
||||
leave = (start[0] + LINK_STUB, src_y)
|
||||
arrive = (end[0] - LINK_STUB, dst_y)
|
||||
# The last turn stands arrive_turn() in front of the target, never closer.
|
||||
arrive = (end[0] - max(LINK_STUB, arrive_turn()), dst_y)
|
||||
|
||||
low, high = min(leave[0], arrive[0]), max(leave[0], arrive[0])
|
||||
run_lo, run_hi = min(src_y, dst_y), max(src_y, dst_y)
|
||||
@@ -509,7 +523,8 @@ def route_link_path(src_box, src_y, dst_box, dst_y, boxes, taken=None,
|
||||
continue
|
||||
in_x = hug_lane(dst_box[0], -1, min(base_cy, dst_y), max(base_cy, dst_y),
|
||||
boxes, claimed + [(out_x, min(src_y, base_cy),
|
||||
max(src_y, base_cy))], max_offset)
|
||||
max(src_y, base_cy))], max_offset,
|
||||
min_offset=arrive_turn())
|
||||
if in_x is None:
|
||||
continue
|
||||
|
||||
@@ -1205,12 +1220,12 @@ def wire_demand_by_boundary(column_of_comp):
|
||||
def column_gap_for(run_count):
|
||||
"""Clear space a column gap needs to carry `run_count` vertical wire runs.
|
||||
|
||||
Lanes start WIRE_MIN_CLEAR in from either box edge and stand WIRE_LANE_GAP apart, so
|
||||
n of them span 2 * WIRE_MIN_CLEAR + (n - 1) * WIRE_LANE_GAP. One or two runs already
|
||||
fit inside the plain TIDY_GAP -- at 10 and 20 across a 30px gap, both still hugging
|
||||
a box -- which is why the great majority of gaps stay at exactly TIDY_GAP.
|
||||
Lanes start WIRE_MIN_CLEAR out from the source box and arrive_turn() in front of
|
||||
the target box, and stand WIRE_LANE_GAP apart, so n of them span
|
||||
WIRE_MIN_CLEAR + arrive_turn() + (n - 1) * WIRE_LANE_GAP.
|
||||
"""
|
||||
return max(TIDY_GAP, 2 * WIRE_MIN_CLEAR + max(0, run_count - 1) * WIRE_LANE_GAP)
|
||||
return max(TIDY_GAP, WIRE_MIN_CLEAR + arrive_turn()
|
||||
+ max(0, run_count - 1) * WIRE_LANE_GAP)
|
||||
|
||||
|
||||
def plan_columns(columns, column_keys, demand, scale):
|
||||
|
||||
Reference in New Issue
Block a user