comparison pkg/octree/triangulation.go @ 2483:620038ade708 octree-diff

Incorporated fogleman's fast Delaunay triangulation adjuted to our vertex model. License: MIT Home: https://github.com/fogleman/delaunay
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 01 Mar 2019 15:33:27 +0100
parents
children 4fa92d468164
comparison
equal deleted inserted replaced
2481:3cf5d27a6c8b 2483:620038ade708
1 // Copyright (C) 2018 Michael Fogleman
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20 package octree
21
22 import (
23 "fmt"
24 "math"
25 )
26
27 type Triangulation struct {
28 Points []Vertex
29 ConvexHull []Vertex
30 Triangles []int
31 Halfedges []int
32 }
33
34 // Triangulate returns a Delaunay triangulation of the provided points.
35 func Triangulate(points []Vertex) (*Triangulation, error) {
36 t := newTriangulator(points)
37 err := t.triangulate()
38 return &Triangulation{points, t.convexHull(), t.triangles, t.halfedges}, err
39 }
40
41 func (t *Triangulation) area() float64 {
42 var result float64
43 points := t.Points
44 ts := t.Triangles
45 for i := 0; i < len(ts); i += 3 {
46 p0 := points[ts[i+0]]
47 p1 := points[ts[i+1]]
48 p2 := points[ts[i+2]]
49 result += area(p0, p1, p2)
50 }
51 return result / 2
52 }
53
54 // Validate performs several sanity checks on the Triangulation to check for
55 // potential errors. Returns nil if no issues were found. You normally
56 // shouldn't need to call this function but it can be useful for debugging.
57 func (t *Triangulation) Validate() error {
58 // verify halfedges
59 for i1, i2 := range t.Halfedges {
60 if i1 != -1 && t.Halfedges[i1] != i2 {
61 return fmt.Errorf("invalid halfedge connection")
62 }
63 if i2 != -1 && t.Halfedges[i2] != i1 {
64 return fmt.Errorf("invalid halfedge connection")
65 }
66 }
67
68 // verify convex hull area vs sum of triangle areas
69 hull1 := t.ConvexHull
70 hull2 := ConvexHull(t.Points)
71 area1 := polygonArea(hull1)
72 area2 := polygonArea(hull2)
73 area3 := t.area()
74 if math.Abs(area1-area2) > 1e-9 || math.Abs(area1-area3) > 1e-9 {
75 return fmt.Errorf("hull areas disagree: %f, %f, %f", area1, area2, area3)
76 }
77
78 // verify convex hull perimeter
79 perimeter1 := polygonPerimeter(hull1)
80 perimeter2 := polygonPerimeter(hull2)
81 if math.Abs(perimeter1-perimeter2) > 1e-9 {
82 return fmt.Errorf("hull perimeters disagree: %f, %f", perimeter1, perimeter2)
83 }
84
85 return nil
86 }