-
Notifications
You must be signed in to change notification settings - Fork 0
/
LSystem3D.cpp
104 lines (88 loc) · 3.31 KB
/
LSystem3D.cpp
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
//
// Created by arno on 3/13/19.
//
#include "LSystem3D.h"
#include <cmath>
Figure draw3DLSystem(const LParser::LSystem3D &l_system, std::vector<double> color) {
std::string str = replace_string(l_system.get_initiator(), l_system, l_system.get_nr_iterations());
Figure lines;
lines.ambientReflection = ColorD(color);
Vector3D H = Vector3D::vector(1, 0, 0);
Vector3D L = Vector3D::vector(0, 1, 0);
Vector3D U = Vector3D::vector(0, 0, 1);
std::vector<std::vector<Vector3D>> round_brackets_stack = {};
Vector3D current_position = Vector3D::point(0, 0, 0);
double angle = l_system.get_angle() * M_PI / 180;
for(char c: str){
if(c == '+'){
Vector3D newH = H*cos(angle) + L * sin(angle);
Vector3D newL = -H * sin(angle) + L*cos(angle);
H = newH;
L = newL;
continue;
} else if(c == '-'){
Vector3D newH = H*cos(-angle) + L * sin(-angle);
Vector3D newL = -H * sin(-angle) + L*cos(-angle);
H = newH;
L = newL;
continue;
} else if (c == '^') {
Vector3D newH = H*cos(angle) + U*sin(angle);
Vector3D newU = -H*sin(angle) + U*cos(angle);
H = newH;
U = newU;
} else if (c == '&') {
Vector3D newH = H*cos(-angle) + U*sin(-angle);
Vector3D newU = -H*sin(-angle) + U*cos(-angle);
H = newH;
U = newU;
} else if (c == '\\') {
Vector3D newL = L*cos(angle) - U*sin(angle);
Vector3D newU = L*sin(angle) + U*cos(angle);
L = newL;
U = newU;
} else if (c == '/') {
Vector3D newL = L*cos(-angle) - U*sin(-angle);
Vector3D newU = L*sin(-angle) + U*cos(-angle);
L = newL;
U = newU;
} else if (c == '|') {
H = -H;
L = -L;
} else if(c=='(') {
round_brackets_stack.push_back({current_position, H, L, U});
continue;
} else if(c == ')') {
std::vector<Vector3D> old_location = round_brackets_stack.back();
current_position = old_location[0];
H = old_location[1];
L = old_location[2];
U = old_location[3];
round_brackets_stack.pop_back();
continue;
} else {
Vector3D old_position = current_position;
current_position += H;
if (l_system.draw(c)) {
lines.points.push_back(old_position);
lines.points.push_back(current_position);
lines.faces.emplace_back(Face({static_cast<int>(lines.points.size() - 1),
static_cast<int>(lines.points.size() - 2)}));
}
continue;
}
}
return lines;
}
std::string replace_string(const std::string &str, const LParser::LSystem3D &l_system, const int &size) {
if(size == 0){ return str; }
std::string new_string = "";
for (char c: str){
if (c == '+' or c == '-' or c == '(' or c ==')' or c == '^' or c == '&' or c == '/' or c == '\\' or c == '|'){
new_string += c;
continue;
}
new_string += l_system.get_replacement(c);
}
return replace_string(new_string, l_system, size-1);
}