Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在haskell中接受4个参数的bezier函数_Haskell_Graphics_Haskell Diagrams - Fatal编程技术网

在haskell中接受4个参数的bezier函数

在haskell中接受4个参数的bezier函数,haskell,graphics,haskell-diagrams,Haskell,Graphics,Haskell Diagrams,我正在尝试制作一个需要4个参数的贝塞尔函数: > import Diagrams.Backend.SVG.CmdLine > import Diagrams.Prelude > import Control.Applicative > bezier4 x1 c1 c2 x2 = bezier3 (c1 ^-^ x1) (c2 ^-^ x1) (x2 ^-^ x1) # translate x1 > lineBtwPoints p1 p2 = fromOffsets

我正在尝试制作一个需要4个参数的贝塞尔函数:

> import Diagrams.Backend.SVG.CmdLine
> import Diagrams.Prelude
> import Control.Applicative

> bezier4 x1 c1 c2 x2 = bezier3 (c1 ^-^ x1) (c2 ^-^ x1) (x2 ^-^ x1) # translate x1
> lineBtwPoints p1 p2 = fromOffsets [p2 ^-^ p1] # translate p1
> illustrateBézier x1 c1 c2 x2
>     =  endpt  # translate x1
>     <> endpt  # translate x2
>     <> ctrlpt # translate c1
>     <> ctrlpt # translate c2
>     <> l1
>     <> l2
>     <> fromSegments [bezier4 x1 c1 c2 x2]
>   where
>     dashed  = dashingN [0.03,0.03] 0
>     endpt   = circle 0.05 # fc red  # lw none
>     ctrlpt  = circle 0.05 # fc blue # lw none
>     l1      = lineBtwPoints x1 c1 # dashed
>     l2      =  lineBtwPoints x2 c2 # dashed
>
> x1      = r2 (0.3, 0.5) :: R2
> x2      = r2 (3,-1) :: R2         -- endpoint
> [c1,c2] = map r2 [(1,2), (3,0)]   -- control points
> example = illustrateBézier x1 c1 c2 x2
>导入Diagrams.Backend.SVG.CmdLine
>导入图表。序曲
>导入控制
>bezier4 x1 c1 c2 x2=bezier3(c1^-^x1)(c2^-^x1)(x2^-^x1)#翻译x1
>lineBtwPoints p1 p2=从偏移量[p2^-^p1]#转换p1
>illustrateBézier x1 c1 c2 x2
>=endpt#平移x1
>endpt#翻译为x2
>ctrlpt#翻译c1
>ctrlpt#翻译c2
>l1
>l2
>fromSegments[bezier4 x1 c1 c2 x2]
>在哪里
>虚线=虚线[0.03,0.03]0
>endpt=圆圈0.05#fc红色#lw无
>ctrlpt=圆圈0.05#fc蓝色#lw无
>l1=线B点x1 c1#虚线
>l2=线B点x2 c2#虚线
>
>x1=r2(0.3,0.5)::r2
>x2=r2(3,-1)::r2--端点
>[c1,c2]=地图r2[(1,2)、(3,0)]--控制点
>示例=illustrateBézier x1 c1 c2 x2
但结果似乎不是我想要的:


首先让我们对名称进行寻址。通常,
bezier4
将是给出四次bezier曲线段的函数的名称。更好的名称是
fixedBezier3
,更好的形式是为参数取
点而不是向量。实际上,该函数在
fixedsecgment
数据类型中以
FCubic
的形式存在

如果我们看一下bezier4的类型,就会发现哪里出了问题:

bezier4 x1 c1 c2 x2 = bezier3 (c1 ^-^ x1) (c2 ^-^ x1) (x2 ^-^ x1) # translate x1

ghci> :t bezier4
bezier4'
  :: (Data.Basis.HasBasis v,
      Data.MemoTrie.HasTrie (Data.Basis.Basis v)) =>
     v -> v -> v -> v -> Segment Closed v
重要的一点是,结果是
段闭合v
。读取

分段是平移不变的,也就是说,它们没有特定的属性 “位置”和不受翻译的影响。然而,它们受到了以下因素的影响: 其他变换,例如旋转和缩放

bezier4
末尾的平移不会产生任何效果,因为类型
无法表示具有位置的值,它只表示“形状”和位移。我们可以在GHCi中看到这一点:

ghci> bezier4 x1 c1 c2 x2
Cubic (0.7 ^& 1.5) (2.7 ^& (-0.5)) (OffsetClosed (2.7 ^& (-1.5)))
ghci> bezier4' x1 c1 c2 x2 # translate (r2 (1000,1000))
Cubic (0.7 ^& 1.5) (2.7 ^& (-0.5)) (OffsetClosed (2.7 ^& (-1.5)))
一种修复方法是使
bezier4
类型产生
定位(段闭合v)
。使用这种类型,我们至少可以表示所需的曲线:

bezier4' x1 c1 c2 x2 = bezier3 (c1 ^-^ x1) (c2 ^-^ x1) (x2 ^-^ x1) `at` (0 .+^ x1)

ghci> bezier4' x1 c1 c2 x2
Loc { loc = P (0.3 ^& 0.5)
    , unLoc = Cubic (0.7 ^& 1.5) (2.7 ^& (-0.5)) (OffsetClosed (2.7 ^& (-1.5)))
    }
请注意,我们得到了与以前相同的线段,但现在我们有了一个位置

ghci> bezier4' x1 c1 c2 x2 # translate (r2 (1000,1000))
Loc { loc = P (1000.3 ^& 1000.5)
    , unLoc = Cubic (0.7 ^& 1.5) (2.7 ^& (-0.5)) (OffsetClosed (2.7 ^& (-1.5)))
    }
不过,我们在这一点上有点卡住了。定位的段并不特别有趣,因为我们通常希望将多个段串在一起作为
轨迹
。一个定位的段列表将我们带到那里,我们可以使用LocSegments的
fromLocSegments

fromLocSegments :: TrailLike t => Located [Segment Closed (V t)] -> t
fromFixedSegments :: TrailLike t => [FizedSegment (V t)] -> t
现在我们有了一些可以使用的东西(在
bezier4
的使用站点上进行了额外的更改):

请注意,我们不能将此函数的输出与其他段串在一起以形成更长的轨迹。图表选择使用具有
轨迹
定位
、和
路径
的强类型,仅允许精确匹配输出中表达的值(“含义”)。例如,假设我们想写作 来自FixedSegments的

fromLocSegments :: TrailLike t => Located [Segment Closed (V t)] -> t
fromFixedSegments :: TrailLike t => [FizedSegment (V t)] -> t

每个立方段将有四个点,但结果将是一条具有“无间隙”含义的轨迹。要做到这一点,我们必须扔掉相邻线段的第一个或最后一个点的信息。这里没有好的选择

但就我所知,
bezier4
曲线并不是一条经过翻译的
bezier3
曲线……哦,这不是一个好名字。bezier3函数总是从原点开始,我只是想做一个可以从任意点开始的函数。这是一个好名字:正如你在上所看到的,你可以为任意数量的点定义一条Bezier曲线。bezier3中的3不是参数的数量,而是曲线的阶数(它是一个立方)因此,函数中的4表示贝塞尔曲线是四次曲线(需要5个点或4个向量)。请注意,bezier3并不“总是从原点开始”,它只是一个段,因此没有位置(这有点像一个向量)。线段在列表中非常有用,可以创建复杂曲线,然后使用
在其起点进行定位。然后,您可以使用
fromLocSegments
获取图表。