1
|
#include "trajectory.hpp"
|
2
|
|
3
|
const float Trajectory::MAX_RADIUS = 120.0f;
|
4
|
const float Trajectory::MIN_RADIUS = 50.0f;
|
5
|
const int Trajectory::SMOOTHING = 50;
|
6
|
|
7
|
Trajectory::Trajectory(): Element(Element::TRAJECTORY)
|
8
|
{
|
9
|
set = false;
|
10
|
}
|
11
|
|
12
|
bool Trajectory::isSet()
|
13
|
{
|
14
|
return set;
|
15
|
}
|
16
|
|
17
|
void Trajectory::setNewCurve(QList<QVector3D> data, const float minimumZ, const float maximumZ)
|
18
|
{
|
19
|
// Uvolneni pameti od stareho tubusu.
|
20
|
clear();
|
21
|
|
22
|
// Vyhozeni zbytecnych bodu.
|
23
|
QList<QVector3D> mData;
|
24
|
QVector3D lastPoint;
|
25
|
for (int i = 0; i < data.count(); i++)
|
26
|
{
|
27
|
if (i > 0 && (data.at(i) - lastPoint).length() < 50)
|
28
|
{
|
29
|
continue;
|
30
|
}
|
31
|
else
|
32
|
{
|
33
|
mData.append(data.at(i));
|
34
|
lastPoint = data.at(i);
|
35
|
}
|
36
|
}
|
37
|
|
38
|
data = mData;
|
39
|
int lastIndex = data.count() - 1;
|
40
|
|
41
|
// Vytvoreni vektoru mezi predchozim a nasledujicim bodem.
|
42
|
QVector3D dv[data.count()];
|
43
|
for (int i = 1; i < lastIndex; i++)
|
44
|
{
|
45
|
dv[i] = data.at(i + 1) - data.at(i - 1);
|
46
|
}
|
47
|
dv[0] = data.at(1) - data.at(0);
|
48
|
//pokud maji prvni dva body stejnou y osu - krivka se nevykresli (nevim proc) - pro jistotu pridame 1 ke kazde ose
|
49
|
dv[0] += QVector3D(1,1,1);
|
50
|
dv[lastIndex] = data.last() - data.at(data.count() - 2);
|
51
|
|
52
|
// Inicializace prvniho normaloveho vektoru pro urceni bodu na kruznici.
|
53
|
QVector3D a(0,0,0);
|
54
|
int index = 0;
|
55
|
float smallest = dv[0].x();
|
56
|
if (dv[0].y() < smallest)
|
57
|
{
|
58
|
smallest = dv[0].y();
|
59
|
index = 1;
|
60
|
}
|
61
|
if (dv[0].z() < smallest)
|
62
|
{
|
63
|
index = 2;
|
64
|
}
|
65
|
switch (index)
|
66
|
{
|
67
|
case 0: a.setX(1.0f); break;
|
68
|
case 1: a.setY(1.0f); break;
|
69
|
default: a.setZ(1.0f); break;
|
70
|
}
|
71
|
|
72
|
// Vypocteni rozsahu souradnic a radiusu.
|
73
|
float rangeZ = maximumZ - minimumZ;
|
74
|
float rangeRadius = MAX_RADIUS - MIN_RADIUS;
|
75
|
|
76
|
// Jestli jde o uzavrenou krivku.
|
77
|
bool flSamePoints = data.at(0) == data.at(lastIndex);
|
78
|
|
79
|
// Vytvoreni tubusu.
|
80
|
QVector3D vertices[data.count()][SMOOTHING];
|
81
|
for (int i = 0; i < data.count(); i++)
|
82
|
{
|
83
|
// a, b jsou normalove vektory definujici kruznici kolem daneho bodu.
|
84
|
QVector3D b = QVector3D::crossProduct(a, dv[i]).normalized();
|
85
|
a = QVector3D::crossProduct(dv[i], b).normalized();
|
86
|
|
87
|
if (i != lastIndex || !flSamePoints)
|
88
|
{
|
89
|
float rTube = MIN_RADIUS + (data[i].z() - minimumZ) / rangeZ * rangeRadius;
|
90
|
for (int j = 0; j < SMOOTHING; j++)
|
91
|
{
|
92
|
double th = j * 2 * M_PI / SMOOTHING;
|
93
|
vertices[i][j] = data[i] + cos(th) * rTube * a + sin(th) * rTube * b;
|
94
|
}
|
95
|
}
|
96
|
}
|
97
|
|
98
|
if (flSamePoints)
|
99
|
{
|
100
|
// Pokud jde o uzavrenou krivku, spojit prvni a posledni kruznici.
|
101
|
for (int i = 0; i < SMOOTHING; i++)
|
102
|
{
|
103
|
vertices[lastIndex][i] = vertices[0][i];
|
104
|
}
|
105
|
}
|
106
|
else
|
107
|
{
|
108
|
// Pokud nejde o uzavrenou krivku, vytvorit krytky koncu.
|
109
|
for (int i = 0; i < SMOOTHING; i++)
|
110
|
{
|
111
|
addTriangle(vertices[0][i], vertices[0][(i + 1) % SMOOTHING], data.at(0));
|
112
|
addTriangle(data.at(lastIndex), vertices[lastIndex][(i + 1) % SMOOTHING], vertices[lastIndex][i]);
|
113
|
}
|
114
|
}
|
115
|
|
116
|
// Vytvoreni trojuhelnikove site.
|
117
|
for (int i = 0; i < lastIndex; i++)
|
118
|
{
|
119
|
for (int j = 0; j < SMOOTHING; j++)
|
120
|
{
|
121
|
addTetragon(vertices[i][j], vertices[i][(j + 1) % SMOOTHING], vertices[i+1][(j + 1) % SMOOTHING], vertices[i+1][j]);
|
122
|
}
|
123
|
}
|
124
|
// Nyni muze byt draha vykreslena.
|
125
|
set = true;
|
126
|
}
|
127
|
|
128
|
void Trajectory::addNewPointToCurve(QVector3D point, const bool start, const bool finish)
|
129
|
{
|
130
|
if (start) {
|
131
|
clear();
|
132
|
curve.clear();
|
133
|
newCurvePointCount = 0;
|
134
|
}
|
135
|
|
136
|
if (curve.size() > 0 && (point - curve.last()).length() < 50)
|
137
|
return;
|
138
|
|
139
|
if (curve.size() > MAX_CURVE_SIZE)
|
140
|
return;
|
141
|
|
142
|
curve.append(point-QVector3D(0,0,4500));
|
143
|
|
144
|
if (curve.size() < 4)
|
145
|
return;
|
146
|
|
147
|
/*setNewCurve(curve, -4500,4500);
|
148
|
curve.clear();
|
149
|
return;*/
|
150
|
|
151
|
// Vytvoreni vektoru mezi predchozim a nasledujicim bodem.
|
152
|
QVector3D dv, dv1, dv0;
|
153
|
int pos = curve.count();
|
154
|
|
155
|
dv0 = curve.at(pos-3) - curve.at(pos-4);
|
156
|
dv0 += QVector3D(1,1,1);
|
157
|
dv = curve.last() - curve.at(pos-3);
|
158
|
dv1 = curve.at(pos-2) - curve.at(pos - 4);
|
159
|
|
160
|
// Inicializace prvniho normaloveho vektoru pro urceni bodu na kruznici.
|
161
|
QVector3D a(0,0,0), a1;
|
162
|
int index = 0;
|
163
|
float smallest = dv0.x();
|
164
|
if (dv0.y() < smallest)
|
165
|
{
|
166
|
smallest = dv0.y();
|
167
|
index = 1;
|
168
|
}
|
169
|
if (dv0.z() < smallest)
|
170
|
{
|
171
|
index = 2;
|
172
|
}
|
173
|
switch (index)
|
174
|
{
|
175
|
case 0: a.setX(1.0f); break;
|
176
|
case 1: a.setY(1.0f); break;
|
177
|
default: a.setZ(1.0f); break;
|
178
|
}
|
179
|
|
180
|
// Vypocteni rozsahu souradnic a radiusu.
|
181
|
float rangeZ = 9000;
|
182
|
float rangeRadius = MAX_RADIUS - MIN_RADIUS;
|
183
|
|
184
|
// Vytvoreni tubusu.
|
185
|
QVector3D vertices[2][SMOOTHING];
|
186
|
// a, b jsou normalove vektory definujici kruznici kolem daneho bodu.
|
187
|
a1 = a;
|
188
|
QVector3D b = QVector3D::crossProduct(a, dv).normalized();
|
189
|
QVector3D b1 = QVector3D::crossProduct(a, dv1).normalized();
|
190
|
a = QVector3D::crossProduct(dv, b).normalized();
|
191
|
a1 = QVector3D::crossProduct(dv1, b1).normalized();
|
192
|
|
193
|
float rTube = MIN_RADIUS + (curve.at(curve.count()-2).z() + 4500) / rangeZ * rangeRadius;
|
194
|
float rTube1 = MIN_RADIUS + (curve.at(curve.count()-3).z() + 4500) / rangeZ * rangeRadius;
|
195
|
for (int j = 0; j < SMOOTHING; j++)
|
196
|
{
|
197
|
double th = j * 2 * M_PI / SMOOTHING;
|
198
|
vertices[0][j] = curve.at(curve.count()-3) + cos(th) * rTube * a + sin(th) * rTube * b;
|
199
|
vertices[1][j] = curve.at(curve.count()-2) + cos(th) * rTube * a + sin(th) * rTube * b;
|
200
|
}
|
201
|
|
202
|
for (int j = 0; j < SMOOTHING; j++)
|
203
|
{
|
204
|
addTetragon(vertices[0][j], vertices[0][(j + 1) % SMOOTHING], vertices[1][(j + 1) % SMOOTHING], vertices[1][j]);
|
205
|
}
|
206
|
|
207
|
set = true;
|
208
|
|
209
|
if (finish) {
|
210
|
//end of tube
|
211
|
}
|
212
|
}
|