comparison pkg/octree/strtree.go @ 2515:6bcaa8bf2603 octree-diff

STR tree: Fixed sorting. Stored num items per nodes. Simpified code.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 05 Mar 2019 15:55:14 +0100
parents 1534df518201
children 1ec4c5633eb6
comparison
equal deleted inserted replaced
2513:1534df518201 2515:6bcaa8bf2603
60 60
61 slices := make([][]int32, S) 61 slices := make([][]int32, S)
62 rest := items 62 rest := items
63 for i := range slices { 63 for i := range slices {
64 var n int 64 var n int
65 if len(rest) < sm { 65 if l := len(rest); l < sm {
66 n = len(rest) 66 n = l
67 } else { 67 } else {
68 n = sm 68 n = sm
69 } 69 }
70 slices[i] = rest[:n] 70 slices[i] = rest[:n]
71 rest = rest[n:] 71 rest = rest[n:]
75 75
76 for _, slice := range slices { 76 for _, slice := range slices {
77 sort.Slice(slice, func(i, j int) bool { 77 sort.Slice(slice, func(i, j int) bool {
78 ti := s.triangles[slice[i]] 78 ti := s.triangles[slice[i]]
79 tj := s.triangles[slice[j]] 79 tj := s.triangles[slice[j]]
80 return s.tri.Points[ti[0]].X < s.tri.Points[tj[0]].X 80 return s.tri.Points[ti[0]].Y < s.tri.Points[tj[0]].Y
81 }) 81 })
82 82
83 for len(slice) > 0 { 83 for len(slice) > 0 {
84 n := numEntries 84 n := numEntries
85 if l := len(slice); l < numEntries { 85 if l := len(slice); l < numEntries {
91 } 91 }
92 92
93 return s.buildNodes(leaves) 93 return s.buildNodes(leaves)
94 } 94 }
95 95
96 func bboxIndex(idx int32) int32 { 96 func (s *STRTree) bbox(idx int32) Box2D {
97 if idx < 0 { 97 if idx < 0 { // Don't care if leaf or node.
98 return -idx - 1 98 idx = -idx - 1
99 } 99 }
100 return idx 100 return s.bboxes[s.index[idx]]
101 } 101 }
102 102
103 func (s *STRTree) buildNodes(items []int32) int32 { 103 func (s *STRTree) buildNodes(items []int32) int32 {
104 104
105 if len(items) <= numEntries { 105 if len(items) <= numEntries {
106 return s.allocNode(items) 106 return s.allocNode(items)
107 } 107 }
108 108
109 sort.Slice(items, func(i, j int) bool { 109 sort.Slice(items, func(i, j int) bool {
110 bi := s.bboxes[s.index[bboxIndex(items[i])]] 110 return s.bbox(items[i]).X1 < s.bbox(items[j]).X1
111 bj := s.bboxes[s.index[bboxIndex(items[j])]]
112 return bi.X1 < bj.X1
113 }) 111 })
114 112
115 P := int(math.Ceil(float64(len(items)) / float64(numEntries))) 113 P := int(math.Ceil(float64(len(items)) / float64(numEntries)))
116 S := int(math.Ceil(math.Sqrt(float64(P)))) 114 S := int(math.Ceil(math.Sqrt(float64(P))))
117 115
118 sm := S * numEntries 116 sm := S * numEntries
119 117
120 slices := make([][]int32, S) 118 slices := make([][]int32, S)
121 /*
122 log.Printf("S: %d\n", S)
123 log.Printf("SM: %d\n", sm)
124 log.Printf("S * SM: %d\n", S*sm)
125 log.Printf("N: %d\n", len(items))
126 */
127 119
128 rest := items 120 rest := items
129 for i := range slices { 121 for i := range slices {
130 var n int 122 var n int
131 if len(rest) < sm { 123 if l := len(rest); l < sm {
132 n = len(rest) 124 n = l
133 } else { 125 } else {
134 n = sm 126 n = sm
135 } 127 }
136 slices[i] = rest[:n] 128 slices[i] = rest[:n]
137 rest = rest[n:] 129 rest = rest[n:]
139 131
140 nodes := make([]int32, 0, S*S) 132 nodes := make([]int32, 0, S*S)
141 133
142 for _, slice := range slices { 134 for _, slice := range slices {
143 sort.Slice(slice, func(i, j int) bool { 135 sort.Slice(slice, func(i, j int) bool {
144 bi := s.bboxes[s.index[bboxIndex(slice[i])]] 136 return s.bbox(slice[i]).Y1 < s.bbox(slice[j]).Y1
145 bj := s.bboxes[s.index[bboxIndex(slice[j])]]
146 return bi.X1 < bj.X1
147 }) 137 })
148 138
149 for len(slice) > 0 { 139 for len(slice) > 0 {
150 n := numEntries 140 n := numEntries
151 if l := len(slice); l < numEntries { 141 if l := len(slice); l < numEntries {
159 return s.buildNodes(nodes) 149 return s.buildNodes(nodes)
160 } 150 }
161 151
162 func (s *STRTree) allocNode(items []int32) int32 { 152 func (s *STRTree) allocNode(items []int32) int32 {
163 pos := len(s.index) 153 pos := len(s.index)
164 s.index = append(s.index, 0) 154 s.index = append(s.index, 0, int32(len(items)))
165 s.index = append(s.index, items...) 155 s.index = append(s.index, items...)
166 if len(items) > 0 { 156 if len(items) > 0 {
167 box := s.bboxes[s.index[bboxIndex(items[0])]] 157 box := s.bbox(items[0])
168 for i := 1; i < len(items); i++ { 158 for i := 1; i < len(items); i++ {
169 it := items[i] 159 box = box.Union(s.bbox(items[i]))
170 b := s.bboxes[s.index[bboxIndex(it)]]
171 box = box.Union(b)
172 } 160 }
173 s.index[pos] = int32(s.allocBBox(box)) 161 s.index[pos] = int32(s.allocBBox(box))
174 } 162 }
175 return int32(pos) 163 return int32(pos)
176 } 164 }
181 return pos 169 return pos
182 } 170 }
183 171
184 func (s *STRTree) allocLeaf(items []int32) int32 { 172 func (s *STRTree) allocLeaf(items []int32) int32 {
185 pos := len(s.index) 173 pos := len(s.index)
186 s.index = append(s.index, 0) 174 s.index = append(s.index, 0, int32(len(items)))
187 s.index = append(s.index, items...) 175 s.index = append(s.index, items...)
188 if len(items) > 0 { 176 if len(items) > 0 {
177 vertices := s.tri.Points
189 ti := s.triangles[items[0]] 178 ti := s.triangles[items[0]]
190 t := Triangle{ 179 t := Triangle{
191 s.tri.Points[ti[0]], 180 vertices[ti[0]],
192 s.tri.Points[ti[1]], 181 vertices[ti[1]],
193 s.tri.Points[ti[2]], 182 vertices[ti[2]],
194 } 183 }
195 box := t.BBox() 184 box := t.BBox()
196 for i := 1; i < len(items); i++ { 185 for i := 1; i < len(items); i++ {
197 it := items[i] 186 it := items[i]
198 ti := s.triangles[it] 187 ti := s.triangles[it]
199 t := Triangle{ 188 t := Triangle{
200 s.tri.Points[ti[0]], 189 vertices[ti[0]],
201 s.tri.Points[ti[1]], 190 vertices[ti[1]],
202 s.tri.Points[ti[2]], 191 vertices[ti[2]],
203 } 192 }
204 box = box.Union(t.BBox()) 193 box = box.Union(t.BBox())
205 } 194 }
206 s.index[pos] = int32(s.allocBBox(box)) 195 s.index[pos] = int32(s.allocBBox(box))
207 } 196 }
208 return -int32(pos) - 1 197 return int32(-(pos + 1))
209 } 198 }