GeoPoly

User guide

GeoPoly is a Julia utility contained in the package MagGravPoly and developed for handling polygonal shapes in the framework of 2D to 2.75D potential-fields forward and inverse modeling.

Tutorial

Check the orientation of a polygon

First load the module and define a list of vertices of the poligonal bodies and the relative indices mapping each body to its vertices:

using MagGravPoly.GeoPoly
# vertices of the poligonal bodies
vertices  = [35.0 50.0;
             65.0 50.0;
             80.0 35.0;
             65.0 20.0;
             35.0 20.0;
             20.0 35.0]

# indices of vertices for the body
ind1 = collect(1:6)
bodyindices = [ind1]
# construct the poligonal body object
pbody = PolygBodies2D(bodyindices,vertices)

and then checks if the polygon is defined in a clockwise or counter-clockwise order:

# check about the order
for i=1:pbody.nbo
aclk = checkanticlockwiseorder(pbody.bo[i])
@show aclk
end
aclk = true

In fact plotting the polygon:

using PyPlot
figure()
for i=1:length(bodyindices)
x = copy(pbody.bo[i].ver1[:,1])
y = copy(pbody.bo[i].ver1[:,2])
append!(x,pbody.bo[i].ver1[1,1])
append!(y,pbody.bo[i].ver1[1,2])
p=PyPlot.plot(x,y,"-o")
for i=1:length(x)-1
s=string(i)
if i<=1
txtalign = "left"
else
txtalign = "right"
end
text(x[i],y[i],s=s,horizontalalignment=txtalign,
fontsize=16,verticalalignment="top")
end
end
gca().invert_yaxis()

is easy to see that is counter-clockwise oriented.

Check and fixing for crossing polygon sides

First load the module and define a list of vertices of the poligonal bodies and the relative indices mapping each body to its vertices:

using MagGravPoly.GeoPoly
# vertices of the poligonal bodies
vertices  = [35.0 50.0;
             80.0 35.0;
             65.0 50.0;
             65.0 20.0;
             35.0 20.0;
             20.0 35.0]

# indices of vertices for the body
ind1 = collect(1:6)
bodyindices = [ind1]
# construct the poligonal body object
pbody = PolygBodies2D(bodyindices,vertices)

Now checks for any crossing polygon side:

chk = checkpoly(pbody.bo)
@show chk[1]
:selfinters

In fact plotting the polygon:

using PyPlot
figure()
for i=1:length(bodyindices)
x = copy(pbody.bo[i].ver1[:,1])
y = copy(pbody.bo[i].ver1[:,2])
append!(x,pbody.bo[i].ver1[1,1])
append!(y,pbody.bo[i].ver1[1,2])
p=PyPlot.plot(x,y,"-o")
for i=1:length(x)-1
s=string(i)
if i<=1
txtalign = "left"
else
txtalign = "right"
end
text(x[i],y[i],s=s,horizontalalignment=txtalign,
fontsize=16,verticalalignment="top")
end
end
gca().invert_yaxis()

We can try to fix the polygonal geometries using the verpolyshift! function:

# polygon fixing
GeoPoly.verpolyshift!(pbody.bo)

and the results will be the following:

Public API

Data structures

MagGravPoly.GeoPoly.BodySegments2DType
struct BodySegments2D

Structure containing the segments of a polygonal body. To create an instance a set of indices have to be passed on.

Fields

  • ver1::SubArray: (x,y) for first set of vertices (beginning of segments)

  • ver2::SubArray: (x,y) for second set of vertices (end of segments)

  • nsegm::Integer: total number of segments

source
MagGravPoly.GeoPoly.PolygBodies2DType
struct PolygBodies2D

Structure containing a set of polygonal bodies (described by their segments and all vertices). To create an instance, input an array of vectors of indices (of vertices) for each body and the array of all the vertices.

Fields

  • bo::Vector{MagGravPoly.GeoPoly.BodySegments2D}: array of bodies defined by their vertices

  • nbo::Integer: number of polygonal bodies

  • allvert::AbstractMatrix{<:Real}: array of all vertices for all bodies

  • bodyindices::Vector{<:Vector{<:Integer}}: array indices relating to the vertices in allvert

source
Warning

Vertices of the polygonal bodies must be provided counterclockwise to the structure BodySegments2D to perform gravity & magnetic anomaly calculations using the functions in the packages MagGravPoly. To assess this use the function checkanticlockwiseorder.

MagGravPoly.GeoPoly.TopoEdgesType

Julia structure defining a topography as set of segments characterized by x and z coordinates and both angular coefficient and intercept.

Fields

  • verx::Vector{Vector{Float64}}: all x couples of topography coordinates

  • verz::Vector{Vector{Float64}}: all z couples of topography coordinates

  • mq::Vector{Vector{Float64}}: angular coefficients and segment intersepts of each coordinates couple

  • xz::Matrix{Float64}: 2D array of (x,z) coordinates for topography

source

Checking-geometries functions

Single polygonal body

