You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell Diagrams疑问:envelope为何不默认采用边界框?

问题与解决方案

问题详情

我编写了这段代码:

(square 10 ||| square 10 ||| square 10 ) `atop` square 30

预期三个小方块能整齐嵌入大方块,效果如下:

+-----------------+
|                 |
|                 |
+-----+-----+-----+
|     |     |     |
|     |     |     |
+-----+-----+-----+
|                 |
|                 |
+-----------------+

但实际显示里,小方块整体右移10个单位:最左侧小方块在大方块中心,中间小方块右边缘和大方块右边缘重合,最右侧小方块直接超出大方块,实际效果是:

+-----------------+
|                 |
|                 |
|     +-----+-----+-----+
|     |     |     |     |
|     |     |     |     |
|     +-----+-----+-----+
|                 |
|                 |
+-----------------+

我原本以为应该用类似这样的代码解决:

(square 10 ||| square 10 ||| square 10 ) # setEnvelopeToBoundingBox `atop` square 30

但找不到setEnvelopeToBoundingBox这类方法,而且觉得不该这么复杂。试过用平移解决,但需求变复杂后完全没法维护。

解决办法

这是diagrams库的默认行为导致的:|||水平拼接后的组合图形,原点默认落在第一个小方块的中心,而atop是将上层图形的原点与下层大方块的原点对齐,所以才会出现整体偏移。

只需要给拼接后的小方块组合加上居中调整,就能实现预期效果:

水平居中(匹配预期效果)

(square 10 ||| square 10 ||| square 10) # centerX `atop` square 30

整体居中(水平+垂直)

如果需要小方块在大方块中同时垂直居中,用center替换centerX即可:

(square 10 ||| square 10 ||| square 10) # center `atop` square 30

另外,diagrams提供了一系列对齐函数,比如alignL(左对齐)、alignR(右对齐)、alignT(顶部对齐)、alignB(底部对齐),可以根据不同布局需求灵活使用,比手动平移更易维护。

内容的提问来源于stack exchange,提问作者Adrian May

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:36:22