Representing point clouds

For the purpose of this package, we refer to a point cloud as a set of points, i.e. a subset of $\mathbb{R}^D$ for some integer $D$. We then also say that it is $D$-dimensional. A point cloud can represent the atom coordinates of a molecule, the surface of a 3D object, or many other things.

The following representations of an $D$-dimensional point cloud are valid for use with this package:

  • a matrix with $D$ rows where each column represents one point (i.e. pointcloud isa AbstractMatrix{<: Real}),
  • a vector of vectors, all of length $D$, where each element represents one point (i.e. pointcloud isa AbstractVector{<: AbstractVector{<: Real}}),
  • an instance of PointCloud, the type that this package uses internally and every other representation is converted to; provides the most control and performance guarantees (i.e. pointcloud isa PointCloud{D}).
PointCloudRegistration.PointCloudType

Representation of a weighted point cloud. An instance pc of PointCloud{N, T} stores N-dimensional points with coordinate type T. Also, it acts as an AbstractMatrix{T} with N rows and length(pc.points) columns.

The purpose of this type is to bring the input data into a form that enables efficient execution of the registration algorithms. As for the public interface, you can consider PointCloud to be defined as

struct PointCloud{N, T} <: AbstractMatrix{T}
    points::AbstractVector{SVector{N, T}}
    weights::AbstractVector{<: Real}
    # ... private fields ...
end

with the SVector type from StaticArrays.jl.

Simple usage

You can construct a PointCloud from a matrix or a vector of vectors:

julia> PointCloud([1. 2. 3.; 4. 5. 6.])
2-dimensional point cloud with 3 points of eltype Float64
 1.0  2.0  3.0
 4.0  5.0  6.0
and unit weights

julia> PointCloud([[1., 4.], [2., 5.], [3., 6.]])
2-dimensional point cloud with 3 points of eltype Float64
 1.0  2.0  3.0
 4.0  5.0  6.0
and unit weights

Type stability

Since the dimensionality of the point cloud is part of the type, the two calls above are not type stable (unless the dimensionality can be inferred, e. g. when the number of rows of the matrix is statically known). This is not a big deal because every function operating on PointClouds is then type stable (function barrier). If you really want the construction of a PointCloud to be type stable, you can use the PointCloud{N} variant:

julia> PointCloud{2}([1. 2. 3.; 4. 5. 6.])
2-dimensional point cloud with 3 points of eltype Float64
 1.0  2.0  3.0
 4.0  5.0  6.0
and unit weights

julia> PointCloud{3}([1. 2. 3.; 4. 5. 6.])
ERROR: ArgumentError: matrix must have given number of rows 3
[...]

julia> isconcretetype(Core.Compiler.return_type(PointCloud, Tuple{Matrix{Float64}}))
false

julia> isconcretetype(Core.Compiler.return_type(PointCloud{2}, Tuple{Matrix{Float64}}))
true

Weights

Optionally, each point can have an individual non-negative weight.

julia> PointCloud([1. 2. 3.; 4. 5. 6.], [.5, 1., .5])
2-dimensional point cloud with 3 points of eltype Float64
 1.0  2.0  3.0
 4.0  5.0  6.0
and weights
 3-element Vector{Float64}
 0.5  1.0  0.5

If no weights are specified, implicit unit weights are used. (They are not explicitly stored and have minimal runtime cost for computations.)

source
PointCloudRegistration.PointCloudMethod
PointCloud(points)
PointCloud{N}(points)

Create a PointCloud from the given points (matrix or vector of vectors) and use implicit unit weights. Optionally provide the dimensionality N for better type inference.

source
PointCloudRegistration.PointCloudMethod
PointCloud(points, weights)
PointCloud{N}(points, weights)

Create a PointCloud from the given points (matrix or vector of vectors) and weights. Optionally provide the dimensionality N for better type inference.

source