如何在F#中添加元组并应用天花板/钳位功能

时间:2013-11-23 06:21:39

标签: f# tuples rgb

所以我正在使用F#进行一些SVG线操作的项目。

我认为将RGB值表示为元组(R,G,B)会很好。这对我来说很有意义。好吧,因为我的项目涉及在循环中生成SVG行。我决定使用颜色偏移,方便地在元组中表示(Roffset,Goffset,Boffset)

这种情况下的偏移表示每行与前一行的差异。

我到了需要添加元组的地方。我认为既然它们的尺寸和类型相同,那就没问题了。但显然不是。我还检查了元组的MSDN,但我没有找到任何关于如何添加或组合它们的信息。

这是我尝试过的。请记住,我试图尽可能多地省略不相关的代码,因为这是一个带有 LOTS 成员的长类定义。

 type lineSet ( 10+ params omitted ,count, colorOff :byte*byte*byte, color :byte*byte*byte ,strokeWid , strokeWidthOff  ) =

    member val Color = color with get, set
    member val ColorOffset = colorOff with get, set
    member val lineCount = count with get, set
    interface  DrawingInterfaces.IRepresentable_SVG with 
        member __.getSVGRepresenation() = 

          let mutable currentColor = __.Color
          for i in 1..__.lineCount do
             currentColor <- currentColor + __.ColorOffset

最后一行代码是我想要做的。但是,您似乎无法直接添加元组。

我还需要一种方法来钳制结果,因此它不能超过255,但我怀疑使用块进行简单的尝试就可以了。或者我可以让params采用int * int * int类型,只需使用if将其重置为255次。

2 个答案:

答案 0 :(得分:3)

正如我在评论中提到的,代码中的clamp函数实际上并不起作用 - 您需要在添加之前将数字转换为整数(然后您可以检查整数是否大于255)。你可以这样做:

let addClamp (a:byte) (b:byte) = 
  let r = int a + int b
  if r > 255 then 255uy else byte r

此外,如果您使用颜色,那么定义自定义颜色类型而不是将颜色作为元组传递可能是有意义的。这样,您还可以在颜色上定义+(使用钳位),这将使您的代码更简单(但仍然有10个构造函数参数有点可怕,所以我会尝试思考是否有办法简化一点)。颜色类型可能如下所示:

type Color(r:byte, g:byte, b:byte) = 
  static let addClamp (a:byte) (b:byte) = 
    let r = int a + int b
    if r > 255 then 255uy else byte r
  member x.R = r
  member x.B = b
  member x.G = g
  static member (+) (c1:Color, c2:Color) = 
    Color(addClamp c1.R c2.R, addClamp c1.G c2.G,addClamp c1.B c2.B)

使用该类型,您可以非常轻松地添加颜色,并且无需在每次需要时添加钳位。例如:

Color(255uy, 0uy, 0uy) + Color(1uy, 0uy, 0uy)

但我仍然认为你可以通过将一些视觉属性(比如stroke和amp; color)重构为一个单独的类型,然后将其传递给LineSet,使代码更具可读性和更易组合。这样,构造函数就不会有10个以上的参数,代码也可能更灵活。

答案 1 :(得分:3)

以下是您的代码的修改版本,我觉得它更好一点

let add3DbyteTuples (tuple1:byte*byte*byte , tuple2:byte*byte*byte) =
    let inline intify (a,b,c) = int a,int b,int c
    let inline tripleadd (a,b,c) (d,e,f) = a+d,b+e,c+f
    let clamp a = if a > 255 then 255 else a
    let R,G,B = tripleadd (intify tuple1) (intify tuple2)
    clamp R,clamp G,clamp B