comparison cmd/isoareas/main.go @ 4544:e5ae16f6d846 iso-areas

Lay foundation to join cut segments to longer arcs.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 27 Sep 2019 13:21:20 +0200
parents 2a707732331f
children e7970d84cb4f
comparison
equal deleted inserted replaced
4543:2a707732331f 4544:e5ae16f6d846
87 if err != nil { 87 if err != nil {
88 log.Fatalf("error: %v\n", err) 88 log.Fatalf("error: %v\n", err)
89 } 89 }
90 } 90 }
91 91
92 type indexedCut struct { 92 type indexedArc struct {
93 cut octree.LineStringZ 93 arc int32
94 index int32 94 index int32
95 } 95 }
96 96
97 func glue(a, b octree.LineStringZ) (octree.LineStringZ, bool) {
98
99 a1, a2 := a[0], a[len(a)-1]
100 b1, b2 := b[0], b[len(b)-1]
101
102 if a1.EpsEquals(b2) {
103 c := make(octree.LineStringZ, len(a)-1+len(b))
104 copy(c, b)
105 copy(c[len(b):], a[1:])
106 return c, true
107 }
108
109 if a2.EpsEquals(b1) {
110 c := make(octree.LineStringZ, len(a)-1+len(b))
111 copy(c, a)
112 copy(c[len(a):], b[1:])
113 return c, true
114 }
115
116 if a1.EpsEquals(b1) {
117 c := make(octree.LineStringZ, len(a)-1+len(b))
118 copy(c, b)
119 c[:len(b)].Reverse()
120 copy(c[len(b):], a[1:])
121 return c, true
122 }
123
124 if a2.EpsEquals(b2) {
125 c := make(octree.LineStringZ, len(a)-1+len(b))
126 copy(c, a)
127 copy(c[len(a):], b[:len(b)-1])
128 c[len(a):].Reverse()
129 return c, true
130 }
131
132 return nil, false
133 }
134
135 func connectArcs(tri *octree.Triangulation, cut []indexedArc, arcs *[]octree.LineStringZ) {
136
137 // TODO: Implement me!
138 }
139
97 func intersectTriangles(tri *octree.Triangulation, heights []float64) [][]octree.LineStringZ { 140 func intersectTriangles(tri *octree.Triangulation, heights []float64) [][]octree.LineStringZ {
98 141
99 cuts := make([][]indexedCut, len(heights)) 142 cuts := make([][]indexedArc, len(heights))
100 143
101 classes := make([][]int32, len(heights)+1) 144 classes := make([][]int32, len(heights)+1)
145
146 var arcs []octree.LineStringZ
102 147
103 all: 148 all:
104 for i := int32(0); i < int32(len(tri.Triangles)); i += 3 { 149 for i := int32(0); i < int32(len(tri.Triangles)); i += 3 {
105 ti := tri.Triangles[i : i+3] 150 ti := tri.Triangles[i : i+3]
106 v0 := tri.Points[ti[0]] 151 v0 := tri.Points[ti[0]]
131 continue 176 continue
132 } 177 }
133 t := octree.Triangle{v0, v1, v2} 178 t := octree.Triangle{v0, v1, v2}
134 cut := t.IntersectHorizontal(h) 179 cut := t.IntersectHorizontal(h)
135 if len(cut) >= 2 { 180 if len(cut) >= 2 {
136 cuts[j] = append(cuts[j], indexedCut{cut, i / 3}) 181 arc := int32(len(arcs))
137 } 182 arcs = append(arcs, cut)
138 } 183 cuts[j] = append(cuts[j], indexedArc{arc, i / 3})
184 }
185 }
186 }
187
188 // connect the arcs in a cut list to longer arcs.
189
190 for _, c := range cuts {
191 connectArcs(tri, c, &arcs)
139 } 192 }
140 193
141 result := make([][]octree.LineStringZ, len(classes)) 194 result := make([][]octree.LineStringZ, len(classes))
142 195
143 log.Println("inside classes:") 196 log.Println("inside classes:")
176 229
177 for l := i - 1; l <= i; l++ { 230 for l := i - 1; l <= i; l++ {
178 if l < 0 || l >= len(cuts) { 231 if l < 0 || l >= len(cuts) {
179 continue 232 continue
180 } 233 }
181 if curr = findCut(ns[j], cuts[l]); curr != nil { 234
235 if arc := findArc(ns[j], cuts[l]); arc >= 0 {
236 curr = arcs[arc]
182 break 237 break
183 } 238 }
184 } 239 }
185 240
186 if curr == nil { 241 if curr == nil {
269 func neighbors(t *octree.Triangulation, idx int32) []int32 { 324 func neighbors(t *octree.Triangulation, idx int32) []int32 {
270 idx *= 3 325 idx *= 3
271 return t.Halfedges[idx : idx+3] 326 return t.Halfedges[idx : idx+3]
272 } 327 }
273 328
274 func findCut(needle int32, haystack []indexedCut) octree.LineStringZ { 329 func findArc(needle int32, haystack []indexedArc) int32 {
275 lo, hi := 0, len(haystack)-1 330 lo, hi := 0, len(haystack)-1
276 for lo <= hi { 331 for lo <= hi {
277 mid := (hi-lo)/2 + lo 332 mid := (hi-lo)/2 + lo
278 switch v := haystack[mid].index; { 333 switch v := haystack[mid].index; {
279 case v < needle: 334 case v < needle:
280 lo = mid + 1 335 lo = mid + 1
281 case v > needle: 336 case v > needle:
282 hi = mid - 1 337 hi = mid - 1
283 default: 338 default:
284 return haystack[mid].cut 339 return haystack[mid].arc
285 } 340 }
286 } 341 }
287 return nil 342 return -1
288 } 343 }
289 344
290 func contains(needle int32, haystack []int32) bool { 345 func contains(needle int32, haystack []int32) bool {
291 lo, hi := 0, len(haystack)-1 346 lo, hi := 0, len(haystack)-1
292 for lo <= hi { 347 for lo <= hi {