MagGravPoly.GeoPoly.intersectpairpolyFunction
intersectpairpoly(
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D}
) -> Bool

Function to check if there are intersections beetween sides of a polygon in respect to neighbour polygons, returning a Boolean value (i.e. true or false).

source
MagGravPoly.GeoPoly.selfintersectpolyFunction
selfintersectpoly(
    bo::MagGravPoly.GeoPoly.BodySegments2D
) -> Bool

Check if there is any self-intersection for a single polygon, returning a Boolean value (i.e. true or false).

source
MagGravPoly.GeoPoly.checkallFunction
checkall(
    bos::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    topo::MagGravPoly.GeoPoly.TopoEdges
) -> Vector{Symbol}

Check if there is any self-intersection considering all polygons beyond to topography crossing, returning three string values.

source

Multiple polygonal bodies

MagGravPoly.GeoPoly.checktopoFunction
checktopo(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D}
) -> Bool

Function to check if there is some polygon crossing the topography, returning a Boolean value (i.e. true or false).

source
MagGravPoly.GeoPoly.checkpolyFunction
checkpoly(
    bos::Vector{MagGravPoly.GeoPoly.BodySegments2D}
) -> Tuple{Symbol, Symbol}

Check if there is any self-intersection considering all polygons, returning two string values.

source

Fixing-geometries functions

MagGravPoly.GeoPoly.verpolyshift!Function
verpolyshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D}
)
verpolyshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)
verpolyshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}},
    bup::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)

Function to check if there is intersection beetween sides of a polygon, trying to shift polygon vertices in order to avoid intersection. This algorithm shifts the polygon vertices in agreement with the mathematical properties of the Hamiltonian Dynamics.

source
MagGravPoly.GeoPoly.verpolyallshift!Function
verpolyallshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D}
)
verpolyallshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)
verpolyallshift!(
    borg::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}},
    bup::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)

Function to check if there are intersections beetween sides of a polygon in respect to neighbour polygons, trying to shift polygon vertices in order to avoid intersection. This algorithm shifts the polygon vertices in agreement with the mathematical properties of the Hamiltonian Dynamics.

source
MagGravPoly.GeoPoly.vertoposhift!Function
vertoposhift!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D}
)
vertoposhift!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)
vertoposhift!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    blow::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}},
    bup::Union{Nothing, Vector{MagGravPoly.GeoPoly.BodySegments2D}}
)

Function to check if there is some polygon crossing the topography, shifting the polygon vertices in order to avoid intersection. This algorithm shifts the polygon vertices in agreement with the mathematical properties of the Hamiltonian Dynamics.

source
MagGravPoly.GeoPoly.fixall!Function
fixall!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    qbo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    inters::Vector{Symbol}
)
fixall!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    qbo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    inters::Vector{Symbol},
    indices::Union{Nothing, Vector{Vector{<:Integer}}}
)
fixall!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    qbo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    inters::Vector{Symbol},
    indices::Union{Nothing, Vector{Vector{<:Integer}}},
    lowcon::Union{Nothing, Vector{Float64}}
)
fixall!(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    qbo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    inters::Vector{Symbol},
    indices::Union{Nothing, Vector{Vector{<:Integer}}},
    lowcon::Union{Nothing, Vector{Float64}},
    upcon::Union{Nothing, Vector{Float64}}
)

Function fixing polygons vertices in order to avoid intersection and topography crossing, changing sign to the corresponding elements in the momentum array. This algorithm is in agreement with the mathematical properties of the Hamiltonian Dynamics.

source

Useful functions

MagGravPoly.GeoPoly.checkbodyindicesFunction
checkbodyindices(
    bodyindicesorg::Vector{<:Vector{<:Integer}},
    verticesorg::AbstractMatrix{<:Real}
) -> Tuple{Vector{<:Vector{<:Integer}}, Any}

Function to check all polygons' vertices and bodyindices in order to make sure that vertices in common among polygons appear only once.

source
MagGravPoly.GeoPoly.Inter2SegmFunction
Inter2Segm(
    P1x::Float64,
    P1z::Float64,
    P2x::Float64,
    P2z::Float64,
    P3x::Float64,
    P3z::Float64,
    P4x::Float64,
    P4z::Float64
) -> Union{Nothing, Matrix{Float64}}

Function to check if there is intersection beetween two segments, defined by their vertices. The output returns the (x,z) coordinates of the point in the case of intersection.

source
MagGravPoly.GeoPoly.isInternalFunction
isInternal(
    bo::MagGravPoly.GeoPoly.BodySegments2D,
    px::Float64,
    pz::Float64
) -> Bool

Function to check if a point is internal to a polygon.

source
MagGravPoly.GeoPoly.checkmodelizdimFunction
checkmodelizdim(
    topo::MagGravPoly.GeoPoly.TopoEdges,
    bo::Vector{MagGravPoly.GeoPoly.BodySegments2D},
    perc::Real
)

Function to check if the topography extends both righward and leftward beyond the outermost polygons by a user-defined percentage (> 25%).

source