-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcurve_renderer.cpp
More file actions
205 lines (159 loc) · 6.16 KB
/
curve_renderer.cpp
File metadata and controls
205 lines (159 loc) · 6.16 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "curve_renderer.h"
#include "GL/glut.h"
#include "GL/freeglut_ext.h"
// Initialize the curve renderer
curve_renderer::curve_renderer()
{
// no curve yet
curve = 0;
// Width and heigth of the basis function graph
basis_width = 300;
basis_height = 100;
}
// Set the active curve to render
void curve_renderer::set_curve(abstract_curve *curve)
{
this->curve = curve;
}
// Sample the curve using "sample_count" samples and store the
// result in the list "samples".
void curve_renderer::sample_curve(int sample_count)
{
samples.clear();
// Nothing to sample if there are not at least 2 control points
if (curve->get_control_points().size()<2)
return;
/***************
Task 4.1.2. Fill the list "samples" with "sample_count" curve points that
are equally sampled along the domain of "t". Mind that this
domain does not always have to range from 0 to 1. You will find
helper methods in "abstract_curve.h". To add a point to the list
use the "push_back"-Method of the "samples"-object.
Aufgabe 4.1.2. Fuellen Sie die Liste "samples" mit "sample_count" Kurvenpunkten,
die gleichmaessig ueber den Wertebereich von "t" verteilt sind.
Beachten Sie, dass dieser Wertebereich nicht zwingend von 0 bis
1 gehen muss. Sie finden Helfermethoden in "abstract_curve.h".
Um einen Punkt in die Liste hinzuzufuegen nutzen Sie die
"push_back"-Methode des "samples"-Objektes.
****************/
// Remove the following lines
//Schrittweite für gleichmäßige Verteilung "/..."
double step = (curve->get_max_t() - curve->get_min_t()) / sample_count;
if (step<=0.0)
return;
for (double t=curve->get_min_t(); t<=curve->get_max_t(); t+=step){
//std::cout<<"t: "<<t<<" point: "<<curve->evaluate(t)<<std::endl;
//Einfügen der Vektoren in die Liste Samples mit der vorher berechneten Schrittweite
//(...) gibt Punkt zu zeichnen zurück [evaluate(t) aus vorheriger Aufgabe]
samples.push_back(curve->evaluate(t));
}
}
// Render the curve
void curve_renderer::render_curve()
{
int n = samples.size();
// Set the color to green
glColor3d(0, 1, 0);
/************
Task 4.1.2. Connect the points in the "samples" list with a consecutive line.
You can get the x and y values of an element with the "x()" and
"y()" methods of a point2d object (of which the list consists).
Aufgabe 4.1.2. Verbinden Sie die Punkte der "samples"-List mit einer geschlossenen
Linie. Um die x- und y-Koordinaten eines Punktes zu erhalten nutzen
Sie die "x()"- und "y()"-Methoden eines point2d-Objektes (aus denen
die Liste besteht).
*************/
//Verbindet Linien zwischen for-Punkten
glBegin(GL_LINE_STRIP);
//Durchlaufen aller Punkte
for(int i = 0; i<n; i++){
//glVertex2d(x-Wert des Punktes, y-Wert des Punktes)
glVertex2d(samples.at(i).x(), samples.at(i).y());
}
glEnd();
}
// Render the basis functions coordinate system
void curve_renderer::render_basis_axes()
{
glPushMatrix();
// Translate to the lower right corner
glTranslated(glutGet(GLUT_WINDOW_WIDTH) - basis_width - 10, glutGet(GLUT_WINDOW_HEIGHT) - basis_height - 10, 0);
// Render the axes
glColor3d(0, 0, 0);
glBegin(GL_LINES);
// Vertical
glVertex2d(0, basis_height);
glVertex2d(0, -basis_height);
// Horizontal
glVertex2d(0, 0);
glVertex2d(basis_width, 0);
// Small vertical at the end of the abszissa
glVertex2d(basis_width, -3);
glVertex2d(basis_width, 3);
glEnd();
// Render the maximum t
double t_max = curve->get_max_t();
if (t_max<=0.0)
t_max = 1.0;
stringstream s;
s<<t_max;
glColor3d(0.0, 0.0, 0.0);
glRasterPos2i(basis_width-5, 15);
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)s.str().c_str());
glPopMatrix();
}
// A helper function you can use to set a color for the basis function
void curve_renderer::set_basis_color(int i)
{
i++;
// Set the color according to the basis function to render
glColor3d(i%2, (i%3)/2.0, (i%5)/6.0);
}
// Render the basis functions
void curve_renderer::render_basis_functions()
{
double t_max = curve->get_max_t();
double t_min = curve->get_min_t();
// Only render the axes if the range is too small
if (t_max <=0.0) {
render_basis_axes();
return;
}
// Translate to the lower bottom of the screen and scale
// into the local coordinate system of the basis function graph
glPushMatrix();
glTranslated(glutGet(GLUT_WINDOW_WIDTH) - basis_width - 10, glutGet(GLUT_WINDOW_HEIGHT) - basis_height - 10, 0);
glScaled(basis_width/t_max, -basis_height, 1);
/**********
Task 4.1.3. Render the basis functions of the curve "curve" by rendering
a consecutive line for every function. To set the color you
can use the method "set_basis_color" with the index of the
basis function as parameter. The system is already translated
and scaled so you can use "t" and the value of the basis function
directly as inputs for the line segments.
Aufgabe 4.1.3. Rendern Sie die Basisfunktionen der Kurve "curve" indem Sie fuer
jede Basisfunktion eine geschlossene Linie zeichnen lassen. Um
eine Zeichenfarbe zu setzen koennen Sie die Methode "set_basis_color"
verwenden, welcher der Index der darzustellenden Basisfunktionen als
Parameter mitgegeben wird. Das Koordinatensystem ist bereits so
verschoben und skaliert, dass Sie die Werte fuer "t" und die der
Basisfunktionen direkt als Eingaben fuer die Liniensegmente verwenden
koennen.
************/
//Anzahl der Kontrollpunkte = Anzahl der Basisfunktionen
int controlPoints = curve->get_control_points().size();
//for: jede Basisfunktion...
for(int i = 0; i <= controlPoints-1; i++){
glBegin(GL_LINE_STRIP);
//... eine andere Farbe
set_basis_color(i);
//... eine eigene Funktion für alle t evaluieren
for(double t = t_min; t <= t_max; t += (t_max-t_min)/basis_width){
glVertex2d(t, curve->evaluate_basis(i, t));
}
glEnd();
}
glPopMatrix();
// Render the axes
render_basis_axes();
}