triangolatte

package module
v0.0.0-...-8b66c38 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2021 License: MIT Imports: 6 Imported by: 19

README


triangolatte

2D triangulation library. Allows translating lines and polygons (both based on points) to the language of GPUs.

Features normal and miter joint line triangulation. Handles polygons using ear clipping algorithm with hole elimination included.

screenshot

For reference: triangulates 99.76% of 75 thousand buildings in Cracow under 3.43s on average programmer notebook (single threaded).

Table of contents

Installation

Nothing surprising

go get github.com/tchayen/triangolatte

Usage

Basic example
vertices := []Point{{10, 20}, {30, 40}, {50, 60}}
t, err = triangolatte.Polygon(vertices)

Examples

In /examples you can find:

  • buildings – full-blown WebGL previewer of buildings triangulated in city example
  • city – triangulation of whole city downloaded from Open Street Map
  • gpx – GPX format parsing and triangulation of its data
  • wireframe – desktop OpenGL wireframe previewer for triangulated shapes

You will find instructions for running the code there.

Features

API

Polygon(points []Point, holes [][]Point) ([]float64, error)

Takes array of points and produces array of triangle coordinates.

Based on the following paper and inspired by EarCut.

JoinHoles(points [][]Point) ([]Point, error)

Removes holes, joining them with the rest of the polygon. Provides preprocessing for Polygon. First element of the points array is the outer polygon, the rest of them are considered as holes to be removed.

Line(joint Joint, points []Point, width int) ([]float64, error)

Takes array of points and triangulates them to resemble a line of given width. Returns array of two-coordinate CCW triangles one after another.

Types

To select method of joining line segments.

type Joint int

const (
	// No joint correction.
	Normal Joint = 0
	// Producing miter joints, i.e. extending the lines until they meet at some point.
	Miter Joint = 1
)

For calculations using points.

type Point struct {
  X, Y float64
}

A wrapper for Point used in cyclic list.

type Element struct {
	Prev, Next *Element
	Point      Point
}

Helpers

You can have a look at helpers.go file. It stores triangolatte's helper functions used mostly by tests and examples. They are not exported because I don't want to commit to supporting them in the future, but they might turn out useful for you.

Tests

Code is (more or less) covered in tests. You can run them like this:

go test -v

You can also run benchmarks for selected functions (refer to the *_test.go files for availability). For example:

go test -run NONE -bench IsInsideTriangle

Benchmarks

NOTE: This section contains work in progress. Numbers below are better reference point than nothing, but still far from perfect.

Polygon() on shape with 10 vertices takes 754ns on average.

Triangulation of 75 thousand buildings runs for around 3.43s.

Using average programmer's notebook. Expect speed up on faster CPUs or while splitting execution into separate threads.

Flame Graphs

CPU time % usage snaphost using Flame Graphs:

assets/torch.svg

Want to learn what is it or maybe you are willing to generate one yourself? Check FlameGraphs document in this repository.

Future plans

Optimizations

NOTE: this library is developed mostly with map data triangulation in mind and it will be its main performance target.

  • explore possibilities for optimizations in JoinHoles(...)
  • maybe allow reusing point array for massive allocation reduction

Content

  • provide more examples (e.g. desktop OpenGL usage, mobile app, live rendering pipeline, other unusual use cases...)
  • add benchmarks with comparison to libraries in other languages

WebAssembly

One of the core plans for this library's development is creating, as soon as it becomes possible, some kind of WebAssembly module for use in JS.

Contributing

You are welcome to create an issue or pull request if you've got an idea what to do. It is usually a good idea to visit Gitter and discuss your thoughts.

Don't have one, but still want to contribute? Get in touch with us and we can brainstorm some ideas.

License

MIT License – refer to the LICENSE file.

Documentation

Overview

Package triangolatte is a 2D triangulation library. Allows translating lines and polygons (both based on points) to the language of GPUs.

Features normal and miter joint line triangulation. Handles polygons using ear clipping algorithm with hole elimination included.

Visit https://github.com/tchayen/triangolatte for complete README with additional info and examples.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Line

func Line(joint Joint, points []Point, width float64) ([]float64, error)

Line takes array of points and triangulates them to resemble a line of given width. Returns array of two-coordinate CCW triangles one after another.

func Polygon

func Polygon(points []Point) ([]float64, error)

Polygon triangulates given CCW polygon using ear clipping algorithm (takes O(n^2) time). Produces array of two-coordinate, CCW triangles, put one after another. Returns empty array and error when triangulation did not complete properly.

Types

type Element

type Element struct {
	Prev, Next *Element
	Point      Point
}

Element type is a wrapper for Point used in cyclic list.

func Insert

func Insert(p Point, e *Element) *Element

Insert function takes Point and Element (optionally nil) and adds Point wrapped in a new Element after given Element, if present.

func (*Element) Remove

func (e *Element) Remove()

Remove detaches Element from the list (preserving its connections for reference). Be aware of potential memory leaks.

type Joint

type Joint int

Joint is a type of connection happening when lines joining two points meet.

const (
	// Normal triangulates with no joint correction.
	Normal Joint = 0
	// Miter triangulates producing miter joints, i.e. extending the lines until
	// they meet at some point.
	Miter Joint = 1
)

type Point

type Point struct {
	X, Y float64
}

Point is a pair of two coordinates. Used as mostly as a point on euclidean planes or a vector.

func JoinHoles

func JoinHoles(points [][]Point) ([]Point, error)

JoinHoles removes holes, joining them with the rest of the polygon. Provides pre-processing for Polygon. First element of the points array is the outer polygon, the rest of them are considered as holes to be removed.

func (Point) Add

func (p Point) Add(r Point) Point

Add adds two two-element vectors.

func (Point) Cross

func (p Point) Cross(r Point) float64

Cross takes one of the approaches to calculating 2D cross product (p.X*r.Y - p.Y*r.X).

func (Point) Distance2

func (p Point) Distance2(r Point) float64

Distance2 calculates squared distance between two points.

func (Point) Dot

func (p Point) Dot(r Point) float64

Dot calculates dot product of two two-element vectors.

func (Point) Normalize

func (p Point) Normalize() Point

Normalize scales vector to have unit length.

func (Point) Scale

func (p Point) Scale(f float64) Point

Scale sets length of vector to given value.

func (Point) Sub

func (p Point) Sub(r Point) Point

Sub subtracts two two-element vectors.

type Set

type Set map[int]bool

Set of int values.

Directories

Path Synopsis
examples
gpx

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL