# \[ANN\] Meshes.jl - Computational Geometry in Julia

**URL:** <https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973>\
**Category:** Package Announcements\
**Tags:** package, announcement, mesh, geo, geometry\
**Created:** [January 26, 2021, 12:00pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973 "2021-01-26T12:00:03Z")\
**Posts on this page:** 19\
**Page:** 3

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 26, 2023, 7:18pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/41 "2023-11-26T19:18:52Z")

</div>

Check the Geospatial Data Science with Julia book:

[https://juliaearth.github.io/geospatial-data-science-with-julia](https://juliaearth.github.io/geospatial-data-science-with-julia)

Use a GeoTable.

---

<div class="post-metadata">

**Author:** ![BambOoxX](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bambooxx/32/22179_2.png) [@BambOoxX](https://discourse.julialang.org/u/BambOoxX)\
**Post date:** [November 26, 2023, 8:59pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/42 "2023-11-26T20:59:53Z")

</div>

Thanks for the tip ! I just went through the book, and I feel like I’m missing some things.

1. It feels like everything is based on the data values at geometry points, but no data can be linked directly with the elements, is that so ?
2. How do you dispatch plotting recipes based on a given `georef`. In my current practice, I have a dedicated `Mesh`-like type that stores all the info and then I use a custom recipe based on various `Makie` basic recipes to do the job. What would be the `Meshes` to achieve that ? Dispatch on the column names of the `geotable` ?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [November 26, 2023, 10:43pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/43 "2023-11-26T22:43:56Z")

</div>

The geometry column can contain any geometry, not just points.

The recipes are dispatched on Domain types which are collections of geometries.

Please let us know if something is not clear. Better ask on Zulip to avoid spamming everyone in this thread.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 22, 2024, 2:12pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/44 "2024-05-22T14:12:30Z")

</div>

# Meshes.jl v0.43

@eliascarv and I are super excited to share a new release of the project, after months of hard work to formalize coordinate reference systems (CRS) with Julia types. This release comes with many breaking changes, which are needed for real-world usage of meshes in industrial applications.

The main innovation that puts us years ahead of other mesh/GIS software out there is the ability to abstract CRS information in type parameters, without increasing memory requirements.

Every point now has a well-defined set of coordinates with Unitful.jl units thanks to CoordRefSystems.jl, and we can carry this important information forward in algorithms without runtime nor storage penalties:

```julia
julia> Point(1,2,3)
Point with Cartesian{NoDatum} coordinates
├─ x: 1.0 m
├─ y: 2.0 m
└─ z: 3.0 m

julia> using CoordRefSystems

julia> Point(Polar(0,0))
Point with Polar{NoDatum} coordinates
├─ ρ: 0.0 m
└─ ϕ: 0.0 rad

```

All geometries and domain types also have this CRS information, which is useful to dispatch specialized algorithms on non-Cartesian coordinates.

We are effectively solving the “implicit” approach to CRS handling where users are responsible for magically finding the CRS of their data.

## Breaking changes

- The `coordinates` function is no longer present. Use the `to` function instead to return the `Vec` from the origin to a given `Point`.
- Geometry and domain types no longer have a type parameter `T` . They still have a `Dim` parameter as in `Geometry{Dim}`.
- All points and vectors have unitful coordinates. End-users are not supposed to handle these coordinates directly, but we provide a function `coords(point)` for that. Most times, the `to` function is what is needed.

## Roadmap

The roadmap for the following weeks consists of updating the rest of the GeoStats.jl stack to accommodate this new release with CRS support, and fix miscellaneous issues that are listed [here](https://github.com/JuliaGeometry/Meshes.jl/issues/839).

---

<div class="post-metadata">

**Author:** ![kylebeggs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kylebeggs/32/43348_2.png) [@kylebeggs](https://discourse.julialang.org/u/kylebeggs)\
**Post date:** [May 22, 2024, 5:37pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/45 "2024-05-22T17:37:07Z")

</div>

This is great to see! What was the motivation for the naming of `to` function? It seems a bit strange to me. I would have never guessed it returns the vector (`Vec`) from the origin. Why not just allow people to use `Vec`?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 22, 2024, 5:52pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/46 "2024-05-22T17:52:40Z")

</div>

This function takes any point and returns the geometric vector `point - origin`, i.e. our `Vec`. The motivation in the name comes `from` origin to `point`.

This is a very specific operation that is not very useful in curved manifolds for example, where the vector connecting the origin of the CRS to the point does not belong to the surface. We will add more features like this in the future, and associated functions.

The name `to` was the shortest name that we found. Given that it is used a lot in implementations, it is convenient to keep it short.

---

<div class="post-metadata">

**Author:** ![cserteGT3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csertegt3/32/8283_2.png) [@cserteGT3](https://discourse.julialang.org/u/cserteGT3)\
**Post date:** [May 22, 2024, 6:33pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/47 "2024-05-22T18:33:46Z")

</div>

Awesome news! Even though I’m not the target audience for this feature, I’m happy to see the active development of the package.

I’m wondering if there are any plans for Makie.jl to use Meshes.jl under the hood? Or Meshes.jl doesn’t want to be the new GeometryBasics.jl package.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 22, 2024, 6:51pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/48 "2024-05-22T18:51:43Z")

</div>

I can answer from the Meshes.jl side that we don’t see any issue with this idea of providing the geometric processing infrastructure for Makie.jl. Both projects would certainly benefit from tons of features, and human resources would be used more wisely.

---

<div class="post-metadata">

**Author:** ![henry2004y](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henry2004y/32/9284_2.png) [@henry2004y](https://discourse.julialang.org/u/henry2004y)\
**Post date:** [May 29, 2024, 3:35am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/49 "2024-05-29T03:35:58Z")

</div>

v0.43 automatically adds units to all the points, which are by default [m] . Is it possible to use a customized unit system, or simply turn off the units?

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 29, 2024, 10:24am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/50 "2024-05-29T10:24:10Z")

</div>

Hi @henry2004y , the following is true now:

`Point(xyz...) = Point(Cartesian(xyz...))`

This means that `Point(1, 2, 3)` is syntactic sugar to construct `Cartesian` coordinates from CoordRefSystems.jl If the coordinates don’t have appropriate units, then [m] will be added as you said. But if the coordinates already have length (L) units, they will pass just fine:

```julia
julia> using Meshes
julia> using Unitful

julia> Point(1u"km", 2u"km", 3u"ft")
Point with Cartesian{NoDatum} coordinates
├─ x: 1000.0 m
├─ y: 2000.0 m
└─ z: 0.9144 m

```

We don’t allow unit-less coordinates anymore because that is the root of all evil in geospatial software. Pretend that the default [m] units always existed implicitly, and that they are just explicit now. Algorithms will be more robust as a consequence, and everything else such as distances, measures, etc. will have a clear physical interpretation:

```julia
julia> area(rand(Triangle{2}))
0.07232380768033886 m^2

```

---

<div class="post-metadata">

**Author:** ![ederag](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ederag/32/4106_2.png) [@ederag](https://discourse.julialang.org/u/ederag)\
**Post date:** [May 31, 2024, 6:07am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/51 "2024-05-31T06:07:22Z")

</div>

> if the coordinates already have length (L) units, they will pass just fine

Meshes can be useful in other spaces  
(for instance in reciprocal space, units may be `rad / nm`).

```julia-repl
julia> using Meshes
julia> using Unitful
julia> Point(1u"rad/nm", 2u"rad/nm")
ERROR: ArgumentError: invalid units for coordinates, please check the documentation

```

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [May 31, 2024, 9:27am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/52 "2024-05-31T09:27:16Z")

</div>

Check CoordRefSystems.jl for other coordinate types with angle units.

Point(Polar(…)) like in the example above.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [June 15, 2024, 5:35pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/53 "2024-06-15T17:35:28Z")

</div>

# Meshes.jl v0.45

### New transforms:

- `Proj` for changing the CRS of geometries, domains and geotables  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/d/4d1c35f0d0345430a0a873282a52ad65307a3aff.png)
- `Shadow` for computing the “shadow” of a 3D domain onto XY, XZ or YZ  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/a/1/a19717925b6593b4b481299cc8b36cb38bf73479.png)
- `LenghtUnit` for changing the lenght unit of geometries and domains  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/b/dbb3e0ecbf4052fd7fee0f1e6cf1a1ce2c39c87e.png)

