-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbar.cc
More file actions
287 lines (267 loc) · 10.6 KB
/
bar.cc
File metadata and controls
287 lines (267 loc) · 10.6 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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#include <cmath>
#include <iostream>
#include <cstdlib>
#include "vect2d.h"
#include "bar.h"
//default ctor
bar::bar() :
mass_p (1.) ,
lenght_p (1.),
baricentro_p (0.5),
theta_p (0.), //theta_p (0.- (3.14159265358979323846264338327950288/2.))
veltheta_p (0.)
{
vect2d perno_p (0., 0.);
vect2d velperno_p (0., 0.);
SetPosEstremo ();
SetVelEstremo ();
} //NB per chiamare questo costruttore scrivere:
//bar asta ;
//e non
//bar asta() ;
//otherwise the compiler think `bar asta ()` as of function declaration with name `asta` and the return type `bar`.
//copy ctor
bar::bar (const bar& original)
{
mass_p = original.mass_p ;
lenght_p = original.lenght_p ;
baricentro_p = original.baricentro_p ;
perno_p = original.perno_p ;
velperno_p = original.velperno_p ;
theta_p = original.theta_p ;
veltheta_p = original.veltheta_p ;
estremo_p = original.estremo_p ;
velestremo_p = original.velestremo_p;
}
//ctor: solo parametri strutturali
bar::bar(double mass, double lenght, double baricentro):
mass_p (mass),
lenght_p (lenght),
baricentro_p(baricentro),
theta_p (0.), //theta_p (0.- (3.14159265358979323846264338327950288/2.))
veltheta_p (0.)
{
vect2d perno_p (0., 0.);
vect2d velperno_p (0., 0.);
SetPosEstremo ();
SetVelEstremo ();
}
//ctor: solo parametri cinetici
bar::bar(vect2d& perno, double theta, vect2d& velperno, double veltheta):
mass_p (1.) ,
lenght_p (1.),
baricentro_p (0.5),
theta_p (theta),
veltheta_p (veltheta)
{
perno_p = perno ;
velperno_p = velperno;
SetPosEstremo ();
SetVelEstremo ();
}
//ctor: completo, setta tutto
bar::bar(double mass, double lenght, double baricentro, vect2d& perno, double theta, vect2d& velperno, double veltheta):
mass_p (mass),
lenght_p (lenght),
baricentro_p(baricentro),
theta_p (theta),
veltheta_p (veltheta)
{
perno_p = perno ;
velperno_p = velperno;
SetPosEstremo ();
SetVelEstremo ();
}
//dtor
bar::~bar() {}
//OPERATORS
bar& bar::operator= (const bar& original)
{
mass_p = original.mass_p ;
lenght_p = original.lenght_p ;
baricentro_p = original.baricentro_p ;
perno_p = original.perno_p ;
velperno_p = original.velperno_p ;
theta_p = original.theta_p ;
veltheta_p = original.veltheta_p ;
SetPosEstremo ();
SetVelEstremo ();
return *this ;
}
//SETTINGS
void bar::SetPosPerno (vect2d& pos)
{
perno_p = pos ;
}
void bar::SetVelPerno (vect2d& vel)
{
velperno_p = vel ;
}
void bar::SetTheta (double& theta)
{
theta_p = theta;
}
void bar::SetVelTheta (double& vel)
{
veltheta_p = vel ;
}
void bar::SetPosEstremo ()
{
vect2d estremo (perno_p.GetX() + lenght_p * sin(theta_p), perno_p.GetY() - lenght_p * cos(theta_p));
estremo_p = estremo;
}
void bar::SetVelEstremo ()
{
vect2d velestremo (veltheta_p * lenght_p * sin(theta_p) , - veltheta_p * lenght_p * cos(theta_p) ) ;
velestremo_p = velestremo ;
}
//GETS
double bar::GetMass() const {
return mass_p;
}
double bar::GetLenght() const {
return lenght_p;
}
double bar::GetBaricentro() const {
return baricentro_p;
}
vect2d bar::GetPosPerno () const
{
return perno_p;
}
vect2d bar::GetVelPerno () const
{
return velperno_p;
}
double bar::GetTheta () const
{
return theta_p ;
}
double bar::GetVelTheta () const
{
return veltheta_p ;
}
vect2d bar::GetPosEstremo () const
{
return estremo_p ;
}
vect2d bar::GetVelEstremo () const
{
return velestremo_p ;
}
//Varie
void bar::Gravity (double deltaStep)
{
perno_p = velperno_p * deltaStep + perno_p ; //sposta il perno, moto rett uniforme
//velperno_p suppongo rimnga uguale
double Fperp = - mass_p * 9.806 * sin(theta_p) ; //calcolo la forza perpendicolare alla sbarra, quindi quella efficace, che ruota il pendolo.
double accTheta = Fperp / (mass_p * lenght_p * baricentro_p ) ; //calcolo l'accelerazione angolare
theta_p += accTheta * deltaStep * deltaStep /2. + veltheta_p * deltaStep ; //imposto il nuovo angolo
veltheta_p += accTheta * deltaStep ; //imposto la nuova velocità angolare
SetPosEstremo();
SetVelEstremo();
}
//fa agire la bar per un periodo di tempo delta t.
//deltaStep: lunghezza dell'intervallo di tempo che corrisponde a ciascuno step
/*poichè per calcolare la nuova posizione angolare faccio uso della velocità angolare
*all'inizio del deltastep (secondo le formule del moto circolaer uniformemente accelerato),
*aggiorno la velocità angolare (veltheta) dopo aver calcolato la nuova posizione angolare (theta)
*/
//la posizione angolare è calcolata tramite approssimazione quadratica
void bar::Gravity1 (double deltaStep)
{
perno_p = velperno_p * deltaStep + perno_p ; //sposta il perno, moto rett uniforme
//velperno_p suppongo rimnga uguale
double Fperp = - mass_p * 9.806 * sin(theta_p) ; //calcolo la forza perpendicolare alla sbarra, quindi quella efficace, che ruota il pendolo.
double accTheta = Fperp / (mass_p * lenght_p * baricentro_p ) ; //calcolo l'accelerazione angolare
theta_p += accTheta * deltaStep * deltaStep /2. + veltheta_p * deltaStep ; //imposto il nuovo angolo
veltheta_p += accTheta * deltaStep ; //imposto la nuova velocità angolare
SetPosEstremo();
SetVelEstremo();
}//la posizione angolare è fissata tramite approssimazione lineare.
void bar::GravFriction (double deltaStep, double k)
{
perno_p = velperno_p * deltaStep + perno_p ; //sposta il perno, moto rett uniforme
//velperno_p suppongo rimnga uguale
double Fperp = - mass_p * 9.806 * sin(theta_p) - k*veltheta_p ; //calcolo la forza perpendicolare alla sbarra, quindi quella efficace, che ruota il pendolo, tenendo conto degli effetti dell'attrito, modellizzato come "viscoso", -k*velocitàangolare
double accTheta = Fperp / (mass_p * lenght_p * baricentro_p ) ; //calcolo l'accelerazione angolare
theta_p += veltheta_p * deltaStep ; //imposto il nuovo angolo (lineare)
veltheta_p += accTheta * deltaStep ; //imposto la nuova velocità angolare
SetPosEstremo();
SetVelEstremo();
}//la posizione angolare è fissata tramite approssimazione lineare.
void bar::GravStabVert (double deltaStep, int i, double A, double w, double phi, vect2d perno )
{
//parametri
double arg = w*i*deltaStep + phi ;
//imposto la posizione del perno
vect2d traslazione (0., A*sin(arg));
perno_p = perno + traslazione ;
//calcolo 3l'accelerazione angolare
double accTheta = A*w*w*sin(arg)*sin(theta_p) - 9.806*sin(theta_p) ;
theta_p += veltheta_p * deltaStep ; //imposto il nuovo angolo
// theta_p += accTheta*deltaStep*deltaStep/2. + veltheta_p * deltaStep ; //imposto il nuovo angolo
veltheta_p += accTheta * deltaStep ; //imposto la nuova velocità angolare
//imposto la posizione dell'estremo
SetPosEstremo();
SetVelEstremo();
}//la posizione angolare è fissata tramite approssimazione lineare.
void bar::GravStabVert1 (double deltaStep, int i, double A, double w, double phi, vect2d perno )
{
//parametri
double arg = w*i*deltaStep + phi ;
//imposto la posizione del perno
vect2d traslazione (0., A*sin(arg));
perno_p = perno + traslazione ;
//calcolo 3l'accelerazione angolare
double accTheta = A*w*w*sin(arg)*sin(theta_p) - 9.806*sin(theta_p) ;
// theta_p += veltheta_p * deltaStep ; //imposto il nuovo angolo
theta_p += accTheta*deltaStep*deltaStep/2. + veltheta_p * deltaStep ; //imposto il nuovo angolo
veltheta_p += accTheta * deltaStep ; //imposto la nuova velocità angolare
//imposto la posizione dell'estremo
SetPosEstremo();
SetVelEstremo();
}//la posizione angolare è fissata tramite approssimazione lineare.
vect2d bar::Vincolo ()
{
vect2d vel_cm = velestremo_p * baricentro_p ; //CM significa baricentro
double mod_vel_cm = vel_cm.Mod() ;
double ModuloReazione = mass_p * ( 9.806 * cos(theta_p) + mod_vel_cm * mod_vel_cm / lenght_p ) ; //calcolo il modulo della tensione
double Reazione_x = -ModuloReazione * sin ( theta_p ) ;
double Reazione_y = ModuloReazione * cos ( theta_p ) ;
vect2d Reazione ( Reazione_x , Reazione_y ) ;
return Reazione ;
}
/*lo scopo di questo metodo è calcolare la reazione vincolare del perno necessaria per ruotare la barra.
* poichè modellizzo la barra con un punto materiale posizionato nel baricentro della barra stessa e massa pari all'intera massa della barra,
* vincolato al perno per mezzo di un'asta inestensibile con massa trascurabile (assimilabile perciò a un pendolo semplice.)
* la reazione vincolare esercitata dal perno è uguale alla tensione dell'asta stessa, calcolata con le tradizionali formule del pendolo semplice.
* il modulo della tensione dell'asta è perciò: T = m ( g * cos(theta) + v^2 / l )
* la direzione della tensione è parallela all'asta stessa con verso opposto a quello del vettore perno->baricentro
* (quindi dal baricentro verso il perno).
* perciò le sue componenti in funzione di teta sono opposte a quelle della barra: x=-sin(theta), y=cos(theta)
* a relazione scritta è istantanea.
*/
void bar::Print() const
{
std::cout << "massa: " << mass_p << std::endl << "lungh: " << lenght_p << std::endl
<< "baricentro: " << baricentro_p << std::endl
<<"posizione perno: (" << perno_p.GetX() << " ; " << perno_p.GetY() << ") \n"
<<"velocità perno: (" << velperno_p.GetX() << " ; " << velperno_p.GetY() << ") \n"
<<"theta: " << theta_p << std::endl << "velocità theta: " << veltheta_p << std::endl
<<"posizione estremo: (" << estremo_p.GetX() << " ; " << estremo_p.GetY() << ") \n"
<<"velocità estremo: (" << velestremo_p.GetX() << " ; " << velestremo_p.GetY() << ") \n" ;
}
std::ostream& operator<< (std::ostream& printer, const bar& other)
{
printer << "massa: " << other.GetMass() << std::endl << "lungh: " << other.GetLenght() << std::endl
<< "baricentro: " << other.GetBaricentro() << std::endl
<<"posizione perno: (" << other.GetPosPerno().GetX() << " ; " << other.GetPosPerno().GetY() << ") \n"
<<"velocità perno: (" << other.GetVelPerno().GetX() << " ; " << other.GetVelPerno().GetY() << ") \n"
<<"theta: " << other.GetTheta() << std::endl << "velocità theta: " << other.GetVelTheta() << std::endl
<<"posizione estremo: (" << other.GetPosEstremo().GetX() << " ; " << other.GetPosEstremo().GetY() << ") \n"
<<"velocità estremo: (" << other.GetVelEstremo().GetX() << " ; " << other.GetVelEstremo().GetY() << ") \n" ;
return printer;
}
//uso il metodo Get perchè gli attributi di other non sono raggiungibili direttamente dal main, mi serve un metodo interno alla classe (in quanto privati)
//per definire questa funzione, serve che tutti i metodi chiamati su other siano di tipo const in quanto ho richiesto che other fosse const. quindi devo aggiungere const nella posizione opportuna a tutti i metodi Get()