use atan2 in V2.unangle
- Dominant language
- Haskell
- Stars
- 220
- Forks
- 55
- PR merge metrics
- No merged PRs in 30d
Description
I propose `unangle (V2 x y) = atan2 y x` because it's shorter and numerically better:
```
ghci> unangle (V2 0 2.646978e-23) :: Float
NaN
ghci> unangle (V2 0 2.6469783e-23) :: Float
0.7853983
ghci> unangle (V2 0 5.4210115e-20) :: Float
1.5703081
ghci> atan2 1e-45 0 :: Float
1.5707964
```
But the output of unangle is on [-pi/2, 3pi/2], while the output of atan2 is on [-pi,pi]:
```haskell
> do printf "unangle, atan2, angle\n" ; sequence_ [ printf "%.2f %.2f %.2f\n" (unangle v) (atan2 y x) ang | ang <- [ -2*pi, -2*pi + pi/4 .. 2*pi ], let v = angle ang, let V2 x y = v ] :: IO ()
unangle, atan2, angle
0.00 0.00 -6.28
0.79 0.79 -5.50
1.57 1.57 -4.71
2.36 2.36 -3.93
3.14 -3.14 -3.14
3.93 -2.36 -2.36
-1.57 -1.57 -1.57
-0.79 -0.79 -0.79
0.00 0.00 0.00
0.79 0.79 0.79
1.57 1.57 1.57
2.36 2.36 2.36
3.14 3.14 3.14
3.93 -2.36 3.93
4.71 -1.57 4.71
-0.79 -0.79 5.50
-0.00 -0.00 6.28
```
You could keep the old range but I suspect it's not necessary:
```haskell
-- | output on [-pi/2, 3pi/2]
unangle (V2 x y) = case atan2 y x of
theta
| theta < -pi/2 -> theta + 2*pi
| otherwise -> theta
```
A bigger problem with the new definition is that the type will change. Some users of unangle need new RealFloat instances:
```haskell
unangle :: (Floating a, Ord a) => V2 a -> a
atan2 :: RealFloat a => a -> a -> a
instance Floating a => Floating (V2 a) -- exists
instance RealFloat a => RealFloat (V2 a) where
atan2 = liftA2 atan2 -- missing for good reason.. how to write encode/decodeFloat?
```
OverlappingInstances, TypeFamilies or maybe rewrite rules are another option to get atan2 for Float and Double, but keep asin for other types.
Contributor guide
No contributing guide indexed for this repository
Research direction
No files or tests are named; start at the V2.unangle definition and inspect its relationship with atan2, angle, and the existing Floating and RealFloat instances. Done means deciding the output range and a compatible typeclass design, then validating the shown ghci examples and affected user behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- haskell
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100