Themis.Geometry 2022.10.27

There is a newer version of this package available.
See the version list below for details.
dotnet add package Themis.Geometry --version 2022.10.27                
NuGet\Install-Package Themis.Geometry -Version 2022.10.27                
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="Themis.Geometry" Version="2022.10.27" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Themis.Geometry --version 2022.10.27                
#r "nuget: Themis.Geometry, 2022.10.27"                
#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.
// Install Themis.Geometry as a Cake Addin
#addin nuget:?package=Themis.Geometry&version=2022.10.27

// Install Themis.Geometry as a Cake Tool
#tool nuget:?package=Themis.Geometry&version=2022.10.27                

Themis.Geometry

Overview

This project encompasses the core geometriic object models and funcitonality that allow for efficient and reliable representation, manipulation, and analysis of common geospatial data types.

Themis.Geometry.Boundary

This namespace exposes the BoundingBox class which represents both 2D BoundingBox and 3D BoundingCube geometries within a single concrete class. In both dimensional cases, the BoundingBox is defined by its local Minima (X,Y,Z) and Maxima (X,Y,Z).

Note: When in 2D - the Minima/Maxima Z coordinates are left as double.NaN.

Further, the BoundingBox implementation is at the core of the spatial indexing functionality provided by the QuadTree.

Boundary Usage

While the current BoundingBox implementation only has a default constructor it also exposes a number of Factory methods as well as a Fluent interface to generate the desired resultant geometry.

Consider the following:


// Create a 2D BoundingBox centered at (1, 1) with minima (-1.5, -1.5) and maxima (3.5, 3.5)
var box = BoundingBox.FromPoint(1.0, 1.0, 5.0);
var box2 = BoundingBox.From(-1.5, -1.5, 3.5, 3.5);
// Resulting Minima & Maxima are equal - thus the two BoundingBoxes are equal
Assert.Equal(box, box2);
Assert.True(box.Contains(1.0, 1.0)); 

// Creates a new 3D BoundingBox with the specified elevation (Z) range
var cube = BoundingBox.From(box).WithZ(0, 100.0);
// The 3D BoundingBox can still perform both 2D & 3D containment checks
Assert.True(cube.Contains(1.0, 1.0));
Assert.True(cube.Contains(1.0, 1.0, 1.0));

We can also easily expand a given BoundingBox to include any other BoundingBox or simply alter the local Minima / Maxima as follows:

// Create two BoundingBoxes that overlap and then create a 3rd that include them both
var A = BoundingBox.From(-1.5, -1.5, 3.5, 3.5);
var B = BoundingBox.From(0, 0, 5.0, 5.0);
// Can check that the two BoundingBoxes intersect/overlap as well
Assert.True(A.Intersects(B));
// Lets create a new BoundingBox by expanding A to include B
var C = A.ExpandToInclude(B);
// Can now see the maxima & minima are expanded as expected
Assert.Equal(5.0, C.MaxX);
Assert.Equal(5.0, C.MaxY);

Beyond the above functionality - each BoundingBox also exposes the following fields:

  • Width (MaxX - MinX)
  • Height (MaxY - MinY)
  • Depth (MaxZ - MinZ)
  • Area (Width * Height)
  • Volume (Width * Height * Depth)
  • (X,Y,Z) Coordinates of the Centroid

Themis.Geometry.Lines

This namespace exposes Themis' LineSegment and LineString implementations that are intended to be used to model 2/3D linear geometries. While both implementations will technically function within any dimension it's recommended consumers limit their dimensionality to 2/3D.

The LineSegment is composed of an ordered pair of vector vertices (named A & B) and encompasses both the infinite line between A->B but also the discrete LineSegment formed by A->B. Given those two components the LineSegment is able to efficiently do the following:

  • Get the station (distance along line from A->B) of any input position
  • Extract a point along the LineSegment at any station (distance along the line)
  • Extract the nearest point on the LineSegment to any input position
  • Get the minimum distance to the LineSegment from any input position

