如何通过设置操作组合形状?

时间:2019-05-22 23:37:59

标签: haskell haskell-diagrams

我想从另一个形状中减去一个形状,然后将所得形状与另一个形状组合。在我的示例中,正方形将被裁剪成两半,而裁剪后的版本将被向右扩展半圈。 因此,我通过difference从另一个正方形中减去一个正方形,并假设整个重叠区域将合并,从而使整个圆成为union。 我在考虑集合操作,其中({1,2,3,4} / {3,4}) U {2,3}等于{1,2,3},但在我的实现中,它等于{1,3}

import Diagrams.Backend.SVG.CmdLine

{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleContexts          #-}
{-# LANGUAGE TypeFamilies              #-}

import Diagrams.Prelude
import qualified Diagrams.TwoD.Path.Boolean as B

main = mainWith (combination # fc red # bgFrame 0.1 white)
  where
    combination :: QDiagram B V2 Double Any
    combination = strokePath plusCircle
    shorterSquare = B.difference Winding (square 2) (square 2 # translateX 1)

    plusCircle = B.union Winding (circle 1 <> shorterSquare)

但是我明白了:enter image description here 这不是我想要的,我希望将半圆与矩形合并,然后将结果填充为红色,内部没有任何行。

2 个答案:

答案 0 :(得分:4)

B.difference的这种特殊用法会颠倒shorterSquare路径的方向,因此您需要re-reverse it

shorterSquare = B.difference Winding (square 2) (square 2 # translateX 1)
    # reversePath

由于这很微妙,值得花点时间描述我如何诊断它。首先,这种填充规则的古怪感觉很像是由路径(或面部等)方向引起的问题。其次,将shorterSquare重新定义为...

shorterSquare = square 2 # scaleX 0.5 # translateX 0.5

...给出预期的结果。这意味着问题与B.differenceshorterSquare的定义有关,而不是与B.union有关。可以通过pathVertices获得确认:

GHCi> -- Counterclockwise.
GHCi> pathVertices $ square 2 # scaleX 0.5 # translateX 0.5
[[P (V2 1.0 (-1.0)),P (V2 0.9999999999999999 1.0),P (V2 (-1.1102230246251565e-16) 1.0),P (V2 (-2.220446049250313e-16) (-1.0))]]
GHCi> -- Clockwise.
GHCi> pathVertices $ B.difference Winding (square 2) (square 2 # translateX 1)
[[P (V2 (-1.0) 1.0),P (V2 0.0 1.0),P (V2 0.0 (-1.0)),P (V2 (-1.0) (-1.0))]]

答案 1 :(得分:1)

我不是图形专家,但是您似乎正在组合笔触路径而不是它们所代表的形状。 Fill Rules有一些有趣的事情要说,“缠绕填充”规则对于重叠的笔触路径的行为方式,这似乎与解释为什么获得结果的原因有关。

相反,我建议使用Composing diagrams中的技术(例如atop)来构成完整的形状。