GeomPP 0.17.3

dotnet add package GeomPP --version 0.17.3
                    
NuGet\Install-Package GeomPP -Version 0.17.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GeomPP" Version="0.17.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GeomPP" Version="0.17.3" />
                    
Directory.Packages.props
<PackageReference Include="GeomPP" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GeomPP --version 0.17.3
                    
#r "nuget: GeomPP, 0.17.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GeomPP@0.17.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GeomPP&version=0.17.3
                    
Install as a Cake Addin
#tool nuget:?package=GeomPP&version=0.17.3
                    
Install as a Cake Tool

GeomPP

A modern C++20 geometry library for 2D and 3D spatial computation — fast, mathematically correct, thoroughly tested, and usable from C++, C# (.Net 8/9/10 or .Net Framework 4.8), and Python 3.

You may be a CAD or a Game developer using C#.Net, and you use APIs native to the platform you develop into. These native APIs are easy to get in, but may contain bugs that have not been fixed, or simply lack some functionalities. You may be a Data Scientist using Python on a GIS project, and having to import 3+ libraries, and covert from data-structure to data-structure to use it. You may be a C++ developer who wants to import a more lightweight library than those which already exist, and possibly more user friendly.

This library was born a few years ago to solve all these problems. It was recently augmented with the aim of using the most modern algorithms to solve a variety of geometrical problems.

