-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
112 lines (105 loc) · 3.4 KB
/
main.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
package main
import (
"fmt"
"math"
"math/rand"
"time"
)
var RANDOM = rand.New(rand.NewSource(time.Now().UnixNano()))
func main() {
system := New("S")
system.AddWeightedProduction('S', "QX", 10)
system.AddWeightedProduction('B', "BB", 10)
system.AddWeightedProduction('B', "B", 10)
system.AddProduction('X', "B[LX[RX]B][RX[LX]B]X")
lString := system.Iterate(8)
XZ := RANDOM.Float64() * 0.05
Y := RANDOM.Float64() * 0.2
branch, _ := createBranch(lString, 0, false, 0.3-XZ, 1-Y, 0.3-XZ)
fmt.Printf("return %s", branch)
}
func createBranch(lString string, si int, lastWasBranch bool, lastScaleX float64, lastScaleY float64, lastScaleZ float64) (string, int) {
children := make([]string, 0)
i := si
OUTER:
for ; i < len(lString); i++ {
switch lString[i] {
case '[':
var branchName string
branchName, i = createBranch(lString, i+1, lastWasBranch, lastScaleX, lastScaleY, lastScaleZ)
if len(children) == 0 {
node := fmt.Sprintf("node%d", i)
fmt.Printf("%s = rt.node('%s')\n", node, node)
children = append(children, node)
}
if branchName != "" {
fmt.Printf("%s:add_child(%s)\n", children[len(children)-1], branchName)
}
case ']':
break OUTER
case 'B':
name := fmt.Sprintf("branch%d", i)
children = append(children, name)
fmt.Printf("%s = rt.cylinder('%s')\n", name, name)
if lastWasBranch {
fmt.Printf("%s:translate(0, 1, 0)\n", name)
} else {
XZ := (RANDOM.Float64() * 0.1) + 0.04
lastScaleX = math.Max(0.05, lastScaleX-XZ)
lastScaleY = math.Max(0.3, lastScaleY-(RANDOM.Float64()*0.1)-0.05)
lastScaleZ = math.Max(0.05, lastScaleZ-XZ)
fmt.Printf("%s:scale(%f, %f, %f)\n", name, lastScaleX, lastScaleY, lastScaleZ)
}
fmt.Printf("%s:set_material(tree)\n", name)
lastWasBranch = true
case 'R':
name := fmt.Sprintf("branchrot%d", i)
children = append(children, name)
fmt.Printf("%s = rt.node('%s')\n", name, name)
zRotation := RANDOM.Intn(20) + 25
yRotation := RANDOM.Intn(160) - 80
fmt.Printf("%s:rotate('z', %d)\n", name, zRotation)
fmt.Printf("%s:rotate('y', %d)\n", name, yRotation)
fmt.Printf("%s:scale(1/%f, 1/%f, 1/%f)\n", name, lastScaleX, lastScaleY, lastScaleZ)
fmt.Printf("%s:translate(0, 0.9, 0)\n", name)
lastWasBranch = false
case 'L':
name := fmt.Sprintf("branchrot%d", i)
children = append(children, name)
fmt.Printf("%s = rt.node('%s')\n", name, name)
zRotation := -(RANDOM.Intn(20) + 25)
yRotation := RANDOM.Intn(160) - 80
fmt.Printf("%s:rotate('z', %d)\n", name, zRotation)
fmt.Printf("%s:rotate('y', %d)\n", name, yRotation)
fmt.Printf("%s:scale(1/%f, 1/%f, 1/%f)\n", name, lastScaleX, lastScaleY, lastScaleZ)
fmt.Printf("%s:translate(0, 0.9, 0)\n", name)
lastWasBranch = false
case 'Q':
name := fmt.Sprintf("branchrot%d", i)
children = append(children, name)
fmt.Printf("%s = rt.node('%s')\n", name, name)
zRotation := RANDOM.Intn(20) - 10
yRotation := RANDOM.Intn(160) - 80
fmt.Printf("%s:rotate('z', %d)\n", name, zRotation)
fmt.Printf("%s:rotate('y', %d)\n", name, yRotation)
lastWasBranch = false
}
}
// add children
currIndex := len(children) - 1
prev := ""
for currIndex >= 0 {
if prev != "" && children[currIndex] != "" {
fmt.Printf("%s:add_child(%s)\n", children[currIndex], prev)
}
if children[currIndex] != "" {
prev = children[currIndex]
}
currIndex--
}
if len(children) > 0 {
return children[0], i
} else {
return "", i
}
}