-
Notifications
You must be signed in to change notification settings - Fork 1
First Meetup Minutes
This meeting originated from the observation that numerous Julia packages define some notion of a point or vector in a coordinate system, often including operations on these type, with use cases including visualization, graphics, rendering, and geography.
In an attempt to reconcile notions of length units used by Compose, Escher, and Compose3D, a unified measures system was prototyped in Measures.jl, and discussed during the meeting. These packages operate on coordinate systems that are not necessarily fully determined when the graphic or layout is being defined, so they must represent lengths as simple expressions, for example 1mm + 1w
, where w
is the width of the not yet determined bounding box.
While Measures.jl
was suitable for these packages, it wasn't clear if it we could generalize it to be more broadly useful to JuliaGeo and JuliaGeometry packages.
We discussed whether functionality similar to FixedSizeArrays.jl and GeometryTypes.jl can be implemented with tuples, now that tuples are performant. This approach was taken in Measures.jl, and we were hopeful we could generalize it elsewhere.
We used as an example, a type defined in Geodesy.jl.
immutable LLA{T <: Datum}
lat::Float64
lon::Float64
alt::Float64
end
This type is annotated to allow dispatch on the Datum type. The same affect could be achieved by defining similarly parameterized types for latitude, longitude, and altitude within a tuple.
immutable Latitude{T <: Datum}
value::Float64
end
immutable Longitude{T <: Datum}
value::Float64
end
immutable Altitude{T <: Datum}
value::Float64
end
typealias LLA{T <: Datum} Tuple{Latitude{T}, Longitude{T}, Altitude{T}}
Defining this type as a plain tuple has some appealing properties. LLA
can be constructed as simply (lat, lon, alt)
, and the Datum information accompanies the individual components, for example.
It has some downsides as well. We can no longer say just lla.lat
to access a number representing latitude. We must say lla[1].value
. In the future, this might be mitigated by defining a getfield
function (see https://github.com/JuliaLang/julia/issues/1974).
function getfield(lla::LLA, name::Symbol)
if name == :latitude
return lla[1].value
elseif name == :longitude
return lla[2].value
elseif name == :altitude
return lla[3].value
else
error("No field $(name)")
end
end
In the end, we ultimately felt somewhat unenthusiastic about this idea. The primary exception is that if we definite some coordinate types this way, it seems they all should for consistency, yet some coordinate types need no extra parameterization. E.g.
immutable ECEF
x::Float64
y::Float64
z::Float64
end
To define this type in the same tuple idiom, we would say
immutable ECEFX
value::Float64
end
immutable ECEFY
value::Float64
end
immutable ECEFZ
value::Float64
end
typealias ECEF (ECEFX, ECEFY, ECEFZ)
This struck us as a little awkward or contrived compared to the original definition. A similar situation arises if we want to color types, such as the ones defined Color.jl. These can be thought of as points in a coordinate system, so we might desire to bring these under a unified coordinate type system as well, but it's difficult to justify replacing very obvious and direct definitions like
immutable RGB{T}
r::T
g::T
b::T
end
unless there is some very clear benefit.
Ultimately, a path forward to unify all coordinate types remained unclear. Measures.jl improves the situation, as defining polygons and geometry that's useable by Compose is no longer strictly coupled to Compose. The status quo of numerous incompatible 2d and 3d vector types remains unsatisfying, though. Any more broad solution will need to provide concreted advantage without necessitating substantial boilerplate code to define simple types.
The immediate plan is to proceed with Measures in it's initial, limited scope, while continuing to discuss a solution with a broader scope.
Beyond points and vectors, simply geometry types are redefined in several packages. For example some variation of
immutable Circle
center::Point
radius::T
end
is defined multiple times. Since some Point
type is used here, unifying simple geometry types like these is dependent on also unifying point and vector types. GeometryTypes.jl is a good starting point, but will need to be generalized to be suitable to all packages.
Continuing with the example of a circle, GeometryTypes defines it as
immutable Circle{T}
center::Point2{T}
r::T
end
This definition, while suitable for many purposes, is too restrictive for Compose, in which the type of the radius, and the center x- and y-coordinate may all be different. This necessitates a definition more like,
immutable Circle{T, U, V}
center::Point2{T, U}
r::V
end
Generalizing GeometryTypes is a feasible solution, though its vector and point types are defined using FixedSizeArrays functionality which restricts these definitions to using the same type for every coordinate.