Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way of representing polygonal chain

I want to have a struct to represent a 3D polygonal chain. I have a struct Point that represents a point in 3D, so my struct must basically be a tuple of points as chains will not increase in number of segments. I need to have the struct because I will define and work with methods exclusive for polygonal chains.

I have it defined as a parametric type in the following way:

struct PolygonalChain{N}
    endpoints::NTuple{N,Point}
end

Where N is supposed to be an integer. I am not sure if this is the best way. I know that parameters in parametric types are supposed to be DataTypes and not concrete instances of types. I am not sure if I could just use Tuples in a smarter way and not define any struct

like image 907
choforito84 Avatar asked Dec 06 '25 03:12

choforito84


1 Answers

In such cases the most two important things are performance and comfort of the API.

Firstly, I would give the type of point as parametric type as one is never limited to only three dimension. Since it is a parametric type it will not affect the performance.

Secondly, you need a comfortable constructor so you do not need to explicitly create a tuple whenever creating your object.

Lastly, since you will be accessing elements of your PolygonalChain frequently so it should behave like a Vector so you do not need to type the field name every time.

Here is how such nice API can be accomplished in Julia:

abstract type AbstractPoint end
struct Point1d <: AbstractPoint 
   x::Float64
end

struct PolygonalChain{N,P <: AbstractPoint} <: AbstractVector{P}
    endpoints::NTuple{N,P}
end
PolygonalChain(x...) =  PolygonalChain((x...,))

Base.size(p::PolygonalChain{N, P}) where {N,P} = (N, )
Base.getindex(p::PolygonalChain, idx::Int) = p.endpoints[idx]

Now let's test it. Note how we use the constructor (no tuple!), how it gets displayed and how points can be accessed:

julia> p=PolygonalChain(Point1d(1.0),Point1d(3.0))
2-element PolygonalChain{2, Point1d}:
 Point1d(1.0)
 Point1d(3.0)

julia> p[1]
Point1d(1.0)
like image 124
Przemyslaw Szufel Avatar answered Dec 09 '25 18:12

Przemyslaw Szufel