tasks a-s
This commit is contained in:
parent
47bf37c096
commit
b83f433714
12433 changed files with 156208 additions and 123 deletions
49
Task/Ray-casting-algorithm/Haskell/ray-casting-algorithm.hs
Normal file
49
Task/Ray-casting-algorithm/Haskell/ray-casting-algorithm.hs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import Data.Ratio
|
||||
|
||||
type Point = (Rational, Rational)
|
||||
type Polygon = [Point]
|
||||
data Line = Sloped {lineSlope, lineYIntercept :: Rational} |
|
||||
Vert {lineXIntercept :: Rational}
|
||||
|
||||
polygonSides :: Polygon -> [(Point, Point)]
|
||||
polygonSides poly@(p1 : ps) = zip poly $ ps ++ [p1]
|
||||
|
||||
intersects :: Point -> Line -> Bool
|
||||
{- @intersects (px, py) l@ is true if the ray {(x, py) | x ≥ px}
|
||||
intersects l. -}
|
||||
intersects (px, _) (Vert xint) = px <= xint
|
||||
intersects (px, py) (Sloped m b) | m < 0 = py <= m * px + b
|
||||
| otherwise = py >= m * px + b
|
||||
|
||||
onLine :: Point -> Line -> Bool
|
||||
{- Is the point on the line? -}
|
||||
onLine (px, _) (Vert xint) = px == xint
|
||||
onLine (px, py) (Sloped m b) = py == m * px + b
|
||||
|
||||
carrier :: (Point, Point) -> Line
|
||||
{- Finds the line containing the given line segment. -}
|
||||
carrier ((ax, ay), (bx, by)) | ax == bx = Vert ax
|
||||
| otherwise = Sloped slope yint
|
||||
where slope = (ay - by) / (ax - bx)
|
||||
yint = ay - slope * ax
|
||||
|
||||
between :: Ord a => a -> a -> a -> Bool
|
||||
between x a b | a > b = b <= x && x <= a
|
||||
| otherwise = a <= x && x <= b
|
||||
|
||||
inPolygon :: Point -> Polygon -> Bool
|
||||
inPolygon p@(px, py) = f 0 . polygonSides
|
||||
where f n [] = odd n
|
||||
f n (side : sides) | far = f n sides
|
||||
| onSegment = True
|
||||
| rayIntersects = f (n + 1) sides
|
||||
| otherwise = f n sides
|
||||
where far = not $ between py ay by
|
||||
onSegment | ay == by = between px ax bx
|
||||
| otherwise = p `onLine` line
|
||||
rayIntersects =
|
||||
intersects p line &&
|
||||
(py /= ay || by < py) &&
|
||||
(py /= by || ay < py)
|
||||
((ax, ay), (bx, by)) = side
|
||||
line = carrier side
|
||||
Loading…
Add table
Add a link
Reference in a new issue