+++ /dev/null
--- Copyright (c) 2000 Galois Connections, Inc.
--- All rights reserved. This software is distributed as
--- free software under the license in the file "LICENSE",
--- which is included in the distribution.
-
-module Interval
- ( IList
- , Intersection
- , emptyIList, openIList
- , mkEntry, mkExit
- , entryexit, exitentry
- , mapI
- , unionIntervals, intersectIntervals, differenceIntervals
- , complementIntervals
- ) where
-
-import Geometry
-
--- The result of a ray trace is represented as a list of surface
--- intersections. Each intersection is a point along the ray with
--- a flag indicating whether this intersection is an entry or an
--- exit from the solid. Each intersection also carries unspecified
--- surface data for use by the illumination model.
-
--- Just the list of intersections isn't enough, however. An empty
--- list can denote either a trace that is always within the solid
--- or never in the solid. To dissambiguate, an extra flag is kept
--- that indicates whether we are starting inside or outside of the
--- solid. As a convenience, we also keep an additional flag that
--- indicates whether the last intersection ends inside or outside.
-
-type IList a = (Bool, [Intersection a], Bool)
-type Intersection a = (Double, Bool, a)
-
-emptyIList = (False, [], False)
-openIList = (True, [], True)
-
-mapI f (b1, is, b2) = (b1, map f is, b2)
-
-isEntry (_, entry, _) = entry
-isExit (_, entry, _) = not entry
-
-mkEntry (t, a) = (t, True, a)
-mkExit (t, a) = (t, False, a)
-
-entryexit w1 w2 = (False, [mkEntry w1, mkExit w2], False)
-exitentry w1 w2 = (True, [mkExit w1, mkEntry w2], True)
-arrange w1@(t1, _) w2@(t2, _) | t1 < t2 = entryexit w1 w2
- | otherwise = entryexit w2 w1
-
-
-cmpI :: Intersection a -> Intersection a -> Ordering
-cmpI (i, _, _) (j, _, _)
- | i `near` j = EQ
- | i < j = LT
- | otherwise = GT
-
-bad (b1, [], b2) = b1 /= b2
-bad (b1, is, b2) = bad' b1 is || b2 /= b3
- where (_, b3, _) = last is
-
-bad' b [] = False
-bad' b ((_, c, _) : is) = b == c || bad' c is
-
-unionIntervals :: IList a -> IList a -> IList a
-unionIntervals (isStartOpen, is, isEndOpen) (jsStartOpen, js, jsEndOpen)
- = (isStartOpen || jsStartOpen, uniIntervals is js, isEndOpen || jsEndOpen)
- where uniIntervals is [] | jsEndOpen = []
- | otherwise = is
- uniIntervals [] js | isEndOpen = []
- | otherwise = js
- uniIntervals is@(i : is') js@(j : js')
- = case cmpI i j of
- EQ -> if isEntry i == isEntry j then i : uniIntervals is' js'
- else uniIntervals is' js'
- LT -> if isEntry j then i : uniIntervals is' js
- else uniIntervals is' js
- GT -> if isEntry i then j : uniIntervals is js'
- else uniIntervals is js'
-
-intersectIntervals :: IList a -> IList a -> IList a
-intersectIntervals is js
- = complementIntervals (unionIntervals is' js')
- where is' = complementIntervals is
- js' = complementIntervals js
-
-differenceIntervals :: IList a -> IList a -> IList a
-differenceIntervals is js
- = complementIntervals (unionIntervals is' js)
- where is' = complementIntervals is
-
-complementIntervals :: IList a -> IList a
-complementIntervals (o1, is, o2)
- = (not o1, [ (i, not isentry, a) | (i, isentry, a) <- is ], not o2)
-
--- tests...
-
-{-
-mkIn, mkOut :: Double -> Intersection a
-mkIn x = (x, True, undefined)
-mkOut x = (x, False, undefined)
-
-i1 = (False, [ mkIn 2, mkOut 7 ], False)
-i1' = (True, [ mkOut 2, mkIn 7 ], True)
-i2 = (False, [ mkIn 1, mkOut 3, mkIn 4, mkOut 5, mkIn 6, mkOut 8 ], False)
-
-t1 = unionIntervals i1 i2
-t2 = intersectIntervals i1 i2
-t3 = intersectIntervals i2 i1
-t4 = complementIntervals i1
-t5 = intersectIntervals i2 i1'
-t6 = differenceIntervals i2 i1
-t7 = differenceIntervals i2 i2
-
-sh (o1,is,o2) =
- do if o1 then putStr "..." else return ()
- putStr $ foldr1 (++) (map si is)
- if o2 then putStr "..." else return ()
-si (i, True, _, _) = "<" ++ show i
-si (i, False, _, _) = " " ++ show i ++ ">"
--}