Projekt

Obecné

Profil

Stáhnout (5.85 KB) Statistiky
| Větev: | Tag: | Revize:
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
}
(7-7/10)