1 |
c137512e
|
Oto Šťáva
|
#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 |
|
|
}
|