The LineString is composed of two or more vertices as an ordered, connected, set of linear geometries. In order to build the LineString we create a LineSegment between each vertex and the following vertex (excluding the final vertex). While in 2D this could represent the connectivity map of power poles, the 3D extension can be used to model wire geometries or other complex shapes composed of many lines. Given this, the LineString exposes the following functionality:

  • Extract the nearest point from all contained LineSegment geometries to any input position
  • Calculate total 2D & 3D Length of all contained LineSegment geometries

Lines Usage

In order to instantiate a LineSegment we'll need to first have two Vectors that represent the starting Vertex (A) and the terminating Vertex (B).

Note: We've also included some extension methods to easily convert a given IEnumerable<T> into a Vector<T> that simplifies this.

Here's an example:

// Need to instantiate the two vertices (0,0,0) and (5,5,5)
var A = new double[] { 0.0, 0.0, 0.0 }.ToVector();
var B = new double[] { 5.0, 5.0, 5.0 }.ToVector();
// Generate the LineSegment A->B from (0,0,0) to (5,5,5)
var line = new LineSegment(A, B);

// Get the 3D and 2D length of the LineSegment
double len = line.Length;
double len2D = line.Length2D;
Assert.NotEqual(len, len2D); // True

Another key example is when you need to find the nearest point (from a collection of points) to a given LineSegment:

// A collection of position vectors
var points = new List<Vector<double>>() { .. };
// Since this is ascending by default, can take the 'first' element as nearest
var nearest = points.OrderyBy(p => line.DistanceToPoint(p)).First();

Or the inverse - given a collection of LineSegments find the one nearest a given point of interest:

// A single query POI
var point = new double[] { .. }.ToVector();
// A collection of LineSegments
var segs = new List<LineSegment>() { .. };
// Get the LineSegment closest to the input POI
var nearestSeg = segs.OrderBy(s => s.DistanceToPoint(point)).First();
var nearestPoint = nearestSeg.GetClosestPoint(point);

Themis.Geometry.Triangles

This namespace exposes the Triangle class which is used to represent 2D/3D triangular geometries as defined by a set of three vector vertices. Once created a Triangle exposes the following key functionality & fields:

  • A collection of all edges as LineSegments
  • A BoundingBox envelope of the Triangle geometry
  • The geometry's Normal Vector
  • Methods to check if a given (X,Y) position is contained by the 2D projection of the Triangle geometry
  • Methods to extract the elevation (Z) on the Triangle surface for a given (X,Y) position

Triangles Usage

As mentioned above - in order to generate a Triangle we'll need to have a collection of vertices that define the Triangle geometry. Here's an example:

// Forming Triangle (0, 0, 0) -> (1, 0, 1) -> (0, 1, 0)
var A = new double[] { 0.0, 0.0, 0.0 }.ToVector();
var B = new double[] { 1.0, 0.0, 1.0 }.ToVector();
var C = new double[] { 0.0, 1.0, 0.0 }.ToVector();
// Generate the Triangle object
var Triangle = new Triangle(new() { A, B, C });

Now with the Triangle defined, we can check for containment of any given position and then sample its elevation on the Triangle surface as follows:

// Input POI's elevation doesn't matter for containment or Z-sampling
var pos = new double[] {0.25, 0.25, double.NaN}.ToVector();
// Checking containment & extract elevation (Z)
if(Triangle.Contains(pos))
{
    double Z = Triangle.GetZ(pos); // 0.25
}
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Themis.Geometry:

Package Downloads
Themis.Index

.NET implementations of common spatial indexing structures such as binary space partioning trees.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2023.10.12 877 10/12/2023
2022.10.27 478 10/27/2022
2022.4.1 465 4/1/2022
2022.3.21 424 3/21/2022
2022.3.20 414 3/19/2022
2022.3.19 422 3/19/2022