# Tracing Geodesic Paths

The function `traceGeodesic`

allows one to compute straightest paths along a surface (i.e. *geodesic* paths).

Note that straightest paths depend only on the *intrinsic* geometry of a surface (via the `IntrinsicGeometryInterface`

). Therefore, these routines can be run on abstract geometric domains as well as traditional surfaces in 3D. However, these routines do assume that the domain is a `ManifoldSurfaceMesh`

.

`#include "geometrycentral/surface/trace_geodesic.h"`

`TraceGeodesicResult traceGeodesic(IntrinsicGeometryInterface& geom, SurfacePoint startP, Vector2 traceVec, const TraceOptions& traceOptions = defaultTraceOptions);`

Trace a geodesic path along a surface mesh.

`inputGeom`

: the input geometry (as always, a`VertexPositionGeometry`

is valid input)`startP`

: the point on the surface where the path should start`traceVec`

: the direction the path should proceed in, and the distance that it should travel`traceOptions`

: options to specify the behavior of`traceGeodesic`

in various situations

The function `traceGeodesic`

traces out a geodesic path starting at `startP`

which proceeds in the direction of `traceVec`

and has length equal to `traceVec.norm()`

, unless the path intersects a boundary edge in which case it stops there.
This is also known as the *exponential map*. (As an aside, `geometry-central`

also provides procedures for computing the inverse of the exponential map, known as the logarithmic map.)

### Example

```
#include "geometrycentral/surface/meshio.h"
#include "geometrycentral/surface/surface_point.h"
#include "geometrycentral/surface/trace_geodesic.h"
// Load a mesh
std::unique_ptr<ManifoldSurfaceMesh> mesh;
std::unique_ptr<VertexPositionGeometry> geometry;
std::tie(mesh, geometry) = readManifoldSurfaceMesh(filename);
Vertex v = mesh->vertex(0);
Vector2 traceVec = 3 * Vector2::fromAngle(M_PI/6);
SurfacePoint pathEndpoint = traceGeodesic(*geometry, SurfacePoint(v), traceVec).endPoint;
```

## Helper Types

### Options

Options are passed in to `traceGeodesic`

via a `TraceOptions`

object.

Field | Default value | Meaning |
---|---|---|

`bool includePath` |
`false` |
whether to return the entire path trajectory (as opposed to merely returning the path’s endpoint) |

`bool errorOnProblem` |
`false` |
whether to throw exceptions if the procedure encounters degenerate geometry |

`EdgeData<bool>* barrierEdges` |
`nullptr` |
if set, paths will stop when they hit barrier edges |

`size_t maxIters` |
`INVALID_IND` |
if set, paths will stop after traversing through `maxIters` faces |

### Result

The result is returned as a `TraceGeodesicResult`

, which has 5 fields:

Field | Meaning |
---|---|

`SurfacePoint endPoint` |
the point the path ended at |

`std::vector<SurfacePoint> pathPoints` |
all points along the path, including start and end |

`Vector2 endingDir` |
the incoming direction to the final point, in its tangent space |

`bool hitBoundary` |
did the path stop early because we hit a boundary? |

`bool hasPath` |
is `pathPoints` populated? |

`double length` |
length of the traced path (generally equals norm of `traceVec` unless tracing stopped early due to hitting a boundary/barrier edge or due to the iteration limit `maxIters` ) |

## Tangent Spaces

The input `traceVec`

is specified as a vector in the *tangent space* of the starting point. The meaning of this vector depends on whether the starting point is located on a vertex, edge, or face of the mesh. Tangent space in geometry central are discussed in more detail on the Quantities page, but we give a brief overview here.

Given any mesh element (i.e. vertex, edge, or face) `p`

, the x-axis of the tangent space at `p`

points in the direction of `p.halfedge()`

. The y-axis then points 90 degrees counterclockwise from the x-axis. (This is slightly more complicated at vertices, where one must use rescaled corner angles to define these directions. See the discussion of vertex tangent spaces) for more details.