comparison pkg/octree/tree.go @ 2466:a1e751c08c56 octree-diff

Calculate difference on single core.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 25 Feb 2019 18:21:33 +0100
parents fe1aa62195c2
children c85b16db8a02
comparison
equal deleted inserted replaced
2465:86c7a023400e 2466:a1e751c08c56
30 Min Vertex 30 Min Vertex
31 // Max is the upper right corner of the bbox. 31 // Max is the upper right corner of the bbox.
32 Max Vertex 32 Max Vertex
33 } 33 }
34 34
35 func (ot *Tree) Vertices() []Vertex {
36 return ot.vertices
37 }
38
35 var scale = [4][4]float64{ 39 var scale = [4][4]float64{
36 {0.0, 0.0, 0.5, 0.5}, 40 {0.0, 0.0, 0.5, 0.5},
37 {0.5, 0.0, 1.0, 0.5}, 41 {0.5, 0.0, 1.0, 0.5},
38 {0.0, 0.5, 0.5, 1.0}, 42 {0.0, 0.5, 0.5, 1.0},
39 {0.5, 0.5, 1.0, 1.0}, 43 {0.5, 0.5, 1.0, 1.0},
40 } 44 }
41 45
42 // Vertical does a vertical cross cut from (x1, y1) to (x2, y2). 46 func (ot *Tree) Value(x, y float64) (float64, bool) {
43 func (ot *Tree) Vertical(x1, y1, x2, y2 float64, fn func(*Triangle)) {
44
45 box := Box2D{
46 X1: math.Min(x1, x2),
47 Y1: math.Min(y1, y2),
48 X2: math.Max(x1, x2),
49 Y2: math.Max(y1, y2),
50 }
51 47
52 // out of bounding box 48 // out of bounding box
53 if box.X2 < ot.Min.X || ot.Max.X < box.X1 || 49 if x < ot.Min.X || ot.Max.X < x ||
54 box.Y2 < ot.Min.Y || ot.Max.Y < box.Y1 { 50 y < ot.Min.Y || ot.Max.Y < y {
55 return 51 return 0, false
56 } 52 }
57
58 line := NewPlane2D(x1, y1, x2, y2)
59 53
60 type frame struct { 54 type frame struct {
61 pos int32 55 pos int32
62 Box2D 56 Box2D
63 } 57 }
64 58
65 dupes := map[int32]struct{}{}
66
67 all := Box2D{ot.Min.X, ot.Min.Y, ot.Max.X, ot.Max.Y} 59 all := Box2D{ot.Min.X, ot.Min.Y, ot.Max.X, ot.Max.Y}
68 //log.Printf("area: %f\n", (box.x2-box.x1)*(box.y2-box.y1))
69 //log.Printf("all: %f\n", (all.x2-all.x1)*(all.y2-all.y1))
70 60
71 stack := []frame{{1, all}} 61 stack := []frame{{1, all}}
72 62
73 for len(stack) > 0 { 63 for len(stack) > 0 {
74 top := stack[len(stack)-1] 64 top := stack[len(stack)-1]
88 dx*scale[i][0] + top.X1, 78 dx*scale[i][0] + top.X1,
89 dy*scale[i][1] + top.Y1, 79 dy*scale[i][1] + top.Y1,
90 dx*scale[i][2] + top.X1, 80 dx*scale[i][2] + top.X1,
91 dy*scale[i][3] + top.Y1, 81 dy*scale[i][3] + top.Y1,
92 } 82 }
83 if nbox.Contains(x, y) {
84 if a != 0 {
85 stack = append(stack, frame{a, nbox})
86 }
87 if b != 0 {
88 stack = append(stack, frame{b, nbox})
89 }
90 break
91 }
92 }
93 }
94 } else { // leaf
95 pos := -top.pos - 1
96 n := ot.index[pos]
97 indices := ot.index[pos+1 : pos+1+n]
98
99 for _, idx := range indices {
100 tri := ot.triangles[idx]
101 t := Triangle{
102 ot.vertices[tri[0]],
103 ot.vertices[tri[1]],
104 ot.vertices[tri[2]],
105 }
106 if t.Contains(x, y) {
107 return t.Plane3D().Z(x, y), true
108 }
109 }
110 }
111 }
112
113 return 0, false
114 }
115
116 // Vertical does a vertical cross cut from (x1, y1) to (x2, y2).
117 func (ot *Tree) Vertical(x1, y1, x2, y2 float64, fn func(*Triangle)) {
118
119 box := Box2D{
120 X1: math.Min(x1, x2),
121 Y1: math.Min(y1, y2),
122 X2: math.Max(x1, x2),
123 Y2: math.Max(y1, y2),
124 }
125
126 // out of bounding box
127 if box.X2 < ot.Min.X || ot.Max.X < box.X1 ||
128 box.Y2 < ot.Min.Y || ot.Max.Y < box.Y1 {
129 return
130 }
131
132 line := NewPlane2D(x1, y1, x2, y2)
133
134 type frame struct {
135 pos int32
136 Box2D
137 }
138
139 dupes := map[int32]struct{}{}
140
141 all := Box2D{ot.Min.X, ot.Min.Y, ot.Max.X, ot.Max.Y}
142 //log.Printf("area: %f\n", (box.x2-box.x1)*(box.y2-box.y1))
143 //log.Printf("all: %f\n", (all.x2-all.x1)*(all.y2-all.y1))
144
145 stack := []frame{{1, all}}
146
147 for len(stack) > 0 {
148 top := stack[len(stack)-1]
149 stack = stack[:len(stack)-1]
150
151 if top.pos > 0 { // node
152 if index := ot.index[top.pos:]; len(index) > 7 {
153 for i := 0; i < 4; i++ {
154 a := index[i]
155 b := index[i+4]
156 if a == 0 && b == 0 {
157 continue
158 }
159 dx := top.X2 - top.X1
160 dy := top.Y2 - top.Y1
161 nbox := Box2D{
162 dx*scale[i][0] + top.X1,
163 dy*scale[i][1] + top.Y1,
164 dx*scale[i][2] + top.X1,
165 dy*scale[i][3] + top.Y1,
166 }
93 if nbox.Intersects(box) && nbox.IntersectsPlane(line) { 167 if nbox.Intersects(box) && nbox.IntersectsPlane(line) {
94 if a != 0 { 168 if a != 0 {
95 stack = append(stack, frame{a, nbox}) 169 stack = append(stack, frame{a, nbox})
96 } 170 }
97 if b != 0 { 171 if b != 0 {