我的边界框功能在哪里出错了?

时间:2016-06-20 21:43:38

标签: algorithm haskell data-structures octree

我正在为octree库编写一个边界框模块。你可以找到我的分支here。在下面的函数中,我尝试明确Octree的隐式边界框。问题是,并非所有边界框都有效。

这是有问题的功能,接着是在ghci中复制问题的方法。

explicateMBB :: (BBox3, Octree a) -> [BBox3]
explicateMBB (mbb, (Leaf _)) = [mbb]
explicateMBB (mbb, (Node { split = split',
                           nwu   = nwu',
                           nwd   = nwd',
                           neu   = neu',
                           ned   = ned',
                           swu   = swu',
                           swd   = swd',
                           seu   = seu',
                           sed   = sed'
             })) =
   mbb:concatMap explicateMBB octList 
  where 
    octList = zip boxList children
    boxList = [swdBox, sedBox, nwdBox, nedBox, swuBox, seuBox, nwuBox, neuBox]
    children = [swd',sed',nwd',ned',swu',seu',nwu',neu']
    swdBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (minX mbb) (minY mbb) (minZ mbb)
        neuCorner = Vector3 (v3x split') (v3y split') (v3z split')
    sedBox = bound_corners swdCorner neuCorner
      where
        swdCorner = Vector3 (v3x split') (minY mbb) (minZ mbb)
        neuCorner = Vector3 (maxX mbb) (v3y split') (minZ mbb)
    nwdBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (minX mbb) (v3y split') (minZ mbb)
        neuCorner = Vector3 (v3x split') (maxY mbb) (v3z split')
    nedBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (v3x split') (v3y split') (minZ mbb)    
        neuCorner = Vector3 (maxX mbb) (maxY mbb) (v3z split')
    swuBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (minX mbb) (minY mbb) (v3z split')
        neuCorner = Vector3 (v3x split') (v3y split') (maxZ mbb)
    seuBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (v3x split') (minY mbb) (v3z split')
        neuCorner = Vector3 (maxX mbb) (v3y split') (maxZ mbb)
    nwuBox = bound_corners swdCorner neuCorner 
      where
        swdCorner = Vector3 (minX mbb) (v3y split') (v3z split')
        neuCorner = Vector3 (v3x split') (maxY mbb) (maxZ mbb)
    neuBox = bound_corners swdCorner neuCorner
      where
        swdCorner = Vector3 (v3x split') (v3y split') (v3z split')
        neuCorner = Vector3 (maxX mbb) (maxY mbb) (maxZ mbb)

要复制问题:

git clone https://github.com/mlitchard/octree.git

git checkout MBB

stack ghci

ghci中,执行以下操作:

:m + Data.List Data.Vector.Class System.Random System.Random.Shuffle Data.BoundingBox.B3
let infinity = (read "Infinity") :: Double
let swdCorner = Vector3 (-infinity) (-infinity) (-infinity)
let neuCorner = Vector3 (infinity) (infinity) (infinity)
let rbb = bound_corners swdCorner neuCorner
xGen <- getStdGen
yGen <- newStdGen
zGen <- newStdGen
let xPoints = shuffle' [-256 .. 256] 513 xGen
let yPoints = shuffle' [-256 .. 256] 513 yGen
let zPoints = shuffle' [-256 .. 256] 513 zGen
let xPoints' = map fromInteger xPoints :: [Double]
let yPoints' = map fromInteger yPoints :: [Double]
let zPoints' = map fromInteger zPoints :: [Double]
let tup513 = zip3 xPoints' yPoints' zPoints'
let construct_vect = (\(x,y,z) -> Vector3 x y z)
let vect513 = map construct_vect tup513
let pre_oct513 = zip vect513 [1 .. 513]
let octree513 = fromList pre_oct513
length $ filter (== False) $ map isValidMBB $ explicateMBB (rbb,octree513)

答案是9,但应该是0。

我觉得fooBox where条款中的一个是错误的,但我已经多次查看过每一个条款,而我看不出它是哪一条。

如果您需要像我一样的视觉辅助,我发现this pic有帮助。我的样本做了2个细分。

任何对出现问题的见解都将不胜感激。

1 个答案:

答案 0 :(得分:3)

这是你的第二个where条款:

where
    swdCorner = Vector3 (v3x split') (minY mbb) (minZ mbb)
    neuCorner = Vector3 (maxX mbb) (v3y split') (minZ mbb)

应该是:

where
    swdCorner = Vector3 (v3x split') (minY mbb) (minZ mbb)
    neuCorner = Vector3 (maxX mbb) (v3y split') (v3z split') <-- v3z split'