### New discretization/tesselation:

- `DelaunayTriangulation` of geometries  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/6/0604673f586a077f452b357bb83f62e48ecb1375.png)
- `DelaunayTesselation` of point sets  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/b/1/b191f407ea4b92d5d695bf6500d564b3ff250491.jpeg)
- `VoronoiTesselation` of point sets  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/4/1/41cfb9f3de19a65f5d99cc937f4671ace92ee9a1.png)

### Breaking changes

(Multi-)polygons with more than 5000 vertices are now discretized with `DelaunayTriangulation` by default. `DehnTriangulation` is preferred for smaller polygons because it is faster.

- `FIST` renamed to `HeldTriangulation`
- `Dehn1899` renamed to `DehnTriangulation`

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 13, 2024, 11:33am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/54 "2024-07-13T11:33:15Z")

</div>

Quick updates:

- Addition of `Wedge` geometry as a 3-Polytope

- Discretization of `Cylinder` into `Hexahedron` and `Wedge` geometries

![image](https://global.discourse-cdn.com/julialang/original/3X/c/8/c84bec3249eb9d7596ca9d1da2b976d14fe8f869.png)

- New `sideof(point, ring)` and `point ∈ poly` with Hao et al. algorithm, which we implemented with multiple-threads. Speedup of ~12x. The algorithm is quite robust, and can handle all sorts of degenerate cases in 2D polygonal areas:

![image](https://global.discourse-cdn.com/julialang/original/3X/7/9/7943ce409efbb10ac300a986d5f67d2954cdab2a.png)

- Angles with explicit `rad` units:

```julia
julia> ∠(Vec(1, 0), Vec(0, 1))
1.5707963267948966 rad

```

- Addition of various CRS for georeferencing data in Brazil, including the `Aratu`, `SAD69`, `SAD96` and `SIRGAS2000` datums:

> <https://github.com/JuliaEarth/CoordRefSystems.jl/blob/3bed4bb6a6c8f6f9063568c6578749d63863c98d/src/get.jl#L29-L47>

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [July 24, 2024, 9:14pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/55 "2024-07-24T21:14:15Z")

</div>

# Meshes.jl v0.47

This release introduces support for **non-Euclidean manifolds** , which means that geometries can be “overlaid” over surfaces such as ellipsoids of revolution representing the Earth.

To give an example, consider the construction of a triangle using `LatLon` coordinates for the vertices:

```julia
julia> using Meshes
julia> using CoordRefSystems

julia> triangle = Triangle(Point(LatLon(0, 0)), Point(LatLon(0, 90)), Point(LatLon(90, 0)))
Triangle
├─ Point(lat: 0.0°, lon: 0.0°)
├─ Point(lat: 0.0°, lon: 90.0°)
└─ Point(lat: 90.0°, lon: 0.0°)

julia> manifold(triangle)
🌐

```

The manifold is automatically detected from the CRS of the points at compile-time, leading to a geodesic triangle over the globe.

Since all our geometry and domain types have an explicit manifold, we can now dispatch specialized algorithms from geodesic geometry.

This is the last major refactor that we had planned before v1.0. We will test the design over the rest of the year before making the first major release official.

We invite all potential users and collaborators to give it a try. Now is the time to report issues and suggest breaking changes.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [August 8, 2024, 10:04pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/56 "2024-08-08T22:04:51Z")

</div>

For those interested in geographic applications:

> [@\[ANN\] GeoStats.jl - Geospatial Data Science and Geostatistical Modeling in Julia](https://discourse.julialang.org/t/ann-geostats-jl/101054/17):
>
> A few tweaks here and there, and we are now able to visualize moderately large “raster” data stored in GeoTIFF files with any CRS in native Julia. To illustrate the feature, consider the following example with data from the NaturalEarth project: using GeoStats using GeoIO import GLMakie as Mke # https://www.naturalearthdata.com/downloads/50m-raster-data/50m-gray-earth raster = GeoIO.load("GRAY\_50M\_SR\_OB.tif") |\> Coerce(Continuous) # upscale for 3D mesh visualization coarse = raster |\> Upsca…

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [October 24, 2024, 11:53am UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/57 "2024-10-24T11:53:34Z")

</div>

For those interested in differential forms and integrals, @mike.ingold @JoshuaLampert and @kylebeggs are working on AD rules for Meshes.jl geometries:

> **[GitHub - JuliaGeometry/MeshIntegrals.jl: Numerical integration over Meshes.jl geometry...](https://github.com/JuliaGeometry/MeshIntegrals.jl)**
>
> Numerical integration over Meshes.jl geometry domains

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 11, 2025, 12:53pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/58 "2025-12-11T12:53:42Z")

</div>

## Meshes.jl v0.56

It is been a long time since our last update here. I am just bumping the thread to say that Meshes.jl v0.56 is out with **lots of fixes** and **performance improvements**. If you didn’t update your environment in a while, now it is a good time.

For those interested in non-Euclidean geometry, we have refactored our internal discretization routines massively to get optimal performance with “flat” geometries, and custom refinement with geometries over other manifolds. Below are a few examples of 1D Bezier curves and 2D triangles embedded on Earth’s surface:

```julia
using Meshes
using CoordRefSystems
import GLMakie

curves = rand(BezierCurve, 10, crs=LatLon)
triangles = rand(Triangle, 2, crs=LatLon)

viz(curves, color="cyan")
viz!(triangles, color="red")

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/1/c1d628f5c4e2f0611220e85bc4993bd44978a869.jpeg)

You can control the level of refinement with the `MAXLEN` scoped value as documented here:

> **[Tolerances · Meshes.jl](https://juliageometry.github.io/MeshesDocs/stable/tolerances/)**
>
> Documentation for Meshes.jl.

By default, we use `500km` as the maximum length of segments in the refined meshes over the Earth surface. Some applications might require smaller tolerances:

```julia
using ScopedValues

with(Meshes.MAXLEN => 100km) do
  viz(triangles) # finer meshes in visualization
end

```

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [April 9, 2026, 2:30pm UTC](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973/59 "2026-04-09T14:30:46Z")

</div>

## Meshes.jl v0.57

Thanks to the work of various contributors (Michael Ingold, Guillaume Dalle, Kyle Beggs, Joshua Lampert, Pablo San-Jose, Zoïs Moitier), we now have full support for differential and integral calculus with Meshes.jl geometries and domains:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/b/8be83c3eccd7fb0ddeb33192c0b5cf580833324c.jpeg)

> **Click to see code**
>
> ```julia
> using Meshes
> using CoordRefSystems
> 
> import GLMakie as Mke
> 
> # curved quadrangle over the globe
> q = Quadrangle(Point(LatLon(0, 0)), Point(LatLon(0, 90)), Point(LatLon(80, 90)), Point(LatLon(80, 0)))
> 
> # Jacobian components as rays over the quadrangle
> uv = Iterators.product(0:0.1:1, 0:0.1:1)
> rs = [Ray.(q(u, v), 0.05 .* jacobian(q, (u, v))) for (u, v) in uv]
> 
> # split rays into u and v components
> rᵤ = first.(rs) |> vec
> rᵥ = last.(rs) |> vec
> 
> viz(q, color="teal")
> viz!(rᵤ, color="gray80")
> viz!(rᵥ, color="gray80")
> 
> # Bezier curve over the globe
> c = BezierCurve(Point(LatLon(0, 0)), Point(LatLon(40, 90)), Point(LatLon(80, 0)))
> 
> # Jacobian components as rays over the curve
> ts = 0:0.1:1
> rs = [Ray.(c(t), 0.05 .* jacobian(c, (t,))) for t in ts]
> 
> # extract t component
> rₜ = first.(rs) |> vec
> 
> viz!(c, color="yellow", segmentsize=4)
> viz!(rₜ, color="magenta")
> 
> Mke.current_figure()
> 
> ```

We support any differentiation backend from DifferentiationInterface.jl and any integration backend from IntegrationInterface.jl, and use ForwardDiff.jl and HAdaptiveIntegration.jl by default.

We use this new feature to compute lengths and areas of curved geometries with unprecedented accuracy (automatic differentiation + h-adaptive integration) given that

`area(g) = integral(_ -> 1, g)`

Please let us know if you encounter any problems.

[Previous page](https://discourse.julialang.org/t/ann-meshes-jl-computational-geometry-in-julia/53973.md?page=2)
