- 
                Notifications
    You must be signed in to change notification settings 
- Fork 43
Make rotations in degrees exact #197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
| Codecov Report❌ Patch coverage is  
 Additional details and impacted files@@            Coverage Diff             @@
##           master     #197      +/-   ##
==========================================
- Coverage   86.12%   85.84%   -0.29%     
==========================================
  Files          14       14              
  Lines        1341     1349       +8     
==========================================
+ Hits         1155     1158       +3     
- Misses        186      191       +5     ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
 | 
| Great! I didn't know that the  julia> import Unitful.°
julia> sin(30°)
0.5
julia> sin(π/6)
0.49999999999999994 | 
| Could you change  julia> using Rotations; import Unitful.°
julia> RotX(30°)
3×3 RotX{Float64, Quantity{Int64, NoDims, FreeUnits{(°,), NoDims, nothing}}} with indices SOneTo(3)×SOneTo(3)(30°):
 1.0  0.0        0.0
 0.0  0.866025  -0.5
 0.0  0.5        0.866025
julia> RotX(30°)[2,3]
-0.5
julia> AngleAxis(30°,1,0,0)
3×3 AngleAxis{Float64} with indices SOneTo(3)×SOneTo(3)(0.523599, 1.0, 0.0, 0.0):
 1.0  0.0        0.0
 0.0  0.866025  -0.5
 0.0  0.5        0.866025
julia> AngleAxis(30°,1,0,0)[2,3]
-0.49999999999999994If  | 
Co-authored-by: Yuto Horikawa <[email protected]>
Co-authored-by: Yuto Horikawa <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add some tests for RotX(30°), AngleAxis(30°,1,0,0), etc?
| 
 I'm in the process of writing extra tests. | 
| 
 I agree with that. That was already implemented before I joined this package. @andyferris | 
| Exactitude of coefficients is lost for  | 
| 
 I think we are not using quaternion here, just Rodrigues' rotation formula, (code in this repo). 
 Exactly. At first, I thought it would be better to have  We can choose from the following: 
 
 Maybe  
 Yeah, but it will be hard to express a point on a sphere with a floating-point number... | 
| 
 But just three lines above your quote: @inline Base.getindex(aa::AngleAxis, i::Int) = UnitQuaternion(aa)[i]Rodrigues formula would indeed be easier for exactness (no angle halving, for a start). 
 Rational exactness is another useful property 😀 (i.e.  
 There is this arXiv paper claiming a rational Rodrigues formula. I'm reading it right now; at first sight, it seems legit. Edit: after reading the paper, this comes down to a simple fact:  the rotation with axis vector u and angle θ has as coefficients rational functions of (tan(θ/2)/‖u‖) u (and with a denominator at most 1+tan²(θ/2)). For example, in the case of  Unfortunately, I believe that the simplest way to cover all those cases is to write ad-hoc code for the case when the angle is a multiple of 30° and the type of the axis vector is exact (integer or rational). | 
| 
 Ah, I missed the line. julia> aa = rand(AngleAxis)
3×3 AngleAxis{Float64} with indices SOneTo(3)×SOneTo(3)(1.78335, 0.814399, 0.0957725, -0.572347):
  0.592207   0.653918  -0.470832
 -0.465016  -0.199847  -0.862451
 -0.658066   0.729693   0.185732
julia> RotMatrix(aa)[1]
0.5922065228804426
julia> aa[1]
0.5922065228804425These values  
 Understood, but I think it will be hard for type stability. 
 I agree with that. As mentioned above, obtaining exact rational numbers seems to be incompatible with type stability here. Do you think adding the new type parameter  | 
| 
 While searching for the exact Rodrigues formula I found (but did not read) a few papers bout rational approximations for rotation matrices. While that's an interesting option for when the user explicitly asks for a rational answer, that is work for another PR indeed. 
 For now I reverted  This is due to the fact that  | 
| 
 👍 
 👍 
 Ah, bad news. Btw, on the current  julia> RotXYZ(30°,60°,90°)
3×3 RotXYZ{Float64} with indices SOneTo(3)×SOneTo(3)(0.523599, 1.0472, 1.5708):
 3.06162e-17  -0.5        0.866025
 0.866025     -0.433013  -0.25
 0.5           0.75       0.433013
julia> RotXYZ(30°,60°,90°)[3,2]
0.75Hmm, should we drop the accurate calculation of floating-point numbers here..? 
 
 I think many users understand that floating-point numbers are approximate calculations, and adding  | 
| 
 In this case  
 This seems reasonable to me. I expect that code for exact rational rotations is never going to be good as a default codepath for a library which is mainly trying to do fast numerical (floating point) rotations. However, it could be useful to have alternative utility functions which try to go to great lengths to get a good rational answer or approximation. An alternative viewpoint here could be that we accept floating point as a practical necessity, but try to make some of the conversions to rotation matrix elements correctly rounded. For example using compensated floating point arithmetic. This is the point of view that leads to functions like  Note that writing correctly rounding code which is fast is very hard though! Practically, it may be better to just use  | 
| 
 The point of the second type parameter is not keeping the angle an integer, it is keeping the angle in degrees, whereas the previous code lost exactness by converting the angle to radians. I expect the standard use case to look more like  | 
| 
 Sure, this is kind of what I was trying to point out: you want the computation to eventually use  | 
| 
 The exact layouts of the structs isn't important to me. This package predates @c42f and I contributing (as well as StaticArrays), so I'm not sure exactly how old those choices are! | 
| I just stumbled upon this, and though I should bump it. My 2 uninformed cents: It seems like perfect may be the enemy of the good here. | 
This PR adds a second type parameter to angular rotations type (
Angle2dand allRotXetc.). This prevents automatic conversion of the angle to floating-point and the resulting inexactitude when angles are in degrees.