The sources of these algorithms are to be found in several textbooks, such as

  • Practical Geometry Algorithms (Danniel Sunday)
  • Computational Geometry in C (Joseph O'Rourke)
  • Computational Geometry (Mark de Berg, Marc van Kreveld, Mark Overmars, Otfried Schwarzkopf)

Finally, the help of AI was used to validate algorithms (bug-free, guarantee the desired big-O), bind into other languages than C++, add edge cases to achieve a high test coverage, and build documentation.

C# Bindings

C++/CLI bindings for geompp, targeting Windows x64.

Available on NuGet as GeomPP.

Supports .NET 8, .NET 9, .NET 10, and .NET Framework 4.8.

Changelog — full release notes for every version.


Install

dotnet add package GeomPP

or in your .csproj:

<PackageReference Include="GeomPP" Version="0.8.0" />
Platform .Net .Net Framework
Windows x64 8 · 9 · 10 4.8

Platform note

GeomPP is built with C++/CLI and is Windows x64 only. It will not run on Linux, macOS, or 32-bit processes.


Test Coverage

This is the summary of the current test coverage. More on test coverage.

Metric Count Notes
Public methods (C++) ~513 Excl. ctors/dtors/operators. geompp::maths/geompp::transformations (templated/free-function, header-only) tracked separately, see test_coverage_report.md
C++ methods tested ~493/513 ~96% (1204 TEST cases, 1202 run, 2 disabled — incl. 37+17 for geompp::maths +6 for its own detail::, 30 for geompp::transformations, +40 direct detail::/detail::view:: tests)
Python methods tested 458/474 ~97% (903 pytest cases — incl. 27+6 for geompp.maths, 24+9 for geompp.transformations, +4 for distance_to(Point) on Polygon2D/3D/Triangle2D/3D)
C# methods tested 518/581 ~89% (1003 harness tests — incl. 24+6 for GeomPP.Maths, 23+9 for GeomPP.Transformations, +6 for DistanceTo(Point) on Polygon2D/3D/Triangle2D/3D, +2 for Triangle2D-Triangle2D intersection parity)
Stubs (not yet impl.) 2 TriangulationParams::Strategy::MonotonePolygon/Delaunay — intentional, see test_coverage_report.md

How to use it

You can look at the test suite to see detailed usage.

A quick list of code examples per topic is provided here.

👉 Visual Documentation and Code Examples on Github


What it provides

Serialization

All primitives support:

  • WKT (Well-Known Text) — ToWkt() / FromWkt() for standard text interchange
  • Binary file I/OToFile() / FromFile() for compact storage

Precision

Floating-point comparisons use a thread-local DECIMAL_PRECISION constant via AlmostEquals() methods, making the library robust against rounding errors while remaining configurable per thread.

Classes

Where not explicitely specified, both 2D and 3D variants are available for all core types:

Primitive Description
Point A coordinate in space
Vector Direction and magnitude
Line An infinite line through two points
Ray A semi-infinite line from an origin in one direction
LineSegment A finite segment between two endpoints
Polyline A connected chain of segments
Triangle Three non-collinear points forming a closed face
Polygon A closed polygon defined by an ordered list of vertices
BBox Axis-aligned bounding box
BBall Minimum bounding sphere (Ritter's algorithm)
BRect2D Minimum oriented bounding rectangle (rotating calipers)
BPrism3D Minimum oriented bounding prism (PCA + rotating calipers)
Plane A flat surface in 3D defined by a point and a normal
View2D A class that converts a 3D point into 2D quicker than plane
Mesh A set of adjacent triangles that together make up a detailed 2D or 3D shape (a surface or a solid)
ConnectedMesh This one keeps track of the neighbors of each triangle, so that going from a facet to its 0-3 neighbors is very quick
PolyMesh Not just triangles, also polygons are allowed, in order to save on the number of vertices on the same planar regions of the surface

Algorithm overview

Each class supports a consistent set of spatial operations where applicable:

  • Containment — does a shape contain a given point?
  • Intersection — do two shapes strike through each other, and what is the resulting geometry? Also available as GeomUtil.FindIntersections() on a free set of segments. The meaning of this operation changes from 2D to 3D — check the class docs.
  • Overlap — do two shapes have a portion in common, and what is the resulting geometry? Meaning changes from 2D to 3D.
  • Touch — do two shapes have a point in common, and which is it? Meaning changes from 2D to 3D.
  • Distance — closest distance from a point to a shape.
  • Plane operations — projection of a point from 3D to 2D, and re-projection from 2D to 3D, via the Plane class or the faster View2D (one of the 3 world planes XY/YZ/ZX, or a custom plane).
  • Interpolation / LocationGeomUtil.Lerp(p0, p1, t) retrieves a point at parameter t between two points (not clamped); Interpolate(t) does the same along a segment or polyline; the opposite operation finds the parameter t for a point already on a shape.
  • Area / Perimeter / Centroid — geometric properties for closed shapes.
  • Signed area — encodes orientation (clockwise vs. counter-clockwise in 2D, surface normal direction in 3D).
  • Simplicity / self-intersectionPolygon2D.IsSimple() and GeomUtil.HasIntersections(segments) (Shamos–Hoey, boolean) / GeomUtil.FindIntersections(segments) (Bentley–Ottmann, every crossing point).
  • Convex hullGeomUtil.ConvexHull(points) — Andrew's monotone chain, returns hull vertices in CCW order.
  • Bounding containers — tight-fitting containers around point clouds: axis-aligned bounding box, bounding ball, minimal oriented rectangle, convex hull.
  • Polyline operationsPolyline.Reduce() (decimation) and Polyline.Expand() (Bezier corner smoothing), or the underlying GeomUtil.DistDecimation()/RdpDecimation()/VwDecimation()/BezierSmoothing2()/PolylineExpansion() for a plain point list.
  • Polygon boolean operationsIntersection(), Union(), Difference(), Xor() between two polygons (map-overlay method), or GeomUtil.Clip(clipperLoop, subjectLoop) for raw point loops without constructing a Polygon first.
  • Point cloud operationsGeomUtil.PrincipalAxes() (PCA) finds the empirical 3 directive axes of a list of points in space.
  • Triangulation — decomposition of a polygon into n-triangles, using several possible algorithms such as the Ear Clip, a Best Fit Ear Clip, Monotone Polygon or Constrained Delaunay.
  • Linear algebra (GeomPP.Maths) — a small fixed-size linear algebra namespace, independent of the geometry classes above: Vector2/Vector3/Vector4, Matrix2/Matrix3/Matrix4, and the Solvers.SolveGauss() / Solvers.SolveCramer() system solvers for Ax = b.
  • Affine transformations (GeomPP.Transformations) — Transform.Translate(), .Rotate(), .Scale(), .Shear(), .Reflect() (fast, single-Point, no matrix needed), and the general Transform.Transform(primitive, matrix) for every primitive from Point2D/Point3D to PolyMesh2D/PolyMesh3D. Use TransformBuilder2D/TransformBuilder3D to fluently chain several transforms (e.g. .Translate(...).Rotate(...).Scale(...)) into a single Matrix3/Matrix4, then apply it once with .Build()/Transform.Transform().

Intersection-style methods return object (null on no intersection) — see the pattern-matching example above.

Free functions

GeomUtil is a static class wrapping the geompp free functions that operate on point/segment lists directly, without needing a class instance first:

Function Description
GeomUtil.AreCoplanar(points) List of Point3D on the same plane
GeomUtil.ClosestWorldPlaneTo(points) XY / YZ / ZX plane nearest to the point cloud
GeomUtil.AreCCW(points, refPlane) Counter-clockwise winding (3D; refPlane = null auto-detects)
GeomUtil.AreCW(points, refPlane) Clockwise winding (3D; refPlane = null auto-detects)
GeomUtil.Lerp(p0, p1, t) Linear interpolation between two points — p0 + t*(p1-p0), not clamped
GeomUtil.Clip(clipperLoop, subjectLoop) Set intersection of two point loops — Point2D natively, Point3D if coplanar (same map-overlay engine as Polygon.Intersection())
GeomUtil.HasIntersections(segments) Shamos–Hoey: true if any two segments in a LineSegment2D list cross
GeomUtil.FindIntersections(segments) Bentley–Ottmann: every crossing point among a set of segments, sorted left-to-right
GeomUtil.ConvexHull(points) Andrew's monotone chain: convex hull, returned in CCW order (3D overload auto-detects the normal)
GeomUtil.DistDecimation(points, threshold) O(n) radial-distance point decimation
GeomUtil.RdpDecimation(points, threshold) Ramer–Douglas–Peucker point decimation
GeomUtil.VwDecimation(points, threshold) Visvalingam–Whyatt point decimation
GeomUtil.BezierSmoothing2(p0, p1, p2, smoothness, minDistance\|numSegments[, minSegmentLength]) Rounds one polyline corner with a quadratic Bezier arc
GeomUtil.PolylineExpansion(points, settings) Rounds every inner corner of a point list and works with either fixed number of segmens or fixed min segment length (the engine behind Polyline.Expand())
GeomUtil.PrincipalAxes(points) PCA on a point cloud: returns a CoordinateFrame (.X primary, .Y secondary, .Z best-fit normal)
GeomUtil.PrincipalNormal(points) Best-fit plane normal (PCA eigenvector with smallest eigenvalue)
GeomUtil.PrincipalDirection(points) Dominant direction (PCA eigenvector with largest eigenvalue)
GeomUtil.FindExtremePoints(polygon, line) The two polygon vertices least/greatest projected along a line's direction
GeomUtil.DistanceTo(polygon, line) Distance from a polygon to a line (zero if they intersect)
GeomUtil.TangentsTo(polygon, pointOrPolygon) Tangent segments from a point to a polygon, or common outer tangents between two polygons
GeomUtil.Triangulate(polygons, settings) Returns a set of adjacent triangles replacing the surface of 1+ polygons (the engine behind Polygon::Triangulate() and PolyMesh::Triangulate()), and with a robust input validation
Maths.Solvers.SolveGauss(a, b) Solve Ax = b via Gaussian elimination
Maths.Solvers.SolveCramer(a, b) Solve Ax = b via Cramer's rule; throws if a is singular
Transformations.Transform.Translate(primitive, offset) Translate a primitive by a vector
Transformations.Transform.Rotate(primitive, angleRad[, axis]) Rotate about the origin — 3D takes an axis
Transformations.Transform.Scale(primitive, factor \| sx, sy[, sz]) Uniform or non-uniform scale about the origin
Transformations.Transform.Shear(primitive, ...) Shear along one axis by a multiple of another
Transformations.Transform.Reflect(primitive, normal) Reflect about a line/plane through the origin with the given normal
Transformations.Transform.Transform(primitive, matrix) Apply an arbitrary Matrix3/Matrix4 (homogeneous) to any primitive from Point to PolyMesh

Build on Windows x64 manually

Build the C# DLL

# from the main directory, geompp

# .NET 8 (LTS, supported until Nov 2026)
msbuild geompp_csharp\GeomPP_Net8.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]

# .NET 9 (STS)
msbuild geompp_csharp\GeomPP_Net9.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]

