comparison pkg/octree/tree.go @ 755:1a1a8b5f2d02

Vertical traversal of octree for cross sections. WIP.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 24 Sep 2018 18:41:29 +0200
parents e9d37300ce99
children 5e14000829d1
comparison
equal deleted inserted replaced
754:105c421f99b1 755:1a1a8b5f2d02
13 13
14 Min Vertex 14 Min Vertex
15 Max Vertex 15 Max Vertex
16 } 16 }
17 17
18 type box2d struct {
19 x1 float64
20 y1 float64
21 x2 float64
22 y2 float64
23 }
24
25 func (a box2d) intersects(b box2d) bool {
26 return !(a.x2 < a.x1 || a.x2 < b.x1 ||
27 a.y2 < a.y1 || a.y2 < b.y1)
28 }
29
30 func (a box2d) mid() (float64, float64) {
31 return (a.x2-a.x1)*0.5 + a.x1, (a.y2-a.y1)*0.5 + a.y1
32 }
33
34 func (a box2d) xi(i int) float64 {
35 if i == 0 {
36 return a.x1
37 }
38 return a.x2
39 }
40
41 func (a box2d) yi(i int) float64 {
42 if i == 0 {
43 return a.y1
44 }
45 return a.y2
46 }
47
48 var scale = [][]float64{
49 {0.0, 0.0, 0.5, 0.5},
50 {0.5, 0.0, 1.0, 0.5},
51 {0.0, 0.5, 0.5, 1.0},
52 {0.5, 0.5, 1.0, 1.0},
53 }
54
55 func (ot *Tree) Vertical(x1, y1, x2, y2 float64, fn func(*Triangle)) {
56
57 box := box2d{
58 x1: math.Min(x1, x2),
59 y1: math.Min(y1, y2),
60 x2: math.Max(x1, x2),
61 y2: math.Max(y1, y2),
62 }
63
64 // out of bounding box
65 if box.x2 < ot.Min.X || ot.Max.X < box.x1 ||
66 box.y2 < ot.Min.Y || ot.Max.Y < box.y1 {
67 return
68 }
69
70 type frame struct {
71 pos int32
72 box2d
73 }
74
75 stack := []frame{{1, box2d{ot.Min.X, ot.Min.Y, ot.Max.X, ot.Max.Y}}}
76
77 for len(stack) > 0 {
78 top := stack[len(stack)-1]
79 stack = stack[:len(stack)-1]
80
81 if top.pos > 0 { // node
82 midx, midy := top.mid()
83
84 var all uint
85 for i := 0; i < 2; i++ {
86 for j := 0; j < 2; j++ {
87 x, y := box.xi(i), box.yi(j)
88 var code uint
89 if x > midx {
90 code |= 1
91 }
92 if y > midy {
93 code |= 2
94 }
95 all |= 1 << code
96 }
97 }
98
99 dx := top.x2 - top.x1
100 dy := top.y2 - top.y1
101 for i := 0; all != 0; i++ {
102 if all&1 == 1 {
103 s := scale[i]
104 nbox := box2d{
105 dx*s[0] + top.x1,
106 dy*s[1] + top.y1,
107 dx*s[2] + top.x1,
108 dy*s[3] + top.y1,
109 }
110 // TODO: Push two frames to stack.
111 _ = nbox
112 }
113 all >>= 1
114 }
115
116 } else { // leaf
117 }
118 }
119 }
120
18 func (ot *Tree) Horizontal(h float64, fn func(*Triangle)) { 121 func (ot *Tree) Horizontal(h float64, fn func(*Triangle)) {
122
123 if h < ot.Min.Z || ot.Max.Z < h {
124 return
125 }
19 126
20 type frame struct { 127 type frame struct {
21 pos int32 128 pos int32
22 min float64 129 min float64
23 max float64 130 max float64
24 }
25
26 if h < ot.Min.Z || ot.Max.Z < h {
27 return
28 } 131 }
29 132
30 stack := []frame{{1, ot.Min.Z, ot.Max.Z}} 133 stack := []frame{{1, ot.Min.Z, ot.Max.Z}}
31 134
32 dupes := map[int32]struct{}{} 135 dupes := map[int32]struct{}{}