Skip to content

coordinates of a Polygon #69

Closed
Closed
@visr

Description

@visr

I have a pretty simple question but I can't seem to find the answer. I'll walk through my attempts, and have some more general questions about coordinates.

Given pol, how do I get a vector like pts back? I only need the exterior.

pts = Point{2, Int}[(3, 1), (4, 4), (2, 4), (1, 2), (3, 1)]
pol = Polygon(pts)

My first guess was coordinates

julia> coordinates(pol.exterior)
4-element reinterpret(GeometryBasics.Ngon{2,Int64,2,Point{2,Int64}}, ::TupleView{Tuple{Point{2,Int64},Point{2,Int64}},2,1,Array{Point{2,Int64},1}}):
 Line([3, 1] => [4, 4])
 Line([4, 4] => [2, 4])
 Line([2, 4] => [1, 2])
 Line([1, 2] => [3, 1])

Somewhat surprisingly to me coordinates returns lines, not points. Of course I can dig deeper and get the coordinates of those:

julia> coordinates.(coordinates(pol.exterior))
4-element Array{StaticArrays.SArray{Tuple{2},Point{2,Int64},1,2},1}:
 [[3, 1], [4, 4]]
 [[4, 4], [2, 4]]
 [[2, 4], [1, 2]]
 [[1, 2], [3, 1]]

But now every inner point appears twice, which is not what I want. I think the TupleView is giving a lines view over the points that I want, but how do I get them? The coordinates documentation says to try decompose:

coordinates(geometry)

Returns the edges/vertices/coordinates of a geometry. Is allowed to return lazy iterators!
Use decompose(ConcretePointType, geometry) to get Vector{ConcretePointType} with
ConcretePointType to be something like Point{3, Float32}.

But that errors, is this a bug or am I using it wrongly?

julia> decompose(Point{2, Int}, pol.exterior)
ERROR: MethodError: no method matching Int64(::Point{2,Int64})
Closest candidates are:
  Int64(::Union{Bool, Int32, Int64, UInt32, UInt64, UInt8, Int128, Int16, Int8, UInt128, UInt16}) at boot.jl:708
  Int64(::Ptr) at boot.jl:718
  Int64(::Float32) at float.jl:706
  ...
Stacktrace:
 [1] (::GeometryBasics.var"#152#153"{Int64,GeometryBasics.Ngon{2,Int64,2,Point{2,Int64}},Int64})(::Int64) at C:\Users\visser_mn\.julia\dev\GeometryBasics\src\geometry_primitives.jl:57
 [2] ntuple at .\ntuple.jl:18 [inlined]
 [3] convert_simplex at C:\Users\visser_mn\.julia\dev\GeometryBasics\src\geometry_primitives.jl:57 [inlined]
 [4] collect_with_eltype(::Type{Point{2,Int64}}, ::Base.ReinterpretArray{GeometryBasics.Ngon{2,Int64,2,Point{2,Int64}},1,Tuple{Point{2,Int64},Point{2,Int64}},TupleView{Tuple{Point{2,Int64},Point{2,Int64}},2,1,Array{Point{2,Int64},1}}}) at C:\Users\visser_mn\.julia\dev\GeometryBasics\src\geometry_primitives.jl:76
 [5] decompose(::Type{Point{2,Int64}}, ::LineString{2,Int64,Point{2,Int64},Base.ReinterpretArray{GeometryBasics.Ngon{2,Int64,2,Point{2,Int64}},1,Tuple{Point{2,Int64},Point{2,Int64}},TupleView{Tuple{Point{2,Int64},Point{2,Int64}},2,1,Array{Point{2,Int64},1}}}}) at C:\Users\visser_mn\.julia\dev\GeometryBasics\src\interfaces.jl:104
 [6] top-level scope at REPL[21]:1

Maybe a little aside, but what is the main benefit of having coordinates return a line or point depending on the type? The field names in the code are a bit confusing as well, since coordinates(x::LineString) = x.points, but x.points are lines. I can see linestrings as either a collection of points or a vector of lines, so perhaps it would be better to have distinct functions for those? Because this seems a bit inconsistent at times, as we saw above coordinates(::Polygon) returns lines, but if we put in an Ngon, a fixed size polygon, then we get the points:

julia> tri = Triangle{2, Float64}([(3, 1), (4, 4), (2, 4)])
Triangle([3.0, 1.0], [4.0, 4.0], [2.0, 4.0])

julia> coordinates(tri)
3-element StaticArrays.SArray{Tuple{3},Point{2,Float64},1,3} with indices SOneTo(3):
 [3.0, 1.0]
 [4.0, 4.0]
 [2.0, 4.0]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions