优化这个haskell线性代数代码

时间:2014-07-27 19:06:19

标签: haskell optimization linear-algebra

我有这个Haskell代码用于测试形状之间的碰撞(它取决于线性和镜头包装)

import Linear hiding (trace)
import Control.Lens.Getter ((^.))

type Vec3 = V3 Float

data Tri = Tri Vec3 Vec3 Vec3
data Box = Box Vec3 Vec3

-- | Any primitive collidable in 3D
class Collide a where
    axes :: a -> [Vec3] -- | return all potentially separating axes, normalized
    -- | project the shape onto the normalized axis, giving a 1D line segment
    project :: a -> Vec3 -> (Float, Float)

intersects :: (Collide a, Collide b) => a -> b -> Bool
intersects a b = isOverlap `all` axs
    where axs = axes a ++ axes b
          --do the line segments overlap?
          overlaps (l, r) (l', r') = l' <= r && r' >= l
          isOverlap ax = project a ax `overlaps` project b ax

{-# SPECIALIZE intersects :: Box -> Tri -> Bool #-}

instance Collide Tri where
    --face normal, and edge normals
    {-# INLINE axes #-}
    axes (Tri q r s) = map normalize (face : edges)
        where face = (q ^-^ r) `cross` (s ^-^ r)
              edges = map (face `cross`) [q ^-^ r, r ^-^ s, s ^-^ q]

    {-# INLINE project #-}
    project (Tri q r s) ax = (minimum projs, maximum projs)
        where projs = map (dot ax) [q, r, s]

instance Collide Box where
    {-# INLINE axes #-}
    axes _ = basis --it's axis aligned!

    {-# INLINE project #-}
    project (Box a b) ax@(V3 x y z) = (min l r, max l r)
        --there are 4 possible pairs of point depending on the direction of ax
              --partially apply just x and y to the constructor in c' and d'
        where (c', d') | x*y > 0 = (V3 (a^._x) (a^._y), V3 (b^._x) (b^._y)) --same x and y
                       | otherwise = (V3 (a^._x) (b^._y), V3 (b^._x) (a^._y)) --different x and y
              (c, d)   | x*z > 0 = (c' (a^._z), d' (b^._z)) --same x and z
                       | otherwise = (c' (b^._z), d' (a^._z)) --different x and z
              (l, r) = (c `dot` ax, d `dot` ax)

intersects :: Box -> Tri -> Bool的调用正在减慢我的应用程序速度,但我无法让它运行得更快。我查看了分析器,堆配置文件和-ddump-simpl的输出,但它们没有提供任何线索。我错过了什么?

0 个答案:

没有答案