# .NET 10 (LTS)
msbuild geompp_csharp\GeomPP_Net10.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]

# .NET Framework 4.8
msbuild geompp_csharp\GeomPP_Net48.vcxproj /p:Platform=x64 /p:GeomppBuildRoot="$PWD\build_win" [/p:Configuration=Release]

# run smoke tests, after build from the main directory geompp
# (GeomPPTests.csproj is an Exe-type console harness, not a Test SDK project —
# `dotnet test` reports success but runs nothing; use `dotnet run`)
dotnet run --project geompp_csharp\tests\GeomPPTests.csproj [-p:GeomPPConfiguration=Release]
Product Compatible and additional computed target framework versions.
.NET net8.0-windows7.0 is compatible.  net9.0-windows was computed.  net9.0-windows7.0 is compatible.  net10.0-windows was computed.  net10.0-windows7.0 is compatible. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.8

    • No dependencies.
  • net10.0-windows7.0

    • No dependencies.
  • net8.0-windows7.0

    • No dependencies.
  • net9.0-windows7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.17.3 97 8/15/2026
0.17.2 92 8/14/2026
0.16.2 85 8/6/2026
0.15.1 119 7/24/2026
0.14.0 104 7/21/2026
0.13.0 117 7/9/2026
0.12.0 103 7/8/2026
0.11.0 110 7/4/2026
0.10.1 119 6/23/2026
0.9.1 222 6/17/2026
0.8.2 117 5/18/2026
0.8.0 111 5/18/2026
0.7.0 104 5/6/2026
0.6.0 104 5/4/2026
0.5.0 103 5/1/2026
0.4.0 115 4/27/2026
0.1.2 124 4/13/2026
0.1.1 123 4/13/2026
0.1.0 125 4/9/2026

### Added

**C++ core**
> `calc_utils2.cpp` and `calc_utils3d.cpp` have been split into several files, by topic, and now they belong to the `calc_utils` folder AND namespace.

**C# bindings**
> the standard, default .Net project `GeomPP` has been changed into the new name `GeomPP_Net10` to be consistent with the naming of the other versions, and to make it clear that .Net10 is the default.

**Misc**
> more documentation has been written for the `geompp/docs` path. that had been left behind for ages and is now updated.