{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} module Geom2d.Intersect where import Geom2d.Point import Geom2d.Line import Geom2d.Line.Internal class Intersect a b where intersect :: a -> b -> Bool instance (Eq a) => Intersect (Point' a) (Point' a) where intersect p q = p == q instance (Eq (p a), Num (p a), Num a, RealFloat a, Point p) => Intersect (InfLine p a) (InfLine p a) where intersect a b | a == b = True | a `parallel` b = False | otherwise = True instance (Point p, Eq a, Fractional a) => Intersect (InfLine p a) (p a) where intersect line@(InfLine a _) q = maybe ( x a == x q ) ( \f -> f (x q) == y q ) ( lineF line ) instance (Point p, Eq a, Fractional a) => Intersect (p a) (InfLine p a) where intersect = flip intersect instance (Eq (p a), Point p, Num (p a), RealFloat a) => Intersect (FinLine p a) (FinLine p a) where intersect (FinLine a1 b1) (FinLine a2 b2) = case intersection (InfLine a1 b1) (InfLine a2 b2) of Nothing -> False Just p -> let minx = max (min (x a1) (x b1)) (min (x a2) (x b2)) maxx = min (max (x a1) (x b1)) (max (x a2) (x b2)) miny = max (min (y a1) (y b1)) (min (y a2) (y b2)) maxy = min (max (y a1) (y b1)) (max (y a2) (y b2)) in and [ x p <= maxx , x p >= minx , y p <= maxy , y p >= miny ] instance (Eq (p a), Point p, Num (p a), RealFloat a) => Intersect (InfLine p a) (FinLine p a) where intersect infLine (FinLine f1 f2) = case intersection infLine (InfLine f1 f2) of Nothing -> False Just p -> let minx = min (x f1) (x f2) maxx = max (x f1) (x f2) miny = min (y f1) (y f2) maxy = max (y f1) (y f2) in and [ x p <= maxx , x p >= minx , y p <= maxy , y p >= miny ] instance (Eq (p a), Point p, Num (p a), RealFloat a) => Intersect (FinLine p a) (InfLine p a) where intersect = flip intersect