如何在Haskell中生成多维数据集的面?

时间:2013-11-02 04:51:30

标签: haskell 3d geometry

我正在Haskell中编写一个函数,它分别代表一个多维数据集的中心和边长的PointDouble

Pointtype Point = [Double]

函数签名为getCubeFaces :: Cube -> [Face],其中Facedata Face = Face [Point]Cubedata Cube = Cube Point Double

我的问题是,我该怎么做呢?我尝试了

的天真方法
[ Face [ [-1, 1, 1], [1, 1, 1] ...

并列出所有6个面孔,如8点所描述 - 但这真的丑陋。

是否有更直观/有图案的方式来解决这个问题(无法访问法线向量)?

1 个答案:

答案 0 :(得分:4)

首先让

type Vector = Point
a <+> b = zipWith (+) a b --vector addition
a <*> b = map (*b) a --vector scalar multiplication

然后,我建议两种方法。多维数据集以0, 0, 0为中心,边长为2。您可以稍后map (\face -> map (\point -> point <*> sideLength/2 <+> center)。第一

face :: Vector -> Vector -> Vector -> Face
face x y z = [x <+> (y <*> i) <+> (z <*> j) | i <- [-1, 1], j <- [-1, 1]]

cube :: [Face]
cube = let
    axes = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    directions = zipWith (\ds i -> map (<*>i) ds) (permutations axes) (cycle [1, -1])
  in map (\[x, y, z] -> face x y z) directions

第二,

cube' :: [Face]
cube' = let
    points = [[x, y, z] | x <- [-1, 1], y <- [-1, 1], z <- [-1, 1]]
    pair i = partition (\x -> x !! i > 0) points
  in map pair [0..2] >>= (\(a, b) -> [a, b]) 

虽然第二个更短,但请注意,当你发现自己真正想要type Face = [Triangle]时,第一个允许你更灵活。