haskell - Haskell 图:方向固定的箭头
问题描述
我需要在两个任意“节点”之间绘制箭头。箭头末端需要从四个基本方向之一进入或退出节点:N、S、E、W。
data Dir = N | S | E | W
deriving (Eq, Ord, Show)
cir, circles :: Diagram B
cir = circle 0.3 # showOrigin # lw thick
circles = (cir # named "1") ||| strutX 3 ||| (cir # named "2")
ctrlPoint :: Dir -> V2 Double
ctrlPoint N = r2 (0, 1)
ctrlPoint S = r2 (0, -1)
ctrlPoint E = r2 (1, 0)
ctrlPoint W = r2 (-1, 0)
-- This function should specify an arrow shaft entering nodes from directions dir1 and dir2
shaft :: Dir -> Dir -> Trail V2 Double
shaft dir1 dir2 = trailFromSegments [bézier3 (controlPoint dir1) (controlPoint dir2) (r2 (3, 0))]
example = circles # connect' (with ... & arrowShaft .~ shaft N S ) "1" "2"
在上图中,箭头在第一个圆圈中从北正确进入,在第二个圆圈中从南进入。但是,如果我垂直设置点,一切都会旋转:
circles = (cir # named "1") === strutY 3 === (cir # named "2")
这是不正确的,因为我希望箭头分别从北和南进入。似乎箭头的轴完全旋转了......如何编写我的函数shaft :: Dir -> Dir -> Trail V2 Double
?谢谢
解决方案
我找到了一个答案arrowFromLocatedTrail'
:
-- control points for bézier curves
control :: Dir -> V2 Double
control N = r2 (0, 0.5)
control S = r2 (0, -0.5)
control E = r2 (0.5, 0)
control W = r2 (-0.5, 0)
-- shaft of arrows
shaft :: (P2 Double, Dir) -> (P2 Double, Dir) -> Located (Trail V2 Double)
shaft (p, d) (p', d') = trailFromSegments [bézier3 (control d) ((p' .-. p) - (control d')) (p' .-. p)] `at` p
-- create a single arrow
mkArrow :: (P2 Double, Dir) -> (P2 Double, Dir) -> Diagram B
mkArrow a b = arrowFromLocatedTrail' (with & arrowHead .~ dart
& lengths .~ veryLarge
& shaftStyle %~ lw thick) (shaft a b)
此版本执行必要的转换:
bézier3 (control d) ((p' .-. p) + (control d')) (p' .-. p)
这是 的签名bézier
:
bézier3 :: v n -> v n -> v n -> Segment Closed v n
它需要 3 个向量,此处命名为 V1、V2 和 V3。贝塞尔曲线默认不在图表中,它们只是指定如何移动。
因此,为了绘制贝塞尔曲线,我们设置:
V1 = control d
V2 = (p' .-. p) + (control d')
V3 = p' .-. p
生成的贝塞尔曲线将位于at
p。
推荐阅读
- createjs - CreateJS 使 Cache Empty 不断占用内存?
- python - 如何在 python 中从 MultiIndexed pandas 数据框创建数组树
- php - Symfony 4 骨架,调用 php binance api 和 php binance api 速率限制器时出错
- javascript - 使用 Webpack 构建静态站点生成器
- scala - Intellij - 工作表找不到类
- c - C 是否需要堆栈和堆才能运行?
- html - 我可以仅使用 CSS 在悬停时定位此元素吗?
- c# - 如何在 MVC 模型中操作字符串
- node.js - 单击按钮时,数字加 1
- python - 如何使用电子邮件将传感器数据发送给用户