Skip to content
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

#666 - Concrete Minkowski sum for polygons #1377

Merged
merged 1 commit into from
May 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/lib/representations.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ constraints_list(::VPolygon{N}) where {N<:Real}
translate(::VPolygon{N}, ::AbstractVector{N}) where {N<:Real}
remove_redundant_vertices(::VPolygon{N}; ::String="monotone_chain") where {N<:Real}
remove_redundant_vertices!(::VPolygon{N}; ::String="monotone_chain") where {N<:Real}
minkowski_sum(::VPolygon{N}, ::VPolygon{N}) where {N<:Real}
```
Inherited from [`LazySet`](@ref):
* [`norm`](@ref norm(::LazySet, ::Real))
Expand Down
58 changes: 57 additions & 1 deletion src/VPolygon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export VPolygon,
remove_redundant_vertices,
remove_redundant_vertices!,
convex_hull,
linear_map
linear_map,
minkowski_sum

"""
VPolygon{N<:Real} <: AbstractPolygon{N}
Expand Down Expand Up @@ -553,3 +554,58 @@ function translate(P::VPolygon{N}, v::AbstractVector{N}) where {N<:Real}
"set by a $(length(v))-dimensional vector"
return VPolygon([x + v for x in vertices_list(P)])
end

"""
mforets marked this conversation as resolved.
Show resolved Hide resolved
minkowski_sum(P::VPolygon{N}, Q::VPolygon{N}) where {N<:Real}

The Minkowski Sum of two polygon in vertex representation.
SebastianGuadalupe marked this conversation as resolved.
Show resolved Hide resolved

### Input

- `P` -- polygon in vertex representation
- `Q` -- another polygon in vertex representation

### Output

A polygon in vertex representation.

### Algorithm

We treat each edge of the polygons as a vector, attaching them in polar order
(attaching the tail of the next vector to the head of the previous vector). The
resulting polygonal chain will be a polygon, which is the Minkowski sum of the
given polygons. This algorithm assumes that the vertices of P and Q are sorted
in counter-clockwise fashion and has linear complexity O(m+n) where m and n are
the number of vertices of P and Q respectively.

mforets marked this conversation as resolved.
Show resolved Hide resolved
"""
function minkowski_sum(P::VPolygon{N}, Q::VPolygon{N}) where {N<:Real}
vlistP = vertices_list(P)
vlistQ = vertices_list(Q)
mP = length(vlistP)
mQ = length(vlistQ)
i = 1
k = 1
j = 1
R = Vector{Vector{N}}(undef, mP+mQ)
fill!(R, N[0, 0])
while i <= size(R, 1)
P₁, P₂ = vlistP[(k-1)%mP+1], vlistP[(k%mP+1)]
P₁P₂ = P₂ - P₁
Q₁, Q₂ = vlistQ[(j-1)%mQ+1], vlistQ[(j%mQ+1)]
Q₁Q₂ = Q₂ - Q₁
R[i] = P₁ + Q₁
turn = right_turn(P₁P₂, Q₁Q₂, N[0, 0])
if turn > 0
k += 1
elseif turn < 0
j += 1
else
pop!(R)
mforets marked this conversation as resolved.
Show resolved Hide resolved
k += 1
j += 1
end
i += 1
end
return VPolygon(R)
end
20 changes: 20 additions & 0 deletions test/unit_Polygon.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,26 @@ for N in [Float64, Float32, Rational{Int}]
@test translate(hp, N[1, 2]) == typeof(hp)(
[HalfSpace(N[2, 2], N(18)), HalfSpace(N[-3, 3], N(9)),
HalfSpace(N[-1, -1], N(-3)), HalfSpace(N[2, -4], N(-6))])

# test for concrete minkowski sum
A = [N[4, 0], N[6, 2], N[4, 4]]
B = [N[-2, -2], N[2, 0], N[2, 2], N[-2, 4]]

P = VPolygon(A)
Q = VPolygon(B)
PQ = minkowski_sum(P, Q)
@test LazySets.ispermutation(PQ.vertices, [N[2, -2], N[6, 0], N[8, 2],
N[8, 4], N[6, 6], N[2, 8]])

#test for corner case of parallel edges in minkowski sum
C = [N[10, 5], N[10, 10], N[8, 10], N[5, 8], N[5, 5]]
D = [N[-1, -2], N[1, -2], N[-1, 2]]

R = VPolygon(C)
S = VPolygon(D)
RS = minkowski_sum(R, S)
@test LazySets.ispermutation(RS.vertices, [N[4, 3], N[11, 3], N[11, 8],
N[9,12], N[7, 12], N[4, 10]])
end

# concrete intersection of H-rep
Expand Down