-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2d_lsystems.cpp
More file actions
121 lines (99 loc) · 3.76 KB
/
Copy path2d_lsystems.cpp
File metadata and controls
121 lines (99 loc) · 3.76 KB
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
113
114
115
116
117
118
119
120
121
//
// Created by Kobe De Broeck on 3-4-2022.
//
#include "2d_lsystems.h"
#include <stack>
#include "l_parser.h"
#include <fstream>
#include "line_drawing_utils.h"
using namespace std;
namespace KDBRenderUtils {
struct PenState {
Point2D cur;
double angle;
double angleDelta;
NormColor color;
};
static std::stack<PenState> penStateStack;
static PenState penState;
void drawLSystemRecursive(
int nrIterations,
const std::string& penInstructions,
std::vector<Line2D>& lines,
const LParser::LSystem2D& lSystem
);
std::vector<Line2D> drawLSystem(const LParser::LSystem2D& lSystem, NormColor lineColor )
{
std::vector<Line2D> lines;
penState.cur = {0,0};
penState.angleDelta = rad(lSystem.get_angle());
penState.angle = rad(lSystem.get_starting_angle());
penState.color = lineColor;
drawLSystemRecursive(lSystem.get_nr_iterations(), lSystem.get_initiator(), lines, lSystem);
return lines;
}
void drawLSystemRecursive(
int nrIterations,
const std::string& penInstructions,
std::vector<Line2D>& lines,
const LParser::LSystem2D& lSystem
)
{
for( char c : penInstructions) {
if( lSystem.get_alphabet().find(c) != lSystem.get_alphabet().end())
{
if(nrIterations <= 0) {
auto next = penState.cur + Point2D{cos(penState.angle), sin(penState.angle)};
if(lSystem.draw(c)) {
lines.push_back({penState.cur, next, penState.color, 0, 0});
}
penState.cur = next;
continue;
}
drawLSystemRecursive(nrIterations-1, lSystem.get_replacement(c), lines, lSystem);
continue;
}
if( c == '(') {
penStateStack.push(penState);
continue;
}
if(c == ')') {
penState = penStateStack.top();
penStateStack.pop();
continue;
}
if( c == '+') {
penState.angle += penState.angleDelta;
continue;
}
if(c == '-') {
penState.angle -= penState.angleDelta;
continue;
}
}
}
img::EasyImage draw2DLSystem(const ini::Configuration& configuration)
{
if(configuration["General"]["type"].as_string_or_default("") != "2DLSystem") {
cerr << "draw2DLSystem didn't get a 2DLSystem config!\n";
return {};
}
unsigned size = configuration["General"]["size"].as_int_or_default(0);
auto backgroundColorVec = configuration["General"]["backgroundcolor"].as_double_tuple_or_default({0,0,0});
std::string inputFile = configuration["2DLSystem"]["inputfile"].as_string_or_die();
auto lineColorVec = configuration["2DLSystem"]["color"].as_double_tuple_or_default({1,0,1});
NormColor lineColor = toNormColor(lineColorVec);
LParser::LSystem2D lSystem;
std::ifstream ifs{inputFile};
ifs >> lSystem;
if(!ifs) std::cerr << "Couldn't read l-system\n";
std::vector<Line2D> lines = drawLSystem(lSystem, lineColor);
//return draw2DLines(lines, size, vec_to_color(backgroundColorVec));
img::EasyImage result;
result = draw2DLines(lines, size, toNormColor(backgroundColorVec));
// Om de move constructor en move assignment uit te testen, moeten we copy elision voorkomen.
// Dit doen we door result te muteren voor dat we ze terug te geven aan de caller
result(0,0) = img::Color{1,2,3};
return result;
}
}