Curve - Convex Polygon | Curve - Curve |
---|---|
CurveProximityQueries implements methods to compute the
- Closest Points
- Minimum Distance
- Tolerance Verification
- Collision Detection
between an absolutely continuous parametric curve and another object, or between two curves. If you find this package/work useful in your research please cite our paper:
@INPROCEEDINGS{Hovakimyan-RSS-19,
AUTHOR = {Arun Lakshmanan AND Andrew Patterson AND Venanzio Cichella AND Naira Hovakimyan},
TITLE = {Proximity Queries for Absolutely Continuous Parametric Curves},
BOOKTITLE = {Proceedings of Robotics: Science and Systems},
YEAR = {2019},
ADDRESS = {Freiburg im Breisgau, Germany},
MONTH = {June},
DOI = {10.15607/RSS.2019.XV.042}
}
julia> ] add CurveProximityQueries
Methods are available to create and manipulate Bernstein polynomials. A Bernstein polynomial with uniformly randomly sampled control points can be created with:
julia> rand(Bernstein{3, 6})
a 5th order Bernstein polynomial with control points at:
([0.345747, 0.149338, 0.609345], [0.86539, 0.736102, 0.31424], [0.20149, 0.167441, 0.662126], [0.975667, 0.468056, 0.505278], [0.371533, 0.477992, 0.83668], [0.322821, 0.973494, 0.93129])
with an arclength of 1.463398157000094
which constructs a 3D 5th order Bernstein polynomial. Control points can be directly fed to the constructor as well:
julia> cpts = [[0.0, 0.0], [1.0, 2.0], [2.0, 0.0], [3.0, 0.0]];
julia> c = Bernstein(cpts)
a 3rd order Bernstein polynomial with control points at:
([0.0, 0.0], [1.0, 2.0], [2.0, 0.0], [3.0, 0.0])
with an arclength of 3.714835124201342
Generally Bernstein polynomials are evaluated between Interval
from the IntervalArithmetic
package:
julia> c = Bernstein(cpts, limits=Interval(0.5, 2.5))
a 3rd order Bernstein polynomial with control points at:
([0.0, 0.0], [1.0, 2.0], [2.0, 0.0], [3.0, 0.0])
with an arclength of 3.714835124201342
The Bernstein
types are functors that evaluate the polynomial at some value.
julia> c(1.5)
2-element SArray{Tuple{2},Float64,1,2}:
1.5
0.75
Note, that the arclength is not a true arclength but an upper bound that is used by the proximity methods. This upper bound can be evaluated at an interval or from the beginning of the limit using:
julia> arclength(c, Interval(0.9, 1.4))
0.7839413641976036
julia> arclength(c, 1.0) # evaluates from 0.5 to 1.0
1.1826380733343569
Several algebraic operations over Bernstein polynomials are available for convenience: addition, subtraction, product with reals, differentiation.
Several obstacle types are provided with convenience macros from ConvexBodyProximityQueries.jl:
julia> @point rand(3)
ConvexPolygon{3,1,Float64}(SArray{Tuple{3},Float64,1,3}[[0.135678, 0.840508, 0.140532]])
julia> @line [0.,1.,1.], [1.,2.,1.] # point A, point B
ConvexPolygon{3,2,Float64}(SArray{Tuple{3},Float64,1,3}[[0.0, 1.0, 1.0], [1.0, 2.0, 1.0]])
julia> @rect [0.,0.], rand(2) # center, widths
ConvexPolygon{2,4,Float64}(SArray{Tuple{2},Float64,1,2}[[0.395191, 0.174093], [-0.395191, 0.174093], [-0.395191, -0.174093], [0.395191, -0.174093]])
julia> @square ones(3), 1.0 # center, width
ConvexPolygon{3,8,Float64}(SArray{Tuple{3},Float64,1,3}[[1.5, 1.5, 1.5], [0.5, 1.5, 1.5], [0.5, 0.5, 1.5], [1.5, 0.5, 1.5], [1.5, 1.5, 0.5], [0.5, 1.5, 0.5], [0.5, 0.5, 0.5], [1.5, 0.5, 0.5]])
Random convex polygons can be constructed for 2D:
julia> obs = randpoly([1., 2.], 0.5; scale=1.0, n=20) # center, rotation; scale, number of vertices
ConvexPolygon{2,20,Float64}(SArray{Tuple{2},Float64,1,2}[[0.642686, 2.36248], [0.622121, 2.34973], [0.42866, 2.06399], [0.412454, 2.0344], [0.454968, 1.98069], [0.499506, 1.92797], [0.599317, 1.82251], [0.62982, 1.79366], [0.659987, 1.76526], [0.733777, 1.71118], [0.87861, 1.63702], [1.07313, 1.54129], [1.46142, 1.68951], [1.46817, 1.72673], [1.48588, 1.85669], [1.46772, 2.06245], [1.3987, 2.23026], [1.30631, 2.4218], [1.20662, 2.61294], [0.88346, 2.47282]])
The formal definitions for each of the proximity queries can be found in the paper.
julia> minimum_distance(c, obs)
0.6542938586889715
julia> tolerance_verification(c, obs, 0.5)
true
julia> tolerance_verification(c, obs, 1.0)
false
julia> collision_detection(c, obs)
false
julia> pts = closest_points(c, obs)
([1.07313, 1.54129], [1.03968, 0.887853])
All the above tests can be performed when obs
is replaced with another parametric curve.
Plotting recipes are provided for the curves. For example to plot the closest points between obs
and c
, one can simply:
julia> plot(c); plot!(obs); plot!(pts)
Parametric curves can be user defined. For example, a monomial basis type can be created as a subtype of Curve{D, T}
where D
is the dimension of the curve and T
is the eltype:
struct Monomial{D, N, T} <: Curve{D, T}
coeff::SVector{N, SVector{D, T}}
limits::Interval{T}
end
Methods to compute the evaluation (as a functor), and arclength upper bound has to be provided (see paper for details).
Similarly, custom types for obstacles can be created. If the obstacles are convex, then only a support mapping for the custom type is required. However, if the obstacle is not convex then methods to compute the minimum_distance
, tolerance_verification
, and collision_detection
between a point in space and the object must be provided.