Skip to content

Commit

Permalink
Merge pull request #89 from jw3126/lazy2d
Browse files Browse the repository at this point in the history
Lazy2d
  • Loading branch information
tkoolen authored Jan 18, 2019
2 parents 11410ec + 489522e commit a5b1635
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 44 deletions.
1 change: 1 addition & 0 deletions src/Rotations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ include("principal_value.jl")

export
Rotation, RotMatrix, RotMatrix2, RotMatrix3,
Angle2d,
Quat, SPQuat,
AngleAxis, RodriguesVec,
RotX, RotY, RotZ,
Expand Down
48 changes: 48 additions & 0 deletions src/core_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,54 @@ Base.inv(r::RotMatrix) = RotMatrix(r.mat')
RotMatrix([ret12 ret3])
end

"""
struct Angle2d{T} <: Rotation{2,T}
theta::T
end
A 2×2 rotation matrix parameterized by a 2D rotation by angle.
Only the angle is stored inside the `Angle2d` type, values
of `getindex` etc. are computed on the fly.
"""
struct Angle2d{T} <: Rotation{2,T}
theta::T
end

Angle2d(r::Angle2d) = r
Angle2d{T}(r::Angle2d) where {T} = Angle2d{T}(T(r.theta))

Base.one(::Type{A}) where {A<: Angle2d} = A(0)

@inline function Base.:*(r::Angle2d, v::StaticVector)
if length(v) != 2
throw(DimensionMismatch("Cannot rotate a vector of length $(length(v))"))
end
x,y = v
s,c = sincos(r.theta)
T = eltype(r)
similar_type(v,T)(c*x - s*y, s*x + c*y)
end

Base.:*(r1::Angle2d, r2::Angle2d) = Angle2d(r1.theta + r2.theta)
Base.:^(r::Angle2d, t::Real) = Angle2d(r.theta*t)
Base.:^(r::Angle2d, t::Integer) = Angle2d(r.theta*t)
Base.inv(r::Angle2d) = Angle2d(-r.theta)
rotation_angle(r::Angle2d) = r.theta

@inline function Base.getindex(r::Angle2d, i::Int)
if i == 1
cos(r.theta)
elseif i == 2
sin(r.theta)
elseif i == 3
-sin(r.theta)
elseif i == 4
cos(r.theta)
else
throw(BoundsError(r,i))
end
end

################################################################################
################################################################################

Expand Down
126 changes: 82 additions & 44 deletions test/2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ using Rotations, StaticArrays, Test
@testset "Identity rotation checks" begin
I = one(SMatrix{2,2,Float64})
I32 = one(SMatrix{2,2,Float32})
R = RotMatrix{2}
@test @inferred(size(R)) == (2,2)
@test @inferred(size(R{Float32})) == (2,2)
@test one(R)::R == I
@test one(R{Float32})::R{Float32} == I32
for R in [RotMatrix{2}, Angle2d]
@test @inferred(size(R)) == (2,2)
@test @inferred(size(R{Float32})) == (2,2)
@test one(R)::R == I
@test one(R{Float32})::R{Float32} == I32
end
end

################################
Expand All @@ -32,16 +33,17 @@ using Rotations, StaticArrays, Test

@testset "Testing inverse()" begin
repeats = 100
R = RotMatrix{2,Float64}
I = one(R)
Random.seed!(0)
for i = 1:repeats
r = rand(R)
@test isrotation(r)
@test inv(r) == adjoint(r)
@test inv(r) == transpose(r)
@test inv(r)*r I
@test r*inv(r) I
for R in [RotMatrix{2,Float64}, Angle2d{Float64}]
I = one(R)
Random.seed!(0)
for i = 1:repeats
r = rand(R)
@test isrotation(r)
@test inv(r) == adjoint(r)
@test inv(r) == transpose(r)
@test inv(r)*r I
@test r*inv(r) I
end
end
end

Expand All @@ -52,41 +54,43 @@ using Rotations, StaticArrays, Test
# a random rotation of a random point
@testset "Rotate Points" begin
repeats = 100
R = RotMatrix{2}
Random.seed!(0)
for i = 1:repeats
for R in [RotMatrix{2}, Angle2d]
Random.seed!(0)
for i = 1:repeats
r = rand(R)
m = SMatrix(r)
v = randn(SVector{2})

@test r*v m*v
end

# Test Base.Vector also
r = rand(R)
m = SMatrix(r)
v = randn(SVector{2})
v = randn(2)

@test r*v m*v
end

# Test Base.Vector also
r = rand(R)
m = SMatrix(r)
v = randn(2)

@test r*v m*v
end

# compose two random rotations
@testset "Compose rotations" begin
repeats = 100
R = RotMatrix{2}
Random.seed!(0)
for i = 1:repeats
r1 = rand(R)
m1 = SMatrix(r1)

r2 = rand(R)
m2 = SMatrix(r2)

@test r1*r2 m1*m2
θ1, θ2 = atan(r1[2,1],r1[1,1]), atan(r2[2,1],r2[1,1])
@test r1*r2 RotMatrix(θ1+θ2)
@test r1/r2 RotMatrix(θ1-θ2)
@test r1\r2 RotMatrix(θ2-θ1)
for R in [RotMatrix{2}, Angle2d]
Random.seed!(0)
for i = 1:repeats
r1 = rand(R)
m1 = SMatrix(r1)

r2 = rand(R)
m2 = SMatrix(r2)

@test r1*r2 m1*m2
θ1, θ2 = atan(r1[2,1],r1[1,1]), atan(r2[2,1],r2[1,1])
@test r1*r2 RotMatrix(θ1+θ2)
@test r1/r2 RotMatrix(θ1-θ2)
@test r1\r2 RotMatrix(θ2-θ1)
end
end
end

Expand All @@ -96,10 +100,13 @@ using Rotations, StaticArrays, Test
#########################################################################
@testset "Convert rotations" begin
repeats = 100
R = RotMatrix{2}
Random.seed!(0)
r1 = rand(R)
@test R(r1) == r1
for R in [RotMatrix{2}, Angle2d]
Random.seed!(0)
for _ in 1:repeats
r1 = rand(R)
@test R(r1) == r1
end
end
end

@testset "Types and products" begin
Expand All @@ -112,6 +119,37 @@ using Rotations, StaticArrays, Test
@test R * R T[0 -1; 1 0]
end
end

@testset "RotMatrix{2} vs Angle2d" begin
repeats = 100
Random.seed!(0)
for _ in 1:repeats
theta = randn()
r1 = RotMatrix{2}(theta)
r2 = Angle2d(theta)
v = randn(2)
@test r1 r2
@test r1 * v r2 * v
end
end

@testset "Angle2d" begin
repeats = 100
Random.seed!(0)
for _ in 1:repeats
r = rand(Angle2d)
@test r^(-1) inv(r)
@test r^(-1.0) inv(r)
@test r^1 r
@test r^1.0 r
@test r^2 r*r
@test r^2.0 r*r

x = randn()
y = randn()
@test r^(x+y) r^x * r^y
end
end
end

nothing

0 comments on commit a5b1635

Please sign in to comment.