我正在Haskell中编写一个函数,它分别代表一个多维数据集的中心和边长的Point
和Double
。
Point
为type Point = [Double]
。
函数签名为getCubeFaces :: Cube -> [Face]
,其中Face
为data Face = Face [Point]
,Cube
为data Cube = Cube Point Double
。
我的问题是,我该怎么做呢?我尝试了
的天真方法[ Face [ [-1, 1, 1], [1, 1, 1] ...
并列出所有6个面孔,如8点所描述 - 但这真的丑陋。
是否有更直观/有图案的方式来解决这个问题(无法访问法线向量)?
答案 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]
时,第一个允许你更灵活。