Skip to content
This repository has been archived by the owner on Oct 23, 2022. It is now read-only.

Commit

Permalink
BrianGun/issue303 (#305)
Browse files Browse the repository at this point in the history
* added more tests

* move planefrompoints2 from inside HeadEyeModel to utilities.jl
Fixes #303

* needed to use Statistics package to get mean for plane_from_points.
  • Loading branch information
BrianGun authored Oct 28, 2021
1 parent 67b900e commit 443cc32
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 24 deletions.
2 changes: 2 additions & 0 deletions src/OpticSim.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module OpticSim

import Unitful
using LinearAlgebra: eigen, svd, I, qr, dot, cross, norm, det, normalize, inv
import LinearAlgebra

using StaticArrays
using DataFrames: DataFrame
using Images
Expand Down
2 changes: 1 addition & 1 deletion src/Optical/ParaxialAnalysis/HeadEyeModel/Arrangement.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function build_paraxial_lens(shape::Shape{3, T}; local_center_point = SVector(0.
# estimate a best fitting plane (least-squares wise)
# switching to SMatrix format - should consider using SMatrix in the basic shapes instead of a vector of points
pts_mat = reshape(SVector(reduce(vcat, pts)...), StaticArrays.Size(length(pts[1]),length(pts)))
fitted_center, fitted_normal = HeadEye.plane_from_points2(pts_mat)
fitted_center, fitted_normal = OpticSim.plane_from_points(pts_mat)

# create a local frame for the fitted plane
local_frame = Transform(fitted_center, fitted_normal)
Expand Down
26 changes: 4 additions & 22 deletions src/Optical/ParaxialAnalysis/HeadEyeModel/Misc.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
"""
plane_from_points(points::Vector{SVector{3, Float64}}) -> centroid, normal
Estimate the best fitting plane for a set of points in 3D
Estimate the best fitting plane for a set of points in 3D.
See utilities.jl for a simpler and possibly more numerically stable version.
"""
function plane_from_points(points::Vector{SVector{3, Float64}})
function plane_from_points2(points::Vector{SVector{3, Float64}})
if length(points) < 3
return nothing # At least three points required
end
Expand Down Expand Up @@ -55,26 +57,6 @@ function plane_from_points(points::Vector{SVector{3, Float64}})
return centroid, normalize(dir)
end

"""
plane_from_points2(points::SMatrix{3, N, Float64}}) -> centroid, normal
Estimate the best fitting plane for a set of points in 3D.
A more efficient version of plane_from_points.
"""
function plane_from_points2(points::SMatrix{3, N, Float64} where {N})
center = mean(points,dims=2)

u, _, _ = svd(points .- center)
normal = u[:,3] # singular vectors in decending order

# make sure the normal is pointing consistently to positive Z direction
if (dot(normal, unitZ3()) < 0.0)
normal = normal * -1.0
end

return SVector(center), SVector(normal) # convert from SMatrix to SVector
end


function csg_sphere(;radius = 10.0)
sph = Sphere(radius)
Expand Down
23 changes: 22 additions & 1 deletion src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,28 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# See LICENSE in the project root for full license information.

# only returns real roots

"""
plane_from_points(points::SMatrix{3, N, Float64}}) -> centroid, normal
Estimate the best fitting plane for a set of points in 3D.
A more efficient version of plane_from_points.
"""
function plane_from_points(points::SMatrix{3, N, Float64} where {N})
center = Statistics.mean(points,dims=2)

u, _, _ = svd(points .- center)
normal = u[:,3] # singular vectors in decending order

# make sure the normal is pointing consistently to positive Z direction
if (dot(normal, unitZ3()) < 0.0)
normal = normal * -1.0
end

return SVector(center), SVector(normal) # convert from SMatrix to SVector
end

"""only returns real roots"""
function quadraticroots(a::T, b::T, c::T) where {T<:Real}
temp = b^2 - 4 * a * c

Expand Down
14 changes: 14 additions & 0 deletions test/testsets/Repeat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,19 @@
return Repeat.ClusterWithProperties(lattice,properties)
end

""" Create a LatticeCluser with three elements at (0,0),(-1,0),(-1,1) coordinates in the HexBasis1 lattice"""
function hex3cluster()
clusterelts = SVector((0,0),(-1,0),(-1,1))
eltlattice = Repeat.HexBasis1()
clusterbasis = Repeat.LatticeBasis(( -1,2),(2,-1))
return Repeat.LatticeCluster(clusterbasis,eltlattice,clusterelts)
end

@test [-1 2;2 -1] == Repeat.basismatrix(Repeat.clusterbasis(hex3RGB()))

function basistest(a::Repeat.AbstractLatticeCluster)
return Repeat.clusterbasis(a)
end

@test basistest(hex3cluster()) == basistest(hex3RGB())
end

0 comments on commit 443cc32

Please sign in to comment.