From bb51e8025f178d7423c5404b8e8e6909f856907b Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Tue, 24 Dec 2024 12:06:32 -0800 Subject: Add axis-aligned plane. --- Spear/Math/Plane.hs | 60 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/Spear/Math/Plane.hs b/Spear/Math/Plane.hs index 5440a43..cbf5aed 100644 --- a/Spear/Math/Plane.hs +++ b/Spear/Math/Plane.hs @@ -2,41 +2,75 @@ module Spear.Math.Plane ( - Plane -, plane -, classify + Plane(..) +, AxisPlane(..) +, plane +, axisPlane +, planeClassify +, axisPlaneClassify ) where import Spear.Math.Vector import Spear.Prelude + +data Axis = X | Y | Z deriving (Eq, Show) + +data AxisOrientation = PositiveAxis | NegativeAxis deriving (Eq, Show) + data PointPlanePos = Front | Back | Contained deriving (Eq, Show) +-- | A 3D plane. data Plane = Plane - { n :: {-# UNPACK #-} !Vector3, - d :: {-# UNPACK #-} !Float + { planeNormal :: {-# UNPACK #-} !Vector3 + , planeDistance :: {-# UNPACK #-} !Float } deriving(Eq, Show) +-- | An axis-aligned 3D plane. +data AxisPlane = AxisPlane + { axisPlaneAxis :: !Axis + , axisPlaneDistance :: {-# UNPACK #-} !Float + , axisPlaneNormal :: !AxisOrientation + } + deriving (Eq, Show) + + -- | Construct a plane from a normal vector and a distance from the origin. plane :: Vector3 -> Float -> Plane plane n d = Plane (normalise n) d +-- | Construct an axis-aligned plane. +axisPlane :: Axis -> Float -> AxisOrientation -> AxisPlane +axisPlane = AxisPlane + -- | Construct a plane from three points. -- -- Points must be given in counter-clockwise order. -fromPoints :: Vector3 -> Vector3 -> Vector3 -> Plane -fromPoints p0 p1 p2 = Plane n d - where n = normalise $ v1 `cross` v2 - v1 = p2 - p1 - v2 = p0 - p1 - d = p0 `dot` n +planeFromPoints :: Vector3 -> Vector3 -> Vector3 -> Plane +planeFromPoints p0 p1 p2 = Plane n d + where n = normalise $ v1 `cross` v2 + v1 = p2 - p1 + v2 = p0 - p1 + d = p0 `dot` n -- | Classify the given point's relative position with respect to the plane. -classify :: Plane -> Vector3 -> PointPlanePos -classify (Plane n d) pt = +planeClassify :: Plane -> Vector3 -> PointPlanePos +planeClassify (Plane n d) pt = case (n `dot` pt - d) `compare` 0 of GT -> Front LT -> Back EQ -> Contained + +-- | Classify the given point's relative position with respect to the plane. +axisPlaneClassify :: AxisPlane -> Vector3 -> PointPlanePos +axisPlaneClassify (AxisPlane axis d _) (Vector3 x y z) = + let classify coord + | coord < d = Back + | coord > d = Front + | otherwise = Contained + in case axis of + X -> classify x + Y -> classify y + Z -> classify z -- cgit v1.2.3