Haskell Diagrams如何实现固定四向出入的节点连接箭头
问题原因
你当前的shaft函数硬编码了贝塞尔曲线终点为水平方向的r2 (3, 0),而connect'默认会自动对shaft做缩放、旋转以匹配两个节点中心的连线方向,因此节点垂直排列时整个箭头被旋转90度,进出方向不符合要求。
解决方法
优先使用diagrams内置的connectPerim'接口,它原生支持指定两个节点的连接进出方向,不需要手动适配节点排列方式:
完整实现代码
import Diagrams.Prelude import Diagrams.Backend.SVG.CmdLine data Dir = N | S | E | W deriving (Eq, Ord, Show) cir, circlesH, circlesV :: Diagram B cir = circle 0.3 # showOrigin # lw thick -- 水平排列节点 circlesH = (cir # named "1") ||| strutX 3 ||| (cir # named "2") -- 垂直排列节点 circlesV = (cir # named "1") === strutY 3 === (cir # named "2") -- 方向对应的圆周角度 dirAngle :: Dir -> Angle Double dirAngle N = 90 @@ deg dirAngle S = 270 @@ deg dirAngle E = 0 @@ deg dirAngle W = 180 @@ deg -- 自定义箭头杆:贝塞尔曲线弯曲样式 bentShaft :: Trail V2 Double bentShaft = trailFromSegments [bézier3 (r2 (0, 1)) (r2 (0, -1)) (r2 (1, 0))] # scaleUToX 1 -- 按指定进出方向连接两个节点 connectDir :: Dir -> Dir -> String -> String -> Diagram B -> Diagram B connectDir outDir inDir n1 n2 = connectPerim' opts n1 n2 (dirAngle outDir) (dirAngle inDir) where opts = with & arrowShaft .~ bentShaft & lw thick -- 水平排列测试 exampleH :: Diagram B exampleH = circlesH # connectDir N S "1" "2" -- 垂直排列测试 exampleV :: Diagram B exampleV = circlesV # connectDir N S "1" "2"
上述实现不管节点是水平、垂直还是任意位置摆放,都可以保证箭头严格从指定的N/S/E/W四个正方向进出节点,不需要修改箭头杆的逻辑。
内容的提问来源于stack exchange,提问作者cdupont
相关产品推荐
相关产品推荐

