Tweak shell spin

This commit is contained in:
2025-01-08 22:07:04 +00:00
parent d952bd48cc
commit c355fe4f5f
9 changed files with 179 additions and 173 deletions
+15 -27
View File
@@ -6,8 +6,8 @@ Description : Geometry helpers
This module provides geometry functions that manipulate pairs of floats.
Conventions:
Seg refers to a segment, typically defined by two points, and will typically not extend beyond either of these points.
Line refers to a line defined by two points, and extends beyond the two points.
Seg refers to a segment between two points and does not extend beyond either of these points.
Line is also defined by two points but does extend beyond the two points.
-}
module Geometry (
module Geometry,
@@ -33,9 +33,6 @@ import Geometry.Vector
import Geometry.Vector3D
import ListHelp
--import Data.Maybe
--import Data.List
{- | Return a point a distance away from a first point towards a second point.
Does not go past the second point.
No check is made for a negative distance, so can go past the first point.
@@ -93,9 +90,9 @@ midPoint !a !b = 0.5 *.* (a +.+ b)
-}
circOnSegNoEndpoints :: Point2 -> Point2 -> Point2 -> Float -> Bool
{-# INLINE circOnSegNoEndpoints #-}
circOnSegNoEndpoints !p1 !p2 !c !rad = intersectSegSegTest p1 p2 (c -.- thenormal) (c +.+ thenormal)
circOnSegNoEndpoints !p1 !p2 !c !rad = intersectSegSegTest p1 p2 (c -.- norm) (c +.+ norm)
where
thenormal = rad *.* vNormal (normalizeV $ p1 -.- p2)
norm = rad *.* vNormal (normalizeV $ p1 -.- p2)
{- | Test whether a circle is on a segment by intersecting a normal and testing
the distance to the endpoints of the segment.
@@ -106,9 +103,9 @@ circOnSeg :: Point2 -> Float -> Point2 -> Point2 -> Bool
circOnSeg !c !rad !p1 !p2 =
magV (p1 -.- c) <= rad
|| magV (p2 -.- c) <= rad
|| intersectSegSegTest p1 p2 (c -.- thenormal) (c +.+ thenormal)
|| intersectSegSegTest p1 p2 (c -.- norm) (c +.+ norm)
where
thenormal = rad *.* vNormal (normalizeV $ p1 -.- p2)
norm = rad *.* vNormal (normalizeV $ p1 -.- p2)
{- | Test whether a segment intersects a circle by intersecting a normal and testing
the distance to the endpoints of the segment.
@@ -118,13 +115,13 @@ segOnCirc :: Point2 -> Point2 -> Point2 -> Float -> Bool
segOnCirc !p1 !p2 !c !rad =
magV (p1 -.- c) <= rad
|| magV (p2 -.- c) <= rad
|| intersectSegSegTest p1 p2 (c -.- thenormal) (c +.+ thenormal)
|| intersectSegSegTest p1 p2 (c -.- norm) (c +.+ norm)
where
thenormal = rad *.* vNormal (normalizeV $ p1 -.- p2)
norm = rad *.* vNormal (normalizeV $ p1 -.- p2)
cylinderOnSeg :: Point3 -> Point3 -> Point3 -> Float -> Bool
{-# INLINE cylinderOnSeg #-}
cylinderOnSeg = undefined
cylinderOnSeg = undefined -- TODO
-- | Find the difference between two Nums.
difference :: (Ord a, Num a) => a -> a -> a
@@ -144,14 +141,15 @@ reflectIn line vec = rotateV (2 * angleBetween line vec) vec
reflectAngle :: Float -> Point2 -> Point2 -> Float
reflectAngle a x y = 2 * argV (x - y) - a
{- | Find the representation (by applying +-pi) of an angle
- that is nearest to another given angle -}
{- | Find the representation (by applying +-pi) of an angle
- that is nearest to another given angle
-}
nearestAngleRep :: Float -> Float -> Float
nearestAngleRep a b
| b >= a && b - a <= pi = b
| b >= a = nearestAngleRep a (b - 2*pi)
| b >= a = nearestAngleRep a (b - 2 * pi)
| a - b <= pi = b
| otherwise = nearestAngleRep a (b + 2*pi)
| otherwise = nearestAngleRep a (b + 2 * pi)
{- | Find angle between two points.
Not normalised, ranges from -2*pi to 2*pi.
@@ -170,7 +168,6 @@ doublePairSet (x, y) = S.fromList [(x, y), (y, x)]
doubleV2 :: V2 a -> [V2 a]
doubleV2 (V2 x y) = [V2 x y, V2 y x]
polyToTris' :: [s] -> [s]
{-# INLINE polyToTris' #-}
polyToTris' [] = []
@@ -193,8 +190,6 @@ nRaysRad n x = take n $ iterate (rotateV (2 * pi / fromIntegral n)) (V2 x 0)
This appears to sometimes fail if the angles are not normalized.
-}
isLeftOfA :: Float -> Float -> Bool
--isLeftOfA angle1 angle2 = (angle1 - angle2 < pi && angle1 > angle2)
-- || (angle2 - angle1 > pi && angle2 > angle1)
isLeftOfA angle1 angle2 = normalizeAngle (angle1 - angle2) < pi
{- | Test whether a vector is to the left of another, according to the smallest
@@ -204,17 +199,10 @@ isLeftOf :: Point2 -> Point2 -> Bool
isLeftOf x y = isLeftOfA (argV x) (argV y)
{- | Find the difference between two angles.
Possibly not correct...
TODO write tests
-}
diffAngles :: Float -> Float -> Float
diffAngles x y
| diff > pi = diffAngles (x - 2 * pi) y
| diff >= 0 = diff
| diff > - pi = - diff
| otherwise = diffAngles (x + 2 * pi) y
where
diff = x - y
diffAngles x y = nearZeroAngle $ x - y
mixAngles :: Float -> Float -> Float -> Float
mixAngles frac a1 a2