forked from go-spatial/geom
-
Notifications
You must be signed in to change notification settings - Fork 0
/
geom.go
114 lines (97 loc) · 2.47 KB
/
geom.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package subdivision
import (
"context"
"log"
"strings"
"github.com/hahaking119/geom"
"github.com/hahaking119/geom/planar"
"github.com/hahaking119/geom/planar/triangulate/delaunay/quadedge"
"github.com/hahaking119/geom/winding"
)
// AsGeom returns a geom based Triangle
func (t Triangle) AsGeom() (tri geom.Triangle) {
e := t.StartingEdge()
for i := 0; i < 3; e, i = e.RNext(), i+1 {
tri[i] = [2]float64(*e.Orig())
}
return tri
}
// NewSubdivisionFromGeomLines returns a new subdivision made up of the given geom lines.
// it is assume that all line are connected. If lines are disjointed that it is undefined
// which disjointed subdivision will be returned
func NewSubdivisionFromGeomLines(lines []geom.Line, order winding.Order) *Subdivision {
lines = planar.NormalizeUniqueLines(lines)
var (
indexMap = make(map[geom.Point]*quadedge.Edge)
ext *geom.Extent
eq *quadedge.Edge
oe *quadedge.Edge
de *quadedge.Edge
)
for i := range lines {
orig, dest := geom.Point(lines[i][0]), geom.Point(lines[i][1])
if cmp.IsEmptyGeo(orig) || cmp.IsEmptyGeo(dest) {
log.Printf("orig %v or dest %v is empty", orig, dest)
}
if ext == nil {
ext = geom.NewExtentFromPoints(orig, dest)
} else {
ext.AddPointers(orig, dest)
}
oe = indexMap[orig]
de = indexMap[dest]
if oe != nil {
if oe.FindONextDest(dest) != nil {
// edge already in graph
continue
}
oe, _ = quadedge.ResolveEdge(order, oe, dest)
if oe == nil {
oe = indexMap[orig]
}
}
if de != nil {
de, _ = quadedge.ResolveEdge(order, de, orig)
if de == nil {
de = indexMap[dest]
}
}
eq = quadedge.New()
eq.EndPoints(&orig, &dest)
switch {
case oe != nil && de != nil:
eq = quadedge.Connect(oe.Sym(), de, order)
case oe != nil && de == nil:
quadedge.Splice(oe, eq)
indexMap[dest] = eq.Sym()
case oe == nil && de != nil:
quadedge.Splice(de, eq.Sym())
indexMap[orig] = eq
case oe == nil && de == nil:
indexMap[orig] = eq
indexMap[dest] = eq.Sym()
}
}
tri, _ := geom.NewTriangleForExtent(ext, 0)
sd := &Subdivision{
frame: [3]geom.Point{
geom.Point(tri[0]),
geom.Point(tri[1]),
geom.Point(tri[2]),
},
ptcount: len(indexMap),
startingEdge: eq,
}
if debug {
var str strings.Builder
DumpSubdivisionW(&str, sd)
log.Print(str.String())
}
if err := sd.Validate(context.Background()); err != nil {
err1 := err.(quadedge.ErrInvalid)
for i, str := range err1 {
log.Printf("%03v: %v", i, str)
}
}
return sd
}