Текущая версия |
Ваш текст |
Строка 1: |
Строка 1: |
− | <div> | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
− | '''[[Абрамов Игорь]]''' | + | '''[[Лебедев Станислав]]''' |
| + | '''Описание программы''': программа записывает в четыре файла результаты вычисления: |
| + | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
| + | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| + | <br /> |
| + | Скачать можно [http://tm.spbstu.ru/Файл:Движение_тела.rar тут]. |
| + | <br /><br /> |
| | | |
− | '''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
| + | <div class="mw-collapsible-content"> |
| | | |
− | '''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display. | + | '''Описание программы''': программа записывает в четыре файла результаты вычисления: |
| + | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
| + | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| + | <br /><br /> |
| + | [[File:1.png]] |
| + | <br /><br /> |
| + | '''Визуализированный результат работы программы''' |
| + | [[File:graph.png]] |
| | | |
− | Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
| + | # o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
| + | # o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
| + | # o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| + | <br /> |
| + | Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2; |
| + | <br /> |
| + | ''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.'' |
| + | <syntaxhighlight lang="cpp" line start="1" enclose="div"> |
| + | #include <iostream> |
| + | #include <math.h> |
| + | #include "Vector.h" |
| + | #include <cstring> |
| + | #include <cmath> |
| + | #include <malloc.h> |
| + | #include <fstream> |
| | | |
− | </div> | + | #include <iostream> |
| + | #include <math.h> |
| + | #include "Vector.h" |
| + | #include <cstring> |
| + | #include <cmath> |
| + | #include <malloc.h> |
| + | #include <fstream> |
| | | |
| + | using namespace std; |
| | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| + | int n = 100; |
− | '''[[Андреева Полина]]'''
| + | ofstream outfile; |
| | | |
− | '''Краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл.
| + | class Ball //класс бросаемого тела |
| + | { |
| + | private: |
| + | double angle,m,k; //угол броска,масса,коэффицент сопротивления воздуха |
| + | Vector3D r,v,a; //радиус-вектор,вектор скорости,ускорения |
| + | public: |
| | | |
− | ''' Инструкция ''':
| + | //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха |
− | Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
| + | Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a) |
| + | { |
| + | angle = _angle; |
| + | r = _r; |
| + | v = _v; |
| + | a = _a; |
| + | } |
| | | |
− | Скачать можно [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут].
| + | //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха |
| + | Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a) |
| + | { |
| + | angle = _angle; |
| + | r = _r; |
| + | v = _v; |
| + | a = _a; |
| + | m = _m; |
| + | k = _k; |
| + | } |
| | | |
| + | //точная формула зависимости координаты от времени |
| + | Vector3D positionReal(double t) |
| + | { |
| + | double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t; |
| + | return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 ); |
| + | } |
| | | |
− | <div class="mw-collapsible-content"> | + | //вывод положения на экран |
| + | void writePosToScreen() |
| + | { |
| + | cout << r.x << " " << r.y << " " << r.z << endl; |
| + | } |
| | | |
| + | //вывод положения в файл |
| + | void writePosToFile(char s[]) |
| + | { |
| + | outfile.open(s,ios :: app); |
| + | outfile << r.x << " " << r.y << endl; |
| + | outfile.close(); |
| + | } |
| | | |
− | '''Визуализированный результат работы программы'''
| + | //вывод произвольного вектора на экран |
| + | void WVTS(Vector3D v) |
| + | { |
| + | cout.width(15); |
| + | cout << v.x; |
| + | cout.width(15); |
| + | cout << v.y; |
| + | cout.width(15); |
| + | cout << v.z << endl; |
| + | } |
| | | |
− | [[:File:graphAP.png]] | + | //вывод произвольного вектора в файл |
| + | void WVTF(Vector3D v,char s[]) |
| + | { |
| + | outfile.open(s,ios :: app); |
| + | outfile << v.x << " " << v.y << endl; |
| + | outfile.close(); |
| + | } |
| | | |
− | Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;
| + | //"пересчет" координаты по Верле(Линейная зависмость) |
| + | void changeR(Vector3D r1, double dt) |
| + | { |
| + | r = MakeVector(2 * r.x - r1.x - k/m*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*v.y)*dt*dt, 0 ); |
| + | } |
| | | |
− | # "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| + | //"пересчет" координаты по Верле(Квадратичная зависимость) |
− | # "MyFile.txt" using 3 : 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| + | void changeRSQ(Vector3D r1, double dt) |
− | # "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| + | { |
− | # "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
| + | r = MakeVector(2 * r.x - r1.x - k/m*Length(v)*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*Length(v)*v.y)*dt*dt, 0 ); |
| + | } |
| + | //пересчет скорости по Верле |
| + | void changeV(Vector3D r1,double dt) |
| + | { |
| + | v =VS((VmV(r,r1)),1/(2*dt)); |
| + | } |
| | | |
| + | //рассчет предыдущегт к 0ому элементу |
| + | Vector3D MR1(double dt) |
| + | { |
| + | return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0); |
| + | } |
| | | |
| + | //возращает координату тела |
| + | Vector3D getR() |
| + | { |
| + | return r; |
| + | } |
| | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| + | //рассчет времени полета |
− | #include <iostream>
| + | double TimeOfFly() |
− | #include <fstream>
| + | { |
− | #include "math.h"
| + | return (2*Length(v)*sin(angle)/Length(a)); |
− | #include <iomanip>
| + | } |
− | using namespace std;
| |
− | class func
| |
− | {
| |
| | | |
− | private:
| + | //рассчет координаты по точной формуле. без сопротивления воздуха. |
− | double speed0, angle0, step ;
| + | Vector3D position(double t) |
− | double time;
| + | { |
| + | return MakeVector(r.x + v.x*t + a.x*t*t/2,r.y + v.y*t + a.y*t*t/2,r.z + v.z*t + a.z*t*t/2); |
| + | } |
| | | |
− | public:
| + | }; |
− | double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
| |
− | double t, amount;
| |
− | int amountint;
| |
− | func ( double _speed0, double _angle0, double _step ):speed0(_speed0), angle0(_angle0), step(_step)
| |
− | {
| |
− | angle0=(3.14159*angle0) / 180 ; ///перевод угла в радианы
| |
| | | |
− | time = ( 2*speed0*sin(angle0) ) / g;///подсчет полного времени полета
| + | int main() |
− | amount = (time/step) + 1;///количество точек для траектории
| + | { |
− | amountint = static_cast<int> (amount) ;
| + | //задание начальных параметров |
| + | Vector3D g = {0,-9.8,0}; |
| + | double a,dt = 0; |
| + | char s[20]; |
| | | |
| + | // cin >> dt; |
| | | |
− | } | + | dt = 0.1; |
| + | a = (M_PI * 30)/180; |
| + | Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g); |
| | | |
| + | double tof = b1.TimeOfFly()+1; //единичка прибавлена,чтобы график красивым был |
| | | |
− | | + | //Без сопротивления возлуха |
− | void SaveFile(char filename[])
| + | strcpy(s,""); |
| + | strcat(s, "o1.txt"); |
| + | outfile.open(s, ios :: trunc); |
| + | outfile.close(); |
| + | for (double i = 0; i <= tof; i += dt) |
| { | | { |
− | double x0=0, y0=0; | + | b1.WVTS(b1.position(i)); |
− | double xv1=0, x1=0, y1=0, Vx1=speed0*cos(angle0),Vy1=speed0*sin(angle0), V1=speed0, yv1=0;
| + | b1.WVTF(b1.position(i), s); |
− | double xm1=x0-speed0*cos(angle0)*step, ym1=y0-speed0*sin(angle0)*step;
| + | } |
− | double xv2=0, x2=0, y2=0, Vx2=speed0*cos(angle0),Vy2=speed0*sin(angle0), V2=speed0, yv2=0;
| |
− | double xm2=x0-speed0*cos(angle0)*step, ym2=y0-speed0*sin(angle0)*step;
| |
− | double x3,y3;
| |
− | std::ofstream fout(filename);
| |
− | for (int i=0; (y0+(speed0*sin(angle0)*i*step - (g*i*i*step*step*0.5)))>=0; i++) | |
− | {
| |
− | ///Верле линейная зависимость
| |
− | x2=2*xv2-xm2-(n/m)*step*step*Vx2;
| |
− | y2=2*yv2-ym2-(g+(n/m)*Vy2)*step*step;
| |
− | Vx2=(x2-xm2) / (2.0*step);
| |
− | Vy2=(y2-ym2) / (2.0*step);
| |
− | xm2=xv2;
| |
− | xv2=x2;
| |
− | ym2=yv2;
| |
− | yv2=y2;
| |
| | | |
− | ///точное решение
| |
− | x3=x0+speed0*cos(angle0)*(m/n)*(1.0-exp(-(n/m)*i*step));
| |
− | y3=y0+(m/n)*(speed0*sin(angle0) + g*(m/n))*(1.0-exp(-(n/m)*i*step))-g*(m/n)*i*step;
| |
| | | |
− | ///метод Верле, квадратичная зависимость
| + | //Верле(Линейная зависимость) |
− | x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
| + | dt = 0.1; |
− | y1=2*yv1-ym1-(g+(n/m)*V1*Vy1)*step*step;
| + | a = (M_PI * 30)/180; |
− | Vx1=(x1-xm1) / (2.0*step);
| + | Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g); |
− | Vy1=(y1-ym1) / (2.0*step);
| |
− | V1=sqrt(Vx1*Vx1+Vy1*Vy1);
| |
− | xm1=xv1;
| |
− | xv1=x1;///запоминание предыдущего шага
| |
− | ym1=yv1;
| |
− | yv1=y1;
| |
| | | |
| + | strcpy(s,""); |
| + | strcat(s, "o2.txt"); |
| + | outfile.open(s,ios :: trunc); |
| + | outfile.close(); |
| + | Vector3D r1 = b2.MR1(dt),rp; |
| + | for (double i = 0; i <= 20; i += dt) |
| + | { |
| + | rp = b2.getR(); |
| + | b2.writePosToFile(s); |
| + | b2.writePosToScreen(); |
| + | b2.changeR(r1,dt); |
| + | b2.changeV(r1,dt); |
| + | r1.x = rp.x; |
| + | r1.y = rp.y; |
| + | } |
| | | |
| + | //Точное решение (Линейная зависимость) |
| + | dt = 0.1; |
| + | a = (M_PI * 30)/180; |
| + | Ball b3(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g); |
| | | |
− | fout<< setw(20) << (x0+(speed0*cos(angle0)*step*i)) << setw(20) << (y0+(speed0*sin(angle0)*i*step - (g*i*i*step*step*0.5)))<<setw(20) << x1 << setw(20) << y1 <<setw(20) << x2 << setw(20)<<y2<<setw(20) << x3 << setw(20) << y3<<" \n";
| + | strcpy(s,""); |
− | | + | strcat(s, "o3.txt"); |
− | } | + | outfile.open(s, ios :: trunc); |
− | fout.close();
| + | outfile.close(); |
| + | for (double i = 0; i <= 20; i += dt) |
| + | { |
| + | b3.WVTS(b3.positionReal(i)); |
| + | b3.WVTF(b3.positionReal(i), s); |
| } | | } |
| | | |
− | };
| |
| | | |
| + | //Верле (Квадратичная зависимость) |
| + | dt = 0.1; |
| + | a = (M_PI * 30)/180; |
| + | Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g); |
| | | |
− | int main()
| + | strcpy(s,""); |
− | {
| + | strcat(s, "o4.txt"); |
− | double V0, angle, step; | + | outfile.open(s, ios :: trunc); |
− | cout << " enter V0 = ";///введите начальную скорость | + | outfile.close(); |
− | cin >> V0; | + | r1 = b4.MR1(dt); |
− | cout << " enter an angle , 0 < angle <= 90, angle = " ;///введите угол в диапозоне от 0 до 90 градусов | + | for (double i = 0; i <= 20; i += dt) |
− | cin >> angle; | + | { |
− | cout << "\n enter step ";///введите шаг, с которым будут рассчитываться координаты
| + | rp = b4.getR(); |
− | cin >> step; cout << endl;
| + | b4.writePosToFile(s); |
− | func f1(V0,angle,step);///создание траектории
| + | b4.writePosToScreen(); |
− | f1.SaveFile("Myfile.txt");///запись в файл
| + | b4.changeRSQ(r1,dt); |
− | | + | b4.changeV(r1,dt); |
| + | r1.x = rp.x; |
| + | r1.y = rp.y; |
| + | } |
| | | |
| return 0; | | return 0; |
| } | | } |
| + | |
| </syntaxhighlight> | | </syntaxhighlight> |
− | </div>
| |
− |
| |
− | <div>
| |
− |
| |
− | '''[[Бальцер Анастасия]]'''
| |
− |
| |
− | '''Описание программы''' : программа записывает в четыре файла результаты вычисления:
| |
− |
| |
− | Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− |
| |
− | Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
| |
− |
| |
| </div> | | </div> |
| | | |
| <div class="mw-collapsible mw-collapsed" style="width:100%" > | | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
| '''[[Белоусова Екатерина]]''' | | '''[[Белоусова Екатерина]]''' |
− | | + | <br /> |
| '''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки. | | '''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки. |
− | | + | <br /> |
| Программа записывает в один файл результаты вычисления: | | Программа записывает в один файл результаты вычисления: |
| # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
Строка 158: |
Строка 264: |
| # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. | | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; | | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; |
− | | + | <br /> |
| Скачать можно [http://tm.spbstu.ru/Файл:задача_3.zip тут]. | | Скачать можно [http://tm.spbstu.ru/Файл:задача_3.zip тут]. |
| + | <br /><br /> |
| | | |
| <div class="mw-collapsible-content"> | | <div class="mw-collapsible-content"> |
| | | |
| [[File:формулы.png]] | | [[File:формулы.png]] |
− | | + | <br /><br /> |
| '''Визуализированный результат работы программы''' | | '''Визуализированный результат работы программы''' |
| [[File:graph1.png]] | | [[File:graph1.png]] |
| | | |
| Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01; | | Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01; |
− | | + | <br /> |
| # "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
| # "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; | | # "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
| # "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости; | | # "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости; |
| # "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости. | | # "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости. |
− | | + | <br /> |
| | | |
| <syntaxhighlight lang="cpp" line start="1" enclose="div"> | | <syntaxhighlight lang="cpp" line start="1" enclose="div"> |
Строка 203: |
Строка 310: |
| Brad=3.14159*Agrad/180.0; ///переводим значение угла из градусов в радианы | | Brad=3.14159*Agrad/180.0; ///переводим значение угла из градусов в радианы |
| | | |
− | time=2*Vo*sin(Brad)/g; ///рассчитываем время полета тела | + | time=2*Vo*sin(Brad)/g; ///расчитываем время полета тела |
| amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом | | amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом |
| amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int | | amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int |
Строка 297: |
Строка 404: |
| | | |
| } | | } |
| + | |
| + | |
| </syntaxhighlight> | | </syntaxhighlight> |
| </div> | | </div> |
| + | |
| | | |
| <div class="mw-collapsible mw-collapsed" style="width:100%" > | | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
| '''[[Васильева Анастасия]]''' | | '''[[Васильева Анастасия]]''' |
− | | + | <br /> |
− | '''Описание программы''': пользователь вводит начальную скорость полета, угол падения и шаг, с которым будут рассчитаны точки. | + | '''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки. |
− | | + | <br /> |
| Программа записывает в один файл результаты вычисления: | | Программа записывает в один файл результаты вычисления: |
| # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
Строка 310: |
Строка 420: |
| # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. | | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; | | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
− | | + | <br /> |
| Скачать можно [http://tm.spbstu.ru/Файл:fly.zip тут]. | | Скачать можно [http://tm.spbstu.ru/Файл:fly.zip тут]. |
− | | + | <br /><br /> |
| | | |
| <div class="mw-collapsible-content"> | | <div class="mw-collapsible-content"> |
| | | |
− | | + | <br /><br /> |
| '''Визуализированный результат работы программы''' | | '''Визуализированный результат работы программы''' |
| [[File:graphick.png]] | | [[File:graphick.png]] |
| | | |
| Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001; | | Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001; |
− | | + | <br /> |
| # "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
| # "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера); | | # "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера); |
| # "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости; | | # "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости; |
| # "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости. | | # "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости. |
− | | + | <br /> |
| | | |
| <syntaxhighlight lang="cpp" line start="1" enclose="div"> | | <syntaxhighlight lang="cpp" line start="1" enclose="div"> |
Строка 474: |
Строка 584: |
| F1.FilePrint(); ///вызываем функцию для записи файла | | F1.FilePrint(); ///вызываем функцию для записи файла |
| } | | } |
| + | |
| + | |
| </syntaxhighlight> | | </syntaxhighlight> |
| </div> | | </div> |
| | | |
− | '''[[Гильманов Илья]]'''
| |
| | | |
− | '''Описание программы''': программа состоит из четырех независимых друг от друга частей:
| |
− | # Полет тела без сопротивления воздуха;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
− | # Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
| | | |
− | Скачать можно [[http://mech.spbstu.ru/File:Движение_тела_в_среде.rar тут]]
| + | '''[[Андреева Полина]]''' |
| | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| + | '''краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл. |
− | '''[[Демченко Артём]]''' | |
| | | |
− | '''Описание программы''': программа записывает в четыре файла результаты вычисления: | + | ''' инструкция ''': |
− | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| + | Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости. |
− | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
| | | |
− | ''' Инструкция ''':
| + | Скачать можно [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут]. |
− | Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
| |
− | | |
− | | |
− | <div class="mw-collapsible-content">
| |
− | | |
− | | |
− | | |
− | '''Визуализированный результат работы программы'''
| |
− | | |
− | [[:File:Throws.png]] | |
− | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | | |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include <iomanip>
| |
− | #include <fstream>
| |
− | #include <conio.h>
| |
− | #include <stdio.h>
| |
− | | |
− | | |
− | using namespace std;
| |
− | | |
− | double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
| |
− | | |
− | int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
| |
− | {
| |
− | FILE *Coord;
| |
− | Coord = fopen ("Throws Without Resistance.txt", "w");
| |
− | double X = 0, Y = 0; // Координаты начала
| |
− | | |
− | while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
| |
− | {
| |
− | | |
− | X = Vo*t*cos(alpha);
| |
− | Y = Vo*t*sin(alpha) - (g*t*t)*0.5;
| |
− | t+= dt;
| |
− | if (Y > Yo )
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
| |
− | else
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
| |
− | }
| |
− | | |
− | }
| |
− | | |
− | int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
| |
− | { // для линейной зависимости
| |
− | FILE *Coord;
| |
− | Coord = fopen ("ExactForm.txt", "w");
| |
− | double X, Y = 0, Vx, Vy;
| |
− | | |
− | while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
| |
− | {
| |
− | | |
− | X = ((m*Vx)/R) * (1 - exp(((-1)*R*t)/m));
| |
− | Y = (m/R)*((Vy + (g*m)/R)*(1 - exp((-1)*R*t/m))) - (g*t*m)/R;
| |
− | Vx = Vo*cos(alpha);
| |
− | Vy = Vo*sin(alpha);
| |
− | t+= dt;
| |
− | if (Y > Yo )
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
| |
− | else
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
| |
− | }
| |
− | }
| |
− | | |
− | int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
| |
− | { // для Квадратичной зависимости сопротивления от скорости
| |
− | FILE *Coord;
| |
− | Coord = fopen ("VerleSq.txt", "w");
| |
− | | |
− | double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
| |
− | // Xop, Yop - вспомогательные координаты для (-1)-го шага
| |
− | | |
− | Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
| |
− | Xop = Xo - Vo*cos(alpha)*dt;
| |
− | X = Xo;
| |
− | Y = Yo;
| |
− | Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
| |
− | Vx = (1.0/(2.0*dt))*(Xnext - Xop);
| |
− | Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
| |
− | Vy = (1.0/(2.0*dt))*(Ynext - Yop);
| |
− | V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
| |
− | | |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, Y); // Записываем первую координату в файл
| |
− | | |
− | Xprev = X; // Меняем координаты местами. Так (n-1)-ый шаг становится n-ым шагом, n-ый шаг становится (n+1)-ым шагом. Далее аналогично
| |
− | X = Xnext;
| |
− | Yprev = Y;
| |
− | Y = Ynext;
| |
− | | |
− | | |
− | while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
| |
− | {
| |
− | Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
| |
− | Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
| |
− | Ynext = 2.0*Y - Yprev - (g +(R/m)*V*Vy)*(dt*dt);
| |
− | Vy = (1.0/(2.0*dt))*(Ynext - Yprev);
| |
− | V = sqrt((Vx*cos(alpha)*Vx*cos(alpha)) + (Vy*sin(alpha) - g*dt)*(Vy*sin(alpha) - g*dt));
| |
− | if (Ynext > Yo )
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
| |
− | else
| |
− | | |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
| |
− | | |
− | Xprev = X;
| |
− | X = Xnext;
| |
− | Yprev = Y;
| |
− | Y = Ynext;
| |
− | }
| |
− | | |
− | }
| |
− | int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
| |
− | { // для линейной зависимости сопротивления от скорости
| |
− | FILE *Coord;
| |
− | Coord = fopen ("VerleL.txt", "w");
| |
− | | |
− | double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,Yop, Xop; // Комментарии аналогичны переменным и формулам в VtrleSq
| |
− | | |
− | Yop = Yo - Vo*sin(alpha)*dt;
| |
− | Xop = Xo - Vo*cos(alpha)*dt;
| |
− | X = Xo;
| |
− | Y = Yo;
| |
− | Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
| |
− | Vx = (1.0/(2.0*dt))*(Xnext - Xop);
| |
− | Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
| |
− | Vy = (1.0/(2.0*dt))*(Ynext - Yop);
| |
− | V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
| |
− | | |
− | fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
| |
− | | |
− | Xprev = X;
| |
− | X = Xnext;
| |
− | Yprev = Y;
| |
− | Y = Ynext;
| |
− | | |
− | | |
− | while (Y >= Yo)
| |
− | {
| |
− | Xnext = 2.0*X - Xprev - (R/m)*Vx*(dt*dt);
| |
− | Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
| |
− | Ynext = 2.0*Y - Yprev - (g +(R/m)*Vy)*(dt*dt);
| |
− | Vy = (1.0/(2.0*dt))*(Ynext - Yprev);
| |
− | if (Ynext > Yo )
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
| |
− | else
| |
− | fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, 0.000);
| |
− | | |
− | Xprev = X;
| |
− | X = Xnext;
| |
− | Yprev = Y;
| |
− | Y = Ynext;
| |
− | }
| |
− | | |
− | }
| |
− | | |
− | int main()
| |
− | {
| |
− | double alpha, Vo, dt, R, m , t = 0, Yo = 0, Xo = 0; // Объявляем переменные: alpha - угол броска; Vo - начальная скорость; dt - шаг по времени; R- коэф. сопротивления; m- масса тела;
| |
− | // t = 0 - начало отсчета времени с 0; Yo = 0, Xo = 0 - координаты начала
| |
− | int i = 0; // переменная для оператора switch
| |
− | | |
− | cout << "Enter start speed:\n";
| |
− | cin >> Vo; // Вводим с клавиатуры начальную скорость
| |
− | cout << "Enter angle in grades ( from 0 to 180 ):\n";
| |
− | cin >> alpha; // Вводим с клавиатуры угол броска в градусах
| |
− | alpha = alpha*Pi / 180; // переводим угол броска из градусов в радианы
| |
− | cout << "Enter mass:\n";
| |
− | cin >> m; // Вводим с клавиатуры массу
| |
− | cout << "Enter precision:\n";
| |
− | cin >> dt; // Вводим с клавиатуры шаг по времени
| |
− | cout << "Enter resistance:\n";
| |
− | cin >> R; // Вводим сопротивление воздуха
| |
− | cout << "Press 1 to draw graph without resistance\n\n"
| |
− | "Press 2 to draw graph in Exact form\n\n"
| |
− | "Press 3 to draw graph in VerleSq form\n\n"
| |
− | "Press 4 to draw graph in VerleL form\n\n"
| |
− | "Press 5 to draw all graphs at the same time\n\n"
| |
− | "Press 0 to quit\n\n";
| |
− | cin >> i;
| |
− | cout << "\nPress any button\n";
| |
− | | |
− | | |
− | FILE *Gnu;
| |
− | Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
| |
− | | |
− | switch ( i )
| |
− | {
| |
− | case 1:
| |
− | {
| |
− | WoutR(alpha,dt,t,Yo,Vo);
| |
− | fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
| |
− | break;
| |
− | }
| |
− | case 2:
| |
− | {
| |
− | ExactForm(alpha,dt,t,Yo,Vo,R,m);
| |
− | fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
| |
− | break;
| |
− | }
| |
− | case 3:
| |
− | {
| |
− | VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
| |
− | fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
| |
− | break;
| |
− | }
| |
− | case 4:
| |
− | {
| |
− | VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
| |
− | fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
| |
− | break;
| |
− | }
| |
− | case 5:
| |
− | {
| |
− | WoutR(alpha,dt,t,Yo,Vo);
| |
− | ExactForm(alpha,dt,t,Yo,Vo,R,m);
| |
− | VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
| |
− | VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
| |
− | fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l, \"ExactForm.txt\" using 1:2 w l, \"VerleSq.txt\" using 1:2 w l, \"VerleL.txt\" using 1:2 w l"); // записываем в Throws.gp названия четырех файлов
| |
− | break;
| |
− | } // с координатами таким образом, чтобы программа gnuplot смогла их увидеть и прочесть
| |
− | case 0:
| |
− | break;
| |
− | default:
| |
− | break;
| |
− | }
| |
− | return 0;
| |
− | }
| |
− | | |
− | </syntaxhighlight>
| |
− | </div>
| |
| | | |
| | | |
| '''[[Иванова Яна]]''' | | '''[[Иванова Яна]]''' |
− | | + | <br /> |
| '''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде. | | '''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде. |
| Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды. | | Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды. |
− | | + | <br /> |
| Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь] | | Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь] |
| + | <br /> |
| | | |
− | <div class="mw-collapsible-content"> | + | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
| '''Визуализированный результат работы программы'''[[File:graph.png]] | | '''Визуализированный результат работы программы'''[[File:graph.png]] |
− | | + | <br /> |
| [[:File:graph.png]] | | [[:File:graph.png]] |
− | | + | <br /> |
| <syntaxhighlight lang="cpp" line start="1" enclose="div"> | | <syntaxhighlight lang="cpp" line start="1" enclose="div"> |
| #include <iostream> | | #include <iostream> |
Строка 865: |
Строка 737: |
| </syntaxhighlight> | | </syntaxhighlight> |
| </div> | | </div> |
| + | <br /><br /> |
| | | |
− | <div>
| |
| | | |
− | '''[[Капитанюк Светлана]]''' | + | '''[[Уманский Александр]]''' |
− | | |
− | '''Описание программы''' : программа записывает в четыре файла результаты вычисления:
| |
− | | |
− | Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− | | |
− | Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
| |
− | | |
− | </div>
| |
− | | |
− | <div>
| |
− | '''[[Киселёв Лев]]'''
| |
− | | |
− | '''Описание программы''': программа рассчитывает координаты точки при следующих случаях
| |
− | # Полет тела без сопротивления воздуха;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
− | # Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
− | | |
− | Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
| |
− | </div>
| |
| | | |
| <div class="mw-collapsible mw-collapsed" style="width:100%" > | | <div class="mw-collapsible mw-collapsed" style="width:100%" > |
− | '''[[Лебедев Станислав]]'''
| + | <br /> |
− | | |
| '''Описание программы''': программа записывает в четыре файла результаты вычисления: | | '''Описание программы''': программа записывает в четыре файла результаты вычисления: |
| # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
Строка 902: |
Строка 750: |
| # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. | | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| | | |
− | Скачать можно [http://tm.spbstu.ru/Файл:Шарик.rar тут].
| + | <br /> |
| | | |
− | <div class="mw-collapsible-content"> | + | [[File:Methods.rar|Скачать архив]] |
| + | <br /><br /> |
| | | |
| [[File:1.png]] | | [[File:1.png]] |
| | | |
| | | |
− | '''Визуализированный результат работы программы'''
| |
− | [[File:graph.png]]
| |
− |
| |
− | # o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | # o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− |
| |
− |
| |
− | Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
| |
− |
| |
− | ''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
| |
− |
| |
− | Файл "'''main.cpp'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include "Vector.h"
| |
− | #include <cstring>
| |
− | #include <cmath>
| |
− | #include <malloc.h>
| |
− | #include <fstream>
| |
− |
| |
− | using namespace std;
| |
− |
| |
− | int n = 100;
| |
− | ofstream outfile;
| |
− |
| |
− | class Ball //класс бросаемого тела
| |
− | {
| |
− | private:
| |
− | double angle,m,k; //угол броска,масса,коэффицент сопротивления воздуха
| |
− | Vector3D r,v,a; //радиус-вектор,вектор скорости,ускорения
| |
− | public:
| |
− |
| |
− | //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
| |
− | Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
| |
− | {
| |
− | angle = _angle;
| |
− | r = _r;
| |
− | v = _v;
| |
− | a = _a;
| |
− | }
| |
− |
| |
− | //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
| |
− | Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
| |
− | {
| |
− | angle = _angle;
| |
− | r = _r;
| |
− | v = _v;
| |
− | a = _a;
| |
− | m = _m;
| |
− | k = _k;
| |
− | }
| |
− |
| |
− | //точная формула зависимости координаты от времени
| |
− | Vector3D positionReal(double t)
| |
− | {
| |
− | double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
| |
− | return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
| |
− | }
| |
− |
| |
− | //вывод положения на экран
| |
− | void writePosToScreen()
| |
− | {
| |
− | cout << r.x << " " << r.y << " " << r.z << endl;
| |
− | }
| |
| | | |
− | //вывод положения в файл
| |
− | void writePosToFile(char s[])
| |
− | {
| |
− | outfile.open(s,ios :: app);
| |
− | outfile << r.x << " " << r.y << endl;
| |
− | outfile.close();
| |
− | }
| |
− |
| |
− | //вывод произвольного вектора на экран
| |
− | void WVTS(Vector3D v)
| |
− | {
| |
− | cout.width(15);
| |
− | cout << v.x;
| |
− | cout.width(15);
| |
− | cout << v.y;
| |
− | cout.width(15);
| |
− | cout << v.z << endl;
| |
− | }
| |
− |
| |
− | //вывод произвольного вектора в файл
| |
− | void WVTF(Vector3D v,char s[])
| |
− | {
| |
− | outfile.open(s,ios :: app);
| |
− | outfile << v.x << " " << v.y << endl;
| |
− | outfile.close();
| |
− | }
| |
− |
| |
− | //"пересчет" координаты по Верле(Линейная зависмость)
| |
− | void changeR(Vector3D r1, double dt)
| |
− | {
| |
− | r = MakeVector(2 * r.x - r1.x - k/m*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*v.y)*dt*dt, 0 );
| |
− | }
| |
− |
| |
− | //"пересчет" координаты по Верле(Квадратичная зависимость)
| |
− | void changeRSQ(Vector3D r1, double dt)
| |
− | {
| |
− | r = MakeVector(2 * r.x - r1.x - k/m*Length(v)*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*Length(v)*v.y)*dt*dt, 0 );
| |
− | }
| |
− | //пересчет скорости по Верле
| |
− | void changeV(Vector3D r1,double dt)
| |
− | {
| |
− | v =VS((VmV(r,r1)),1/(2*dt));
| |
− | }
| |
− |
| |
− | //рассчет предыдущегт к 0ому элементу
| |
− | Vector3D MR1(double dt)
| |
− | {
| |
− | return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
| |
− | }
| |
− |
| |
− | //возращает координату тела
| |
− | Vector3D getR()
| |
− | {
| |
− | return r;
| |
− | }
| |
− |
| |
− | //рассчет времени полета
| |
− | double TimeOfFly()
| |
− | {
| |
− | return (2*Length(v)*sin(angle)/Length(a));
| |
− | }
| |
− |
| |
− | //рассчет координаты по точной формуле. без сопротивления воздуха.
| |
− | Vector3D position(double t)
| |
− | {
| |
− | return MakeVector(r.x + v.x*t + a.x*t*t/2,r.y + v.y*t + a.y*t*t/2,r.z + v.z*t + a.z*t*t/2);
| |
− | }
| |
− |
| |
− | };
| |
− |
| |
− | int main()
| |
− | {
| |
− | //задание начальных параметров
| |
− | Vector3D g = {0,-9.8,0};
| |
− | double a,dt = 0;
| |
− | char s[20];
| |
− |
| |
− | // cin >> dt;
| |
− |
| |
− | dt = 0.1;
| |
− | a = (M_PI * 30)/180;
| |
− | Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
| |
− |
| |
− | double tof = b1.TimeOfFly()+1; //единичка прибавлена,чтобы график красивым был
| |
− |
| |
− | //Без сопротивления возлуха
| |
− | strcpy(s,"");
| |
− | strcat(s, "o1.txt");
| |
− | outfile.open(s, ios :: trunc);
| |
− | outfile.close();
| |
− | for (double i = 0; i <= tof; i += dt)
| |
− | {
| |
− | b1.WVTS(b1.position(i));
| |
− | b1.WVTF(b1.position(i), s);
| |
− | }
| |
− |
| |
− |
| |
− | //Верле(Линейная зависимость)
| |
− | dt = 0.1;
| |
− | a = (M_PI * 30)/180;
| |
− | Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
| |
− |
| |
− | strcpy(s,"");
| |
− | strcat(s, "o2.txt");
| |
− | outfile.open(s,ios :: trunc);
| |
− | outfile.close();
| |
− | Vector3D r1 = b2.MR1(dt),rp;
| |
− | for (double i = 0; i <= 20; i += dt)
| |
− | {
| |
− | rp = b2.getR();
| |
− | b2.writePosToFile(s);
| |
− | b2.writePosToScreen();
| |
− | b2.changeR(r1,dt);
| |
− | b2.changeV(r1,dt);
| |
− | r1.x = rp.x;
| |
− | r1.y = rp.y;
| |
− | }
| |
− |
| |
− | //Точное решение (Линейная зависимость)
| |
− | dt = 0.1;
| |
− | a = (M_PI * 30)/180;
| |
− | Ball b3(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
| |
− |
| |
− | strcpy(s,"");
| |
− | strcat(s, "o3.txt");
| |
− | outfile.open(s, ios :: trunc);
| |
− | outfile.close();
| |
− | for (double i = 0; i <= 20; i += dt)
| |
− | {
| |
− | b3.WVTS(b3.positionReal(i));
| |
− | b3.WVTF(b3.positionReal(i), s);
| |
− | }
| |
− |
| |
− |
| |
− | //Верле (Квадратичная зависимость)
| |
− | dt = 0.1;
| |
− | a = (M_PI * 30)/180;
| |
− | Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
| |
− |
| |
− | strcpy(s,"");
| |
− | strcat(s, "o4.txt");
| |
− | outfile.open(s, ios :: trunc);
| |
− | outfile.close();
| |
− | r1 = b4.MR1(dt);
| |
− | for (double i = 0; i <= 20; i += dt)
| |
− | {
| |
− | rp = b4.getR();
| |
− | b4.writePosToFile(s);
| |
− | b4.writePosToScreen();
| |
− | b4.changeRSQ(r1,dt);
| |
− | b4.changeV(r1,dt);
| |
− | r1.x = rp.x;
| |
− | r1.y = rp.y;
| |
− | }
| |
− |
| |
− | return 0;
| |
− | }
| |
− | </syntaxhighlight>
| |
− |
| |
− | Файл "'''Vector.h'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | #ifndef VECTOR_H_INCLUDED
| |
− | #define VECTOR_H_INCLUDED
| |
− |
| |
− | struct Vector3D
| |
− | {
| |
− | double x,y,z;
| |
− | };
| |
− |
| |
− | Vector3D VmV(Vector3D v1,Vector3D v2) //векторное вычитание
| |
− | {
| |
− | Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
| |
− | return v;
| |
− | };
| |
− | Vector3D VpV(Vector3D v1,Vector3D v2) //векторное сложение
| |
− | {
| |
− | Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
| |
− | return v;
| |
− | }
| |
− |
| |
− | double VV(Vector3D v1,Vector3D v2) //скалярное умножение
| |
− | {
| |
− | return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
| |
− | }
| |
− |
| |
− | Vector3D VxV(Vector3D v1,Vector3D v2) //векторное умножение
| |
− | {
| |
− | Vector3D v = {v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z,v1.x*v2.y - v1.y*v2.x};
| |
− | return v;
| |
− | }
| |
− |
| |
− | bool Kol(Vector3D v1,Vector3D v2)
| |
− | {
| |
− | return ((v1.x/v2.x == v1.y/v2.y)&&(v1.z/v2.z == v1.y/v2.y))? true:false;
| |
− | }
| |
− |
| |
− | Vector3D VS(Vector3D v1, double s)
| |
− | {
| |
− | Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
| |
− | return v;
| |
− | }
| |
− |
| |
− | double Length(Vector3D v1)
| |
− | {
| |
− | return sqrt(VV(v1,v1));
| |
− | }
| |
− |
| |
− | Vector3D MakeVector(double x,double y,double z)
| |
− | {
| |
− | Vector3D v = {x,y,z};
| |
− | return v;
| |
− | }
| |
− |
| |
− | Vector3D MakeVector(double length,double angle)
| |
− | {
| |
− | Vector3D v = {length * cos(angle), length * sin(angle),0};
| |
− | return v;
| |
− | }
| |
− |
| |
− | double Proection(Vector3D base, Vector3D dir)
| |
− | {
| |
− | return (VV(base,dir)/Length(base));
| |
− | }
| |
− | #endif // VECTOR_H_INCLUDED
| |
− | </syntaxhighlight>
| |
− | </div>
| |
− |
| |
− |
| |
− | <div>
| |
− | '''[[Лобанов Илья]]'''
| |
− |
| |
− | '''Описание программы''' : программа записывает в четыре файла результаты вычисления:
| |
− |
| |
− | Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− |
| |
− |
| |
− | '''Краткая инструкция''':
| |
− |
| |
− | В окне консоли пользователю предлагается вывести следующие значения: начальную скорость , угол и шаг.
| |
− | После этого полученные в результате работы программы данные выводятся в файл.
| |
− |
| |
− | Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
| |
− | [[http://tm.spbstu.ru/File:phys.rar тут]]
| |
− |
| |
− | </div>
| |
− |
| |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
| '''[[Лосева Татьяна ]]''' | | '''[[Лосева Татьяна ]]''' |
− |
| |
| '''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений: | | '''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений: |
| # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; | | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; |
Строка 1234: |
Строка 765: |
| # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. | | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости. |
| # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; | | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; |
− |
| |
− | <div class="mw-collapsible-content">
| |
| | | |
| ''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;'' | | ''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;'' |
Строка 1399: |
Строка 928: |
| </div> | | </div> |
| | | |
− | Скачать можно [http://tm.spbstu.ru/Файл:Verle.rar тут].
| |
| | | |
− | <div>
| |
| | | |
− | '''[[Ляжков Сергей]]'''
| |
| | | |
− | '''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
| + | Скачать можно [http://tm.spbstu.ru/Файл:Verle.rar тут]. |
− | Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
| |
− | Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
| |
− | Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
| |
− | </div>
| |
− | | |
− | <br>'''[[Нарядчиков Александр]]'''<br>
| |
− | '''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
| |
− | '''Описание программы:''' В комнате скачут 4 мячика, первый двигается без сопротивления воздуха, второй двигается с квадратичной зависимостью сопротивления воздуха от скорости (Метод Верле), третий двигается с линейной зависимостью сопротивления воздуха от скорости (точное решение), четвертый двигается с линейной зависимостью сопротивления воздуха от скорости (Метод Верле).<br>
| |
− | '''Описание алгоритма:''' Программа реализована с помощью системы анимации(class anim), используя библиотеки OpenGl и GLUT. Изменения координат мячей проходят в режиме реального времени в векторной форме.<br>
| |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | "'''T06BALL.CPP'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | /* FILENAME: T06BALL.CPP
| |
− | * LAST UPDATE: 17.01.2016
| |
− | */
| |
− | | |
− | #include "ANIM.H"
| |
− | #include "SAMPLE.H"
| |
− | | |
− | /* Main function */
| |
− | void main( void )
| |
− | {
| |
− | // Получение единственного экземпляра класса анимации
| |
− | sagl::anim &My = sagl::anim::Get();
| |
− |
| |
− | // Шар, летящий без сопротивлением воздуха
| |
− | for (int i = 0; i < 1; i++)
| |
− | My << new ball(Pi / 6, 10 + i);
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
| |
− | for (int i = 0; i < 1; i++)
| |
− | My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | for (int i = 0; i < 1; i++)
| |
− | My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | for (int i = 0; i < 1; i++)
| |
− | My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
| |
− | | |
− | // Запуск главного цикла
| |
− | My.Run();
| |
− | } // End of 'main' function
| |
− | | |
− | // END OF 'T43ANIM.CPP' FILE
| |
− | </syntaxhighlight>
| |
− | "'''ANIM.CPP'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | /* FILENAME: ANIM.CPP
| |
− | * LAST UPDATE: 17.01.2016
| |
− | */
| |
− | | |
− | #include <stdio.h>
| |
− | #include <stdlib.h>
| |
− | #include <time.h>
| |
− | | |
− | #include "ANIM.H"
| |
− | | |
− | // Единственный экземпляр класса
| |
− | sagl::anim sagl::anim::Instance;
| |
− | | |
− | /* Reshape function */
| |
− | // Стандартная функция, вызываемая при изменении размеров окна
| |
− | void sagl::anim::Reshape( int W, int H )
| |
− | {
| |
− | // Установка области просмотра - все окно
| |
− | glViewport(0, 0, W, H);
| |
− | Instance.WinW = W;
| |
− | Instance.WinH = H;
| |
− | double ratio_x = 1, ratio_y = 1;
| |
− | if (W > H)
| |
− | ratio_x = (double)W / H;
| |
− | else
| |
− | ratio_y = (double)H / W;
| |
− | double Size = 1, Near = 1, Far = 500;
| |
− | // Установка системы координат "камеры"
| |
− | glMatrixMode(GL_PROJECTION);
| |
− | glLoadIdentity();
| |
− | glFrustum(-Size * ratio_x, Size * ratio_x,
| |
− | -Size * ratio_y, Size * ratio_y,
| |
− | Near, Far);
| |
− | // Установка "мировой" СК в состояние без преобразований
| |
− | glMatrixMode(GL_MODELVIEW);
| |
− | } // End of 'Reshape' function
| |
− | | |
− | /* Timer function */
| |
− | // Подсчет времени
| |
− | void sagl::anim::Timer( void )
| |
− | {
| |
− | long Time = clock();
| |
− |
| |
− | if (IsPause)
| |
− | DeltaTime = 0, PauseTime += Time - OldTime;
| |
− | else
| |
− | DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;
| |
− | OldTime = Time;
| |
− | | |
− | SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
| |
− | } /* End of 'Timer' function */
| |
− | | |
− | /* Display function */
| |
− | // Стандартная функция, вызываемая при перерисовке окна
| |
− | void sagl::anim::Display( void )
| |
− | {
| |
− | // Запуск времени
| |
− | Instance.Timer();
| |
− | // Очищаем цветовой буфер для создания нового изображения
| |
− | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
| |
− | | |
− | glLoadIdentity();
| |
− | // Позиционирование СК
| |
− | gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
| |
− | | |
− | // Отрисовка объектов
| |
− | Instance.Render();
| |
− | | |
− | glFinish();
| |
− | // Копируем вторичный буфер в окно
| |
− | glutSwapBuffers();
| |
− | // Вызываем функцию обновления кадра
| |
− | glutPostRedisplay();
| |
− | } // End of 'Display' function
| |
− | | |
− | /* Keyboard function */
| |
− | // Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
| |
− | void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
| |
− | {
| |
− | // Выход из программы
| |
− | if (Key == 27)
| |
− | exit(0);
| |
− | // Открытие программы в полном экране
| |
− | else if (Key == 'f')
| |
− | glutFullScreen();
| |
− | // Пауза
| |
− | else if (Key == 'p' || Key == 'P')
| |
− | Instance.IsPause = !Instance.IsPause;
| |
− | } // End of 'Keyboard' function
| |
− | | |
− | sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
| |
− | StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
| |
− | {
| |
− | // Инициализации OpenGL и GLUT
| |
− | glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
| |
− |
| |
− | // Задача размеров и позиции окна
| |
− | glutInitWindowPosition(0, 0);
| |
− | glutInitWindowSize(700, 700);
| |
− | // Создание окна
| |
− | glutCreateWindow("T06BALL");
| |
− | | |
− | // Установка функций 'обратного вызова'
| |
− | glutDisplayFunc(Display);
| |
− | glutKeyboardFunc(Keyboard);
| |
− | glutReshapeFunc(Reshape);
| |
− | | |
− | // Установка цвета закраски фона
| |
− | glClearColor(0.3, 0.5, 0.7, 1);
| |
− | // Включение буфера глубины
| |
− | glEnable(GL_DEPTH_TEST);
| |
− | // Включение режима вычисления цвета согласно освещенности от источников света
| |
− | glEnable(GL_LIGHTING);
| |
− | // Включение источника света
| |
− | glEnable(GL_LIGHT0);
| |
− | // Включение упрощенного режима освещенности для простого способа описания свойств поверхности
| |
− | glEnable(GL_COLOR_MATERIAL);
| |
− | // Приведение нормалей к единичной длине
| |
− | glEnable(GL_NORMALIZE);
| |
− | }
| |
− | | |
− | // Деструктор
| |
− | sagl::anim::~anim( void )
| |
− | {
| |
− | // Чистка памяти
| |
− | for (int i = 0; i < StockSize; i++)
| |
− | delete Stock[i];
| |
− | }
| |
− | | |
− | /* Render function */
| |
− | // Отрисовка объектов
| |
− | void sagl::anim::Render( void )
| |
− | {
| |
− | for (int i = 0; i < StockSize; i++)
| |
− | Stock[i]->Render(*this);
| |
− | } // End of 'Render' function
| |
− | | |
− | /* Run function */
| |
− | // Запуск главного цикла
| |
− | void sagl::anim::Run( void )
| |
− | {
| |
− | // Запуск основного цикла построения
| |
− | glutMainLoop();
| |
− | } // End of 'Run' function
| |
− | | |
− | // END OF 'ANIM.CPP' FILE
| |
− | </syntaxhighlight>
| |
− | "'''ANIM.H'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | /* FILENAME: ANIM.H
| |
− | * LAST UPDATE: 17.01.2016
| |
− | */
| |
− | | |
− | #ifndef __ANIM_H_
| |
− | #define __ANIM_H_
| |
− | | |
− | #include <stdio.h>
| |
− | #include <stdlib.h>
| |
− | #include <time.h>
| |
− | | |
− | #include <GL\glut.h>
| |
− | | |
− | #include "VEC.H"
| |
− | | |
− | // Константы
| |
− | #define Pi 3.14159265358979323846
| |
− | #define E 2.71828182845904523536
| |
− | | |
− | // Собственное пространство имен 'sagl'
| |
− | namespace sagl
| |
− | {
| |
− | // Объявления класса анимации наперед
| |
− | class anim;
| |
− |
| |
− | // Функции получения случайных чисел
| |
− | inline double r0( void )
| |
− | {
| |
− | return rand() / (double)RAND_MAX;
| |
− | }
| |
− | inline double r1( void )
| |
− | {
| |
− | return 2.0 * rand() / RAND_MAX - 1;
| |
− | }
| |
− |
| |
− | // Класс объектов
| |
− | class object
| |
− | {
| |
− | public:
| |
− | // Вектора перемещения и скоростей
| |
− | vec P, V, AbsV;
| |
− |
| |
− | // Конструктор
| |
− | object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
| |
− | {
| |
− | }
| |
− |
| |
− | // Отрисовка объектов
| |
− | virtual void Render( anim &Ani )
| |
− | {
| |
− | } // End of 'Render' function
| |
− | }; // end of 'object' class
| |
− |
| |
− | // Класс анимации
| |
− | class anim
| |
− | {
| |
− | private:
| |
− | // Функции 'обратного вызова'
| |
− | static void Display( void );
| |
− | static void Keyboard( unsigned char Key, int X, int Y );
| |
− | static void Reshape( int W, int H );
| |
− | | |
− | // Единственный экземпляр класса
| |
− | static anim Instance;
| |
− |
| |
− | // Конструктор
| |
− | anim( void );
| |
− | | |
− | // Максимальное количество объектов
| |
− | static const int Max = 100;
| |
− | // 'Контейнер' объектов
| |
− | object *Stock[Max];
| |
− | // Размер 'контейнера' объектов
| |
− | int StockSize;
| |
− |
| |
− | // Переменные, хранящие время в секундах
| |
− | long StartTime, OldTime, PauseTime;
| |
− |
| |
− | // Отрисовка объектов
| |
− | void Render( void );
| |
− |
| |
− | // Подсчет времени
| |
− | void Timer( void );
| |
− | public:
| |
− | // Добавление объектов в 'контейнер'
| |
− | anim & operator<<( object *Obj )
| |
− | {
| |
− | if (StockSize < Max )
| |
− | Stock[StockSize++] = Obj;
| |
− | else
| |
− | delete Obj;
| |
− |
| |
− | return *this;
| |
− | }
| |
− |
| |
− | // Ширина и высота окна
| |
− | int WinW, WinH;
| |
− | | |
− | // Переменные, хранящие время в секундах
| |
− | double SyncTime, DeltaTime;
| |
− | | |
− | // Переменная, отвечающая за паузу
| |
− | bool IsPause;
| |
− | | |
− | // Деструктор
| |
− | ~anim( void );
| |
− |
| |
− | // Запуск главного цикла
| |
− | void Run( void );
| |
− |
| |
− | // Метод, возвращающий переменную - единственный экземпляр данного типа
| |
− | static anim & Get( void )
| |
− | {
| |
− | return Instance;
| |
− | }
| |
− | }; // end of 'anim' class
| |
− | } // end of 'sagl' namespace
| |
− | | |
− | #endif /*__ANIM_H_ */
| |
− | | |
− | // END OF 'ANIM.H' FILE
| |
− | </syntaxhighlight>
| |
− | "'''VEC.H'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | /* FILENAME: VEC.H
| |
− | * LAST UPDATE: 17.01.2016
| |
− | */
| |
− | | |
− | #ifndef __VEC_H_
| |
− | #define __VEC_H_
| |
− | | |
− | #include <stdlib.h>
| |
− | #include <math.h>
| |
− | | |
− | // Собственное пространство имен 'sagl'
| |
− | namespace sagl
| |
− | {
| |
− | // Класс векторов
| |
− | class vec
| |
− | {
| |
− | public:
| |
− | // Координаты вектора
| |
− | double X, Y, Z;
| |
− |
| |
− | // Конструктор
| |
− | vec( void ) : X(0), Y(0), Z(0)
| |
− | {
| |
− | }
| |
− |
| |
− | // Конструктор
| |
− | vec( double A, double B, double C ) : X(A), Y(B), Z(C)
| |
− | {
| |
− | }
| |
− |
| |
− | // Функции получения случайных чисел
| |
− | static double R0( void )
| |
− | {
| |
− | return rand() / (double)RAND_MAX;
| |
− | }
| |
− |
| |
− | static double R1( void )
| |
− | {
| |
− | return 2 * rand() / (double)RAND_MAX - 1;
| |
− | }
| |
− |
| |
− | // Функции получения случайных векторов
| |
− | static vec Rnd( void )
| |
− | {
| |
− | return vec(R0(), R0(), R0());
| |
− | }
| |
− |
| |
− | static vec Rnd1( void )
| |
− | {
| |
− | return vec(R1(), R1(), R1());
| |
− | }
| |
− |
| |
− | vec operator+( vec V )
| |
− | {
| |
− | return vec(X + V.X, Y + V.Y, Z + V.Z);
| |
− | }
| |
− |
| |
− | vec operator*( double t )
| |
− | {
| |
− | return vec(X * t, Y * t, Z * t);
| |
− | }
| |
− |
| |
− | vec & operator+=( const vec &V )
| |
− | {
| |
− | X += V.X;
| |
− | Y += V.Y;
| |
− | Z += V.Z;
| |
− |
| |
− | return *this;
| |
− | }
| |
− |
| |
− | // Длина вектора
| |
− | double operator!(void) const
| |
− | {
| |
− | return sqrt(X * X + Y * Y + Z * Z);
| |
− | } /* end of 'operator!' function */
| |
− | }; // end of 'vec' class
| |
− | } // end of 'sagl' namespace
| |
− | | |
− | #endif /*__VEC_H_ */
| |
− | | |
− | // END OF 'VEC.H' FILE
| |
− | </syntaxhighlight>
| |
− | "'''SAMPLE.H'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | /* FILENAME: SAMPLE.H
| |
− | * LAST UPDATE: 17.01.2016
| |
− | */
| |
− | | |
− | #ifndef __SAMPLE_H_
| |
− | #define __SAMPLE_H_
| |
− | | |
− | #include <math.h>
| |
− | | |
− | #include "ANIM.H"
| |
− | | |
− | // Шар, летящий без сопротивлением воздуха
| |
− | class ball : public sagl::object
| |
− | {
| |
− | private:
| |
− | double angle, v; // угол вектора скорости к горизонту; модуль скорости
| |
− | public:
| |
− | // Конструктор
| |
− | ball( void ) : angle(Pi / 3), v(1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Конструктор
| |
− | ball( double angle1, double v1 ) : angle(angle1), v(v1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Отрисовка объекта
| |
− | void Render( sagl::anim &Ani )
| |
− | {
| |
− | // Вектор ускорения свободного падения
| |
− | sagl::vec g = sagl::vec(0, -9.8, 0);
| |
− | // Размер комнаты
| |
− | double Size = 120;
| |
− | | |
− | // Изменение вектора скорости
| |
− | V += g * Ani.DeltaTime;
| |
− | // Изменение вектора перемещения
| |
− | P += V * Ani.DeltaTime;
| |
− | | |
− | // Ограничения - стенки
| |
− | if (P.X > Size / 4)
| |
− | V.X = -fabs(V.X);
| |
− | if (P.X < -Size / 4)
| |
− | V.X = fabs(V.X);
| |
− | | |
− | if (P.Y > Size / 4)
| |
− | V.Y = -fabs(V.Y);
| |
− | if (P.Y < -Size / 4)
| |
− | V.Y = fabs(V.Y);
| |
− | | |
− | if (P.Z > Size / 4)
| |
− | V.Z = -fabs(V.Z);
| |
− | if (P.Z < -Size / 4)
| |
− | V.Z = fabs(V.Z);
| |
− |
| |
− | // Запоминание состояния изменения текущей СК
| |
− | glPushMatrix();
| |
− |
| |
− | // Рисование стенок
| |
− | glutWireCube(Size / 2);
| |
− | // Задача перемещения мяча
| |
− | glTranslated(P.X, P.Y, P.Z);
| |
− | // Цвет мяча
| |
− | glColor3d(0, 1, 0);
| |
− | // Рисование мяча
| |
− | glutSolidSphere(0.5, 30, 30);
| |
− |
| |
− | // Восстановление последнего запоминания состояния изменения текущей СК
| |
− | glPopMatrix();
| |
− | }
| |
− | }; // end of 'ball' class
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
| |
− | class ball_air : public sagl::object
| |
− | {
| |
− | private:
| |
− | double angle, v, m, n;
| |
− | public:
| |
− | // Конструктор
| |
− | ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Конструктор
| |
− | ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Отрисовка объекта
| |
− | void Render( sagl::anim &Ani )
| |
− | {
| |
− | // Вектор ускорения свободного падения и вектор полного ускорения
| |
− | sagl::vec g = sagl::vec(0, -9.8, 0), a;
| |
− | // Размер комнаты
| |
− | double Size = 120;
| |
− | | |
− | // Изменение вектора ускорения
| |
− | a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
| |
− | | |
− | // Изменение вектора скорости
| |
− | V += a * Ani.DeltaTime;
| |
− | // Изменение вектора перемещения
| |
− | P += V * Ani.DeltaTime;
| |
− | | |
− | // Ограничения - стенки
| |
− | if (P.X > Size / 4)
| |
− | V.X = -fabs(V.X);
| |
− | if (P.X < -Size / 4)
| |
− | V.X = fabs(V.X);
| |
− | | |
− | if (P.Y > Size / 4)
| |
− | V.Y = -fabs(V.Y);
| |
− | if (P.Y < -Size / 4)
| |
− | V.Y = fabs(V.Y);
| |
− | | |
− | if (P.Z > Size / 4)
| |
− | V.Z = -fabs(V.Z);
| |
− | if (P.Z < -Size / 4)
| |
− | V.Z = fabs(V.Z);
| |
− |
| |
− | // Запоминание состояния изменения текущей СК
| |
− | glPushMatrix();
| |
− |
| |
− | // Рисование стенок
| |
− | glutWireCube(Size / 2);
| |
− | // Задача перемещения мяча
| |
− | glTranslated(P.X, P.Y, P.Z);
| |
− | // Цвет мяча
| |
− | glColor3d(1, 0, 0);
| |
− | // Рисование мяча
| |
− | glutSolidSphere(0.5, 30, 30);
| |
− |
| |
− | // Восстановление последнего запоминания состояния изменения текущей СК
| |
− | glPopMatrix();
| |
− | }
| |
− | }; // end of 'ball_air' class
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | class ball_air_2 : public sagl::object
| |
− | {
| |
− | private:
| |
− | double angle, v, m, n;
| |
− | public:
| |
− | // Конструктор
| |
− | ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Конструктор
| |
− | ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Отрисовка объекта
| |
− | void Render( sagl::anim &Ani )
| |
− | {
| |
− | // Вектор ускорения свободного падения и вектор полного ускорения
| |
− | sagl::vec g = sagl::vec(0, -9.8, 0), a;
| |
− | // Размер комнаты
| |
− | double Size = 120;
| |
− | | |
− | // Изменение вектора скорости
| |
− | V.Z = V.Z * exp(-n / m * Ani.DeltaTime);
| |
− | V.Y = (V.Y - g.Y * m / n) * exp(-n / m * Ani.DeltaTime) + g.Y * m / n;
| |
− | // Изменение вектора перемещения
| |
− | P += V * Ani.DeltaTime;
| |
− | | |
− | // Ограничения - стенки
| |
− | if (P.X > Size / 4)
| |
− | V.X = -fabs(V.X);
| |
− | if (P.X < -Size / 4)
| |
− | V.X = fabs(V.X);
| |
− | | |
− | if (P.Y > Size / 4)
| |
− | V.Y = -fabs(V.Y);
| |
− | if (P.Y < -Size / 4)
| |
− | V.Y = fabs(V.Y);
| |
− | | |
− | if (P.Z > Size / 4)
| |
− | V.Z = -fabs(V.Z);
| |
− | if (P.Z < -Size / 4)
| |
− | V.Z = fabs(V.Z);
| |
− | | |
− | // Запоминание состояния изменения текущей СК
| |
− | glPushMatrix();
| |
− | | |
− | // Рисование стенок
| |
− | glutWireCube(Size / 2);
| |
− | // Задача перемещения мяча
| |
− | glTranslated(P.X, P.Y, P.Z);
| |
− | // Цвет мяча
| |
− | glColor3d(0, 1, 1);
| |
− | // Рисование мяча
| |
− | glutSolidSphere(0.5, 30, 30);
| |
− |
| |
− | // Восстановление последнего запоминания состояния изменения текущей СК
| |
− | glPopMatrix();
| |
− | }
| |
− | }; // end of 'ball_air_2' class
| |
− | | |
− | // Шар, летящий с сопротивлением воздуха
| |
− | // Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | class ball_air_3 : public sagl::object
| |
− | {
| |
− | private:
| |
− | double angle, v, m, n;
| |
− | public:
| |
− | // Конструктор
| |
− | ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Конструктор
| |
− | ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
| |
− | {
| |
− | P = sagl::vec(sagl::r0() + 5, 5, 0);
| |
− | V.X = 0;
| |
− | V.Y = sin(angle) * v;
| |
− | V.Z = cos(angle) * v;
| |
− | }
| |
− |
| |
− | // Отрисовка объекта
| |
− | void Render( sagl::anim &Ani )
| |
− | {
| |
− | // Вектор ускорения свободного падения и вектор полного ускорения
| |
− | sagl::vec g = sagl::vec(0, -9.8, 0), a;
| |
− | // Размер комнаты
| |
− | double Size = 120;
| |
− | | |
− | // Изменение вектора ускорения
| |
− | a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
| |
− | | |
− | // Изменение вектора скорости
| |
− | V += a * Ani.DeltaTime;
| |
− | // Изменение вектора перемещения
| |
− | P += V * Ani.DeltaTime;
| |
− | | |
− | // Ограничения - стенки
| |
− | if (P.X > Size / 4)
| |
− | V.X = -fabs(V.X);
| |
− | if (P.X < -Size / 4)
| |
− | V.X = fabs(V.X);
| |
− | | |
− | if (P.Y > Size / 4)
| |
− | V.Y = -fabs(V.Y);
| |
− | if (P.Y < -Size / 4)
| |
− | V.Y = fabs(V.Y);
| |
− | | |
− | if (P.Z > Size / 4)
| |
− | V.Z = -fabs(V.Z);
| |
− | if (P.Z < -Size / 4)
| |
− | V.Z = fabs(V.Z);
| |
− | | |
− | // Запоминание состояния изменения текущей СК
| |
− | glPushMatrix();
| |
− | | |
− | // Рисование стенок
| |
− | glutWireCube(Size / 2);
| |
− | // Задача перемещения мяча
| |
− | glTranslated(P.X, P.Y, P.Z);
| |
− | // Цвет мяча
| |
− | glColor3d(1, 0.5, 0);
| |
− | // Рисование мяча
| |
− | glutSolidSphere(0.5, 30, 30);
| |
− |
| |
− | // Восстановление последнего запоминания состояния изменения текущей СК
| |
− | glPopMatrix();
| |
− | }
| |
− | }; // end of 'ball_air_3' class
| |
− | | |
− | #endif /*__SAMPLE_H_ */
| |
− | | |
− | // END OF 'SAMPLE.H' FILE
| |
− | </syntaxhighlight>
| |
− | </div>
| |
− | [http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
| |
− | <br>
| |
− | | |
− | '''[[Рубинова Раиса]]'''
| |
− | | |
− | '''Описание программы''': программа состоит из четырех независимых друг от друга частей:
| |
− | # Полет тела без сопротивления воздуха;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
| |
− | # Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
− | # Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
| |
− | | |
− | Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут]. | |
− | | |
− | <div class="mw-collapsible-content">
| |
− | | |
− | [[File:Обычный.png]]
| |
− | [[File:Точный.png]]
| |
− | [[File:Верле2.png]]
| |
− | [[File:Верле1.png]]
| |
− | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | // Первый случай
| |
− | | |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include <cstdlib>
| |
− | #include <fstream>
| |
− | | |
− | /// Программа, анализирующая полет тела;
| |
− | | |
− | using namespace std;
| |
− | double a,s,H,p1,p2,X,f; /// Создание переменных, необходимых для работы:
| |
− | /// a - угол к горизонту, под которым летит тело, вводится пользователем;
| |
− | /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
| |
− | /// H - координата тела по оси Oy;
| |
− | /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
| |
− | /// X - координата тела по оси Oy;
| |
− | /// f - шаг по времени;
| |
− | | |
− | int main()
| |
− | {
| |
− | cout << "Enter speed and angle and step of time" << endl; /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
| |
− | cin >> s >> a >> f; /// Считывание данных, введенных пользователем, в переменные;
| |
− | double t=s*sin(a*3.14159/180.0)/9.8; /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
| |
− | for (double i=f; i<(2*t+f); i+=f) /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
| |
− | {
| |
− | p1=s*sin(a*3.14159/180)*i; /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
| |
− | p2=4.9*i*i; /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
| |
− | H=double(p1)-p2; /// Вычисление координаты тела по оси Oy;
| |
− | X=s*cos(a*3.14159/180)*i; /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
| |
− | cerr << X << " "; /// Вывод на экран значения по оси Ox
| |
− | cerr << H << endl; /// и по оси Oy;
| |
− | }
| |
− | ofstream out("zap.txt"); /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
| |
− | for (double i=0; i<(2*t+f); i+=f) /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
| |
− | {
| |
− | p1=s*sin(a*3.14159/180)*i; /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
| |
− | p2=4.9*i*i; /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
| |
− | H=double(p1)-p2; /// Вычисление координаты тела по оси Oy;
| |
− | X=s*cos(a*3.14159/180)*i; /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
| |
− | out << X << " "; /// Запись в файл значения по оси Ox
| |
− | out << H << endl; /// и по оси Oy;
| |
− | }
| |
− | out.close(); /// Закрываем файл, с которым работали в течение программы;
| |
− | return 0; /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
| |
− | }
| |
− | | |
− | // Второй случай
| |
− | | |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include <cstdlib>
| |
− | #include <fstream>
| |
− | | |
− | /// Программа, позволяющая описать полет точки при помощи точного метода;
| |
− | | |
− | using namespace std;
| |
− | double v,a,st,m; /// Создание переменных, необходимых для работы:
| |
− | /// v - модуль скорости, который задает сам пользователь;
| |
− | /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
| |
− | /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
| |
− | /// m - масса тела, задается пользователем;
| |
− | double *V,*X, *Y, *U; /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
| |
− | /// V - массив, хранящий значения скорости по оси Ox;
| |
− | /// X - массив, хранящий координаты точки по оси Ox;
| |
− | /// Y - массив, хранящий значения скорости по оси Oy;
| |
− | /// U - массив, хранящий координаты точки по оси Oy;
| |
− | | |
− | int main()
| |
− | {
| |
− | cout << "Enter speed and angle and step of time and weight" << endl; /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
| |
− | cin >> v >> a >> st >> m; /// Считывание данных, введенных пользователей в переменные;
| |
− | double t=(v/9.8)*sin(3.14159*a/180.0); /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
| |
− | int n=2*t/st; /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
| |
− | //int p=1/st;
| |
− | V = new double [n+2]; /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
| |
− | X = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
| |
− | Y = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | U = new double [n+2]; /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | V[0]=v*cos(3.14159*a/180.0); /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
| |
− | X[0]=0; /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
| |
− | U[0]=v*sin(3.14159*a/180.0); /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
| |
− | Y[0]=0; /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
| |
− | ofstream out("Res.txt"); /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
| |
− | for (int i=1; i<n; ++i) /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
| |
− | /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
| |
− | {
| |
− | Y[i]=(m/0.001)*(U[0]+9.8*(m/0.001))*(1-exp(((0-0.001)/m)*i*st))-9.8*(m/0.001)*i*st; /// Вычисление координаты тела в момент времени (i*st) по оси Oy по формуле, выведенной через дифференциальное уравнение точки для вертикальной оси и находящей координату как функцию от времени и координаты тела в предыдущей рассматриваемой нами точке;
| |
− | X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st)); /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
| |
− | /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
| |
− | /// Движение по горизонтальной оси рассматривается как равномерное прямолинейное движение;
| |
− | /// Движение по вертикальной оси рассматривается как равноускоренное прямолинейное движение;
| |
− | cerr << X[i] << " " << Y[i] << endl; /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | out << X[i] << " " << Y[i] << endl; /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
| |
− | }
| |
− | out.close(); /// Закрываем файл, с которым работали в течение программы;
| |
− | return 0; /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
| |
− | | |
− | | |
− | }
| |
− | | |
− | // Третий случай
| |
− | | |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include <cstdlib>
| |
− | #include <fstream>
| |
− | | |
− | /// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
| |
− | | |
− | using namespace std;
| |
− | double v,a,st,m,x,y; /// Создание переменных, необходимых для работы;
| |
− | /// v - модуль скорости, который задает сам пользователь;
| |
− | /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
| |
− | /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
| |
− | /// m - масса тела, задается пользователем;
| |
− | /// x - координата тела по оси Ox в мнимый момент времени t=-1;
| |
− | /// y - координата тела по оси Oy в мнимый момент времени t=-1;
| |
− | double *V,*X, *Y, *U; /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
| |
− | /// V - массив, хранящий значения скорости по оси Ox;
| |
− | /// X - массив, хранящий координаты точки по оси Ox;
| |
− | /// Y - массив, хранящий значения скорости по оси Oy;
| |
− | /// U - массив, хранящий координаты точки по оси Oy;
| |
− | | |
− | int main()
| |
− | {
| |
− | cout << "Enter speed and angle and step of time and weight" << endl; /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
| |
− | cin >> v >> a >> st >> m; /// Считывание данных, введенных пользователей в переменные;
| |
− | double t=(v/9.8)*sin(3.14159*a/180.0); /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
| |
− | int n=2*t/st; /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
| |
− | //int p=1/st;
| |
− | V = new double [n+2]; /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
| |
− | X = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
| |
− | Y = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | U = new double [n+2]; /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | V[0]=v*cos(3.14159*a/180.0); /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
| |
− | X[0]=0; /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
| |
− | x=X[0]-V[0]*st; /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
| |
− | X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st; /// Вычисление координаты тела по оси Ox в момент времени t=1;
| |
− | U[0]=v*sin(3.14159*a/180.0); /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
| |
− | Y[0]=0; /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
| |
− | y=Y[0]-U[0]*st; /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
| |
− | Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st; /// Вычисление координаты тела по оси Oу в момент времени t=1;
| |
− | cerr << X[1] << " " << Y[1] << endl; /// Вывод на экран значений координат по обеим осям в момент времени t=1;
| |
− | ofstream out("Res.txt"); /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
| |
− | out << X[1] << " " << Y[1] << endl; /// Записываем в файл полученные значения координат тела в момент времени t=1;
| |
− | int k=1; /// Создаем целочисленную переменную k=1 для работы в цикле;
| |
− | //cerr<<"N "<<n<<"\n";
| |
− | for (int i=0; i<n; ++i) /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
| |
− | /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
| |
− | {
| |
− | X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st; /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
| |
− | V[k]=(X[k+1]-X[k-1])/(2*st); /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
| |
− | Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k])*st*st; /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
| |
− | U[k]=(Y[k+1]-Y[k-1])/(2*st); /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
| |
− | //cerr <<i<<" "<<k<<" "<<
| |
− | cerr << X[k+1] << " " << Y[k+1] << endl; /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | out << X[k+1] << " " << Y[k+1] << endl; /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | k=k+1; /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
| |
− | /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
| |
− | }
| |
− | out.close(); /// Закрываем файл, с которым работали в течение программы;
| |
− | return 0; /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
| |
− | }
| |
− | | |
− | // Четвертый случай
| |
− | | |
− | #include <iostream>
| |
− | #include <math.h>
| |
− | #include <cstdlib>
| |
− | #include <fstream>
| |
− | | |
− | /// Программа, анализирующая полет тела при помощи метода Верле;
| |
− | | |
− | using namespace std;
| |
− | double v,a,st,m,x,y; /// Создание переменных, необходимых для работы:
| |
− | /// v - модуль скорости, который задает сам пользователь;
| |
− | /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
| |
− | /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
| |
− | /// m - масса тела, задается пользователем;
| |
− | /// x - координата тела по оси Ox в мнимый момент времени t=-1;
| |
− | /// y - координата тела по оси Oy в мнимый момент времени t=-1;
| |
− | double *V,*X, *Y, *U; /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
| |
− | /// V - массив, хранящий значения скорости по оси Ox;
| |
− | /// X - массив, хранящий координаты точки по оси Ox;
| |
− | /// Y - массив, хранящий значения скорости по оси Oy;
| |
− | /// U - массив, хранящий координаты точки по оси Oy;
| |
− | | |
− | int main()
| |
− | {
| |
− | cout << "Enter speed and angle and step of time and weight" << endl; /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
| |
− | cin >> v >> a >> st >> m; /// Считывание данных, введенных пользователем, в переменные;
| |
− | double t=(v/9.8)*sin(3.14159*a/180.0); /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
| |
− | int n=2*t/st; /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
| |
− | //int p=1/st;
| |
− | V = new double [n+2]; /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
| |
− | X = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
| |
− | Y = new double [n+2]; /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | U = new double [n+2]; /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
| |
− | V[0]=v*cos(3.14159*a/180.0); /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
| |
− | X[0]=0; /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
| |
− | x=X[0]-V[0]*st; /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
| |
− | X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st; /// Вычисление координаты тела по оси Ox в момент времени t=1;
| |
− | U[0]=v*sin(3.14159*a/180.0); /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
| |
− | Y[0]=0; /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
| |
− | y=Y[0]-U[0]*st; /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
| |
− | Y[1]=2*Y[0]-y-(0.01/m)*U[0]*U[0]/sin(3.14159*a/180.0)*st*st; /// Вычисление координаты тела по оси Oу в момент времени t=1;
| |
− | cerr << X[1] << " " << Y[1] << endl; /// Вывод на экран значений координат по обеим осям в момент времени t=1;
| |
− | ofstream out("Res.txt"); /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
| |
− | out << X[1] << " " << Y[1] << endl; /// Записываем в файл полученные значения координат тела в момент времени t=1;
| |
− | int k=1; /// Создаем целочисленную переменную k=1 для работы в цикле;
| |
− | //cerr<<"N "<<n<<"\n";
| |
− | for (int i=0; i<n; ++i) /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
| |
− | /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
| |
− | {
| |
− | X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*V[k]*st*st; /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
| |
− | V[k]=(X[k+1]-X[k-1])/(2*st); /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
| |
− | Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k]*U[k])*st*st; /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
| |
− | U[k]=(Y[k+1]-Y[k-1])/(2*st); /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
| |
− | //cerr <<i<<" "<<k<<" "<<
| |
− | cerr << X[k+1] << " " << Y[k+1] << endl; /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | out << X[k+1] << " " << Y[k+1] << endl; /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
| |
− | k=k+1; /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
| |
− | /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
| |
− | }
| |
− | out.close(); /// Закрываем файл, с которым работали в течение программы;
| |
− | return 0; /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
| |
− | }
| |
− | | |
− | </syntaxhighlight>
| |
− | </div>
| |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | '''[[Савельева Ольга]]'''
| |
− | | |
− | '''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
| |
− | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | | |
− | <div class="mw-collapsible-content">
| |
− | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | #include <stdio.h>
| |
− | #include <stdlib.h>
| |
− | #include <cmath>
| |
− | | |
− | using namespace std;
| |
− | | |
− | FILE *output;
| |
− | | |
− | double e = 0.0000001; //точность
| |
− | double g = 9.8; //ускорение свободного падения
| |
− | double dt = 0.00001; //шаг по времени
| |
− | double windageLinearCoefficient = 0.1;
| |
− | double windageSquareCoefficient = 0.00001;
| |
− | | |
− | struct Vector //вектор
| |
− | {
| |
− | double x, y;
| |
− | Vector():x(0), y(0)
| |
− | {}
| |
− | Vector(double x, double y):x(x), y(y)
| |
− | {}
| |
− | const Vector operator+(const Vector &v) const
| |
− | {
| |
− | return Vector(this -> x + v.x, this -> y + v.y);
| |
− | }
| |
− | const Vector operator-(const Vector &v) const
| |
− | {
| |
− | return Vector(this -> x - v.x, this -> y - v.y);
| |
− | }
| |
− | const Vector operator*(const double k) const
| |
− | {
| |
− | return Vector(this -> x * k, this -> y * k);
| |
− | }
| |
− | const Vector operator*(const int k) const
| |
− | {
| |
− | return Vector(this -> x * k, this -> y * k);
| |
− | }
| |
− | const Vector operator/(const double k) const
| |
− | {
| |
− | return Vector(this -> x / k, this -> y / k);
| |
− | }
| |
− | };
| |
− | | |
− | const Vector operator*(const double a, const Vector &v)
| |
− | {
| |
− | return Vector(v.x * a, v.y * a);
| |
− | }
| |
− | | |
− | const Vector operator*(const int k, const Vector &v)
| |
− | {
| |
− | return Vector(v.x * k, v.y * k);
| |
− | }
| |
− | | |
− | double abs(const Vector &v)
| |
− | {
| |
− | return sqrt(v.x * v.x + v.y * v.y);
| |
− | }
| |
− | | |
− | void printCoordinate(const char *description, const Vector &v) //выводит координаты в более читаемом виде
| |
− | {
| |
− | fputs(description, output);
| |
− | fputs(": ", output);
| |
− | fprintf(output, "%lf", v.x);
| |
− | fputs(", ", output);
| |
− | fprintf(output, "%lf\n", v.y);
| |
− | }
| |
− | | |
− | Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
| |
− | {
| |
− | double fallTime = 2 * velocity * sin(angle) / g; //расчет времени падения
| |
− | if((time < 0) or (time > fallTime))
| |
− | time = fallTime;
| |
− | double x = velocity * cos(angle) * time; // x = vx*t;
| |
− | double y = velocity * sin(angle) * time - g * time * time / 2; // y = vy*t-(g*t^2)/2;
| |
− | return Vector(x, y);
| |
− | }
| |
− | | |
− | Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
| |
− | {
| |
− | double nowTime = dt;
| |
− | Vector rsb(0, 0);
| |
− | if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
| |
− | return rsb; //вернитесь в начальную точку
| |
− | Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
| |
− | Vector r = v * dt; //вторая точка
| |
− | Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
| |
− | a.y -= g;
| |
− | v = v + a * dt; //скорость во второй точке
| |
− | a = -windageLinearCoefficient * v; //ускорение во второй точке
| |
− | a.y -= g;
| |
− | while((r.y > 0) or ((time > 0) and (nowTime <= time))) //пока точка выше 0 или не достигла заданного времени
| |
− | {
| |
− | Vector rn = 2 * r - rsb + a * dt * dt; // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
| |
− | v = (rn - rsb) / (2 * dt); // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
| |
− | rsb = r; //обновление r(t-dt) and r(t)
| |
− | r = rn;
| |
− | a = -windageLinearCoefficient * v; //обновление a(t)
| |
− | a.y -= g;
| |
− | nowTime += dt; //обновленное время
| |
− | }
| |
− | return r;
| |
− | }
| |
− | | |
− | Vector calculateForTime(Vector &v, double time)
| |
− | {
| |
− | Vector r;
| |
− | // x = vx/k*(1-e^(-k*t));
| |
− | r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
| |
− | // y = ((vy+g/k)*(1-e^(-k*t))-g*t)/k;
| |
− | r.y = ((v.y + g / windageLinearCoefficient) * (1 - exp(-windageLinearCoefficient * time)) - g * time) / windageLinearCoefficient;
| |
− | return r;
| |
− | }
| |
− | | |
− | Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
| |
− | {
| |
− | if(windageLinearCoefficient < e) //если коэффициент слишком близок к нулю
| |
− | return getCoordinatesWithoutWindage(velocity, angle, time); //вычисляй будто это 0
| |
− | Vector r;
| |
− | Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
| |
− | if(time >= 0) //время данное
| |
− | {
| |
− | r = calculateForTime(v, time);
| |
− | if(r.y >= 0) //если объект в воздухе или только приземлился
| |
− | return r; //затем верните координаты объекта
| |
− | else //еще
| |
− | return getCoordinatesAccurateLinear(velocity, angle); //верните координаты приземления
| |
− | }
| |
− | else
| |
− | {
| |
− | double timer, timel, timem;
| |
− | timer = v.y / g;
| |
− | timel = 0;
| |
− | while(calculateForTime(v, timer).y > 0) //смотрим на некоторые значения времени, которые больше времени посадки
| |
− | timer *= 1.5;
| |
− | timem = timel + (timer - timel) / 2;
| |
− | r = calculateForTime(v, timem);
| |
− | while(abs(r.y) > e) //бинарный поиск времени посадки
| |
− | {
| |
− | if(r.y > 0)
| |
− | timel = timem;
| |
− | else
| |
− | timer = timem;
| |
− | timem = timel + (timer - timel) / 2;
| |
− | r = calculateForTime(v, timem);
| |
− | }
| |
− | return r;
| |
− | }
| |
− | }
| |
− | | |
− | Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
| |
− | {
| |
− | double nowTime = dt;
| |
− | Vector rsb(0, 0);
| |
− | if((dt / 2 - time > 0)and(time >= 0)) //если время слишком малое для рсчета
| |
− | return rsb; //вернитесь в начальную точку
| |
− | Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
| |
− | Vector r = v * dt; //вторая точка
| |
− | Vector a = -abs(v) * v * windageSquareCoefficient; //ускорение в начальной точке
| |
− | a.y -= g;
| |
− | v = v + a * dt; //скорость во второй точке
| |
− | a = -abs(v) * v * windageSquareCoefficient; //ускорение во второй точке
| |
− | a.y -= g;
| |
− | while((r.y > 0) or ((time > 0) and (nowTime <= time))) //когда точка выше нулевой отметки и не достигает заданного времени
| |
− | {
| |
− | Vector rn = 2 * r - rsb + a * dt * dt; // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
| |
− | v = (rn - rsb) / (2 * dt); // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
| |
− | rsb = r; //updating r(t-dt) and r(t)
| |
− | r = rn;
| |
− | a = -abs(v) * v * windageSquareCoefficient; //новое a(t)
| |
− | a.y -= g;
| |
− | nowTime += dt; //новое a(t)
| |
− | }
| |
− | return r;
| |
− | }
| |
− | | |
− | void err(const char *s) //печатает сообщение об ошибке и завершает работу
| |
− | {
| |
− | fputs(s, output);
| |
− | exit(1);
| |
− | }
| |
− | | |
− | int main(int argc, const char *argv[])
| |
− | {
| |
− | double velocity, angle;
| |
− | bool needRead = true;
| |
− | if(argc==3) //если даны 2 аргумента
| |
− | {
| |
− | velocity = atof(argv[1]); //истолкование его как скорости и угла
| |
− | angle = atof(argv[2]);
| |
− | needRead = false;
| |
− | }
| |
− | if(needRead)
| |
− | {
| |
− | puts("Enter initial velocity (m/s)");
| |
− | scanf("%lf", &velocity);
| |
− | }
| |
− | if(velocity < 0) //проверка, если скорость меньше 0
| |
− | err("Initial velocity must be above 0");
| |
− | if(needRead)
| |
− | {
| |
− | puts("Enter initial angle (0-180 degrees)");
| |
− | scanf("%lf", &angle);
| |
− | }
| |
− | if((angle < 0) or (angle > 180)) //проверка, что угол в нужном интервале
| |
− | err("Initial angle must be from 0 to 180");
| |
− | angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
| |
− | output = fopen("Coordinates.txt", "w"); //открытие результативного файла
| |
− | //вычисление и печать 4 значений
| |
− | printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
| |
− | printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
| |
− | printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
| |
− | printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
| |
− | fclose(output); //закрытие файла
| |
− | return 0;
| |
− | }
| |
− | </syntaxhighlight>
| |
− | </div>
| |
− | Скачать можно [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9A%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D1%8B.zip здесь]
| |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | | |
− | | |
− | '''[[Сенников Иван]]'''
| |
− | | |
− | '''Суть программы:'''Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.
| |
− | | |
− | '''Идея:''' Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.
| |
− | | |
− | '''Инструкция:''' Результаты программы будут записаны в соответствующий файл (подробности смотри в самой программе). Пользователю будет предоставлена возможность ввести начальную скорость и угол, под которым и бросают тело.
| |
− | | |
− | Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Throws_v2.0.zip здесь].
| |
− | | |
− | </div>
| |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | '''[[Степанянц Степан]]'''
| |
− | | |
− | '''Описание программы''': программа записывает в четыре файла результаты вычисления:
| |
− | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− | | |
− | Скачать можно [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
| |
− | | |
− | <div class="mw-collapsible-content">
| |
− | [[File:graph239.png]]
| |
− | | |
− | Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
| |
− | | |
− | | |
− | | |
− | Файл "'''main.cpp'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | #include <iostream>
| |
− | #include <locale.h>
| |
− | #include <math.h>
| |
− | #include <fstream>
| |
− | #include<iomanip>
| |
− | #include <cmath>
| |
− | using namespace std;
| |
− | main ()
| |
− | {
| |
− | ofstream F; //a1-угол в градусах,dt-шаг,r-сопротивление воздуха
| |
− | int u0=50;
| |
− | double x,y,t,a,a1=30,dt=0.1,y0=0,x0=0,g=9.8,r=0.05,m=1,ux,uy,ypr,xpr,ysl,xsl,u,yt; //ux,uy - проэкции скорости на оси х и у.
| |
− | a=a1*M_PI/180; //Градусы в радианы
| |
− | t=0;
| |
− |
| |
− | //Движение без сопротивления воздуха
| |
− | F.open("C:\\1.txt",ios::out);
| |
− | while(y>=0)
| |
− | {
| |
− | x=x0+u0*cos(M_PI/6)*t;
| |
− | y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t; //Расчитываем координаты в каждой точке через шаг
| |
− | F<<x<<" "<<y<<endl;
| |
− | t=t+dt;
| |
− |
| |
− | }
| |
− |
| |
− | F.close();
| |
− | //Точное решение для линейной зависимости
| |
− | F.open("C:\\2.txt",ios::out);
| |
− | y=y0;
| |
− | x=x0;
| |
− | t=0; //Расчитываем координаты в каждой точке через шаг
| |
− | while(y>=0)
| |
− | {
| |
− | ux = u0 * cos(a);
| |
− | uy = u0 * sin(a);
| |
− | x = x0+ (m * ux / r)* (1 - exp(-1 * r * t / m)); //подстановка формул
| |
− | y = y0+(m/r)*((uy + g * m / r)*(1 - exp(-1 * r * t / m)) - g * t);
| |
− | t = t + dt;
| |
− |
| |
− | F << x << ' ' << y << endl;
| |
− |
| |
− |
| |
− |
| |
− | }
| |
− | F.close();
| |
− | //метод Верле 1
| |
− | ypr = y0 - u0*sin(a)*dt;
| |
− | yt=ypr;
| |
− | xpr = x0 - u0*cos(a)*dt;
| |
− | x = x0; //Начальные условия
| |
− | y = y0;
| |
− | u = u0;
| |
− | ux = u0 * cos(a);
| |
− | uy = u0 * sin(a);
| |
− | F.open("C:\\3.txt",ios::out);
| |
− |
| |
− | while (y >= y0)
| |
− | {
| |
− | xsl = 2 * x - xpr - (r / m) * u * ux * (dt * dt);
| |
− | ux = ( xsl - xpr )/ (2 * dt);
| |
− | ysl = 2 * y - ypr - (g + (r / m) * u * uy) * (dt * dt); //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
| |
− | uy = (ysl - ypr)/ (2 * dt);
| |
− | u = sqrt(uy*uy + ux*ux );
| |
− | F << x << ' ' << y << endl;
| |
− |
| |
− | xpr = x;
| |
− | x = xsl;
| |
− | ypr = y;
| |
− | y = ysl;
| |
− | }
| |
− | F.close();
| |
− | //Метод Верле 2
| |
− | ypr = y0 - u0*sin(a)*dt;
| |
− | yt=ypr;
| |
− | xpr = x0 - u0*cos(a)*dt;
| |
− | x = x0; //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
| |
− | y = y0;
| |
− | u = u0;
| |
− | ux = u0 * cos(a);
| |
− | uy = u0 * sin(a);
| |
− | F.open("C:\\4.txt",ios::out);
| |
− | | |
− | while (y >= y0)
| |
− | {
| |
− | xsl = 2 * x - xpr - (r / m) * ux * (dt * dt);
| |
− | ux = ( xsl - xpr )/ (2 * dt);
| |
− | ysl = 2 * y - ypr - (g + (r / m) * uy) * (dt * dt);
| |
− | uy = (ysl - ypr)/ (2 * dt);
| |
− | u = sqrt(uy*uy + ux*ux );
| |
− | F << x << ' ' << y << endl;
| |
− |
| |
− | xpr = x;
| |
− | x = xsl;
| |
− | ypr = y;
| |
− | y = ysl;
| |
− | }
| |
− | F.close();
| |
− |
| |
− |
| |
− | return 0;
| |
− |
| |
− |
| |
− | }
| |
− | | |
− | </syntaxhighlight>
| |
− | </div>
| |
− | | |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | '''[[Александр Сюрис]]'''
| |
− | | |
− | '''Описание программы''':
| |
− | Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
| |
− | #Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
| |
− | #Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | #Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
| |
− | #Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
| |
− | Скачать можно [http://mech.spbstu.ru/File:%D0%9F%D0%BE%D0%BB%D0%B5%D1%82_%D1%82%D0%B5%D0%BB%D0%B0(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip тут].
| |
− | <div class="mw-collapsible-content">
| |
− | [[File:Снимок.PNG]]
| |
− | Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
| |
− | Файл "'''main.cpp'''"
| |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | #include <iostream>
| |
− | #include <fstream>
| |
− | #include <math.h>
| |
− | #include <cmath>
| |
− | using namespace std;
| |
− | int o;
| |
− | double v,a,m,k;
| |
− | ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
| |
− | | |
− | | |
− | | |
− | int rez_1(double v, double a)
| |
− | {
| |
− | fout<<"---------------Первый режим-------------------------"<<endl;
| |
− | fout<<" T=0 x=0 y=0";
| |
− | fout<<endl;
| |
− | double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
| |
− | V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
| |
− | V0y=v*sin(a/180*M_PI);
| |
− | Ty=2*V0y/g;//время полета
| |
− | while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
| |
− | {
| |
− | x=x+V0x*t; //ф-лы для рассчета x и y в данный момент времени
| |
− | y=y+V0y*t-g*pow(t,2)/2;
| |
− | | |
− | if (y<0) //если y<0
| |
− | {
| |
− | t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
| |
− | x=x+V0x*t1;//используя это время находим координату по х
| |
− | fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
| |
− | break;
| |
− | }
| |
− | else
| |
− | {
| |
− | V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
| |
− | fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
| |
− | T=T+t;//увел время на шаг
| |
− | }
| |
− | }
| |
− | | |
− | | |
− | }
| |
− | | |
− | | |
− | int rez_2(double v, double a, double k, double m)
| |
− | {
| |
− | fout<<"---------------Второй режим работы-------------------------"<<endl;
| |
− | fout<<" T=0 x=0 y=0";
| |
− | fout<<endl;
| |
− | double t=0.1, Vx=v*cos(a/180*M_PI), Vy=v*sin(a/180*M_PI),y,x,T=0.1,g=9.8;
| |
− | x=(m*Vx/k)*(1-exp(-1*k*T/m)); //ф-лы для рассчета x и y в данный момент времени
| |
− | y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T); //точное решение при лин завсисимости
| |
− | while (y>0)
| |
− | {
| |
− | x=(m*Vx/k)*(1-exp(-1*k*T/m));
| |
− | y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T);
| |
− | fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
| |
− | T=T+t;
| |
− | }
| |
− | | |
− | | |
− | }
| |
− | | |
− | | |
− | | |
− | int rez_3(double v, double a, double k, double m)
| |
− | {
| |
− | fout<<"---------------Третий режим работы-------------------------"<<endl;
| |
− | fout<<" T=0 x=0 y=0";
| |
− | fout<<endl;
| |
− | double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
| |
− | x3=0,x2=0,x1=x2-Vxn*t, y3=0,
| |
− | y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
| |
− | //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
| |
− | | |
− | | |
− | x3=2*x2-x1-k/m*Vxn*pow(t,2); //координаты в момент времени T
| |
− | y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
| |
− | Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
| |
− | Vyn=(y3-y1)/(2.0*t);
| |
− | x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
| |
− | y1=y2;
| |
− | x2=x3;//-//- к координате в n шаге значение в момент времени T
| |
− | y2=y3;
| |
− | while (y2>0)
| |
− | {
| |
− | x3=2*x2-x1-k/m*Vxn*pow(t,2);
| |
− | y3=2*y2-y1-(g+k/m*Vyn)*pow(t,2);
| |
− | Vxn=(x3-x1)/(2.0*t);
| |
− | Vyn=(y3-y1)/(2.0*t);
| |
− | fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
| |
− | | |
− | if (y3<0)
| |
− | {
| |
− | t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
| |
− | x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
| |
− | fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
| |
− | }
| |
− | | |
− | T=T+t;
| |
− | x1=x2;
| |
− | y1=y2;
| |
− | x2=x3;
| |
− | y2=y3;
| |
− | | |
− | }
| |
− | | |
− | }
| |
− | | |
− | | |
− | int rez_4(double v, double a, double k, double m)
| |
− | {
| |
− | fout<<"---------------Четвертый режим работы-------------------------"<<endl;
| |
− | fout<<" T=0 x=0 y=0";
| |
− | fout<<endl;
| |
− | double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
| |
− | x3=0,x1=0, x2=x1+Vxn*t, y3=0, y1=0,
| |
− | y2=y1+Vyn*t, g=9.8, t1, T=0.1, V=v;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
| |
− | //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
| |
− | | |
− | | |
− | x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
| |
− | y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
| |
− | Vxn=(x3-x1)/(2.0*t);
| |
− | Vyn=(y3-y1)/(2.0*t);
| |
− | V=sqrt(pow(Vxn,2)+pow(Vyn,2.0));
| |
− | x1=x2;
| |
− | y1=y2;
| |
− | x2=x3;
| |
− | y2=y3;
| |
− | while (y2>0)
| |
− | {
| |
− | x3=2.0*x2-x1-(k/m)*Vxn*V*pow(t,2);
| |
− | y3=2.0*y2-y1-(g+(k/m)*Vyn*V)*pow(t,2);
| |
− | Vxn=(x3-x1)/(2.0*t);
| |
− | Vyn=(y3-y1)/(2.0*t);
| |
− | V=sqrt(pow(Vxn,2)+pow(Vyn,2));
| |
− | fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
| |
− | | |
− | if (y3<0)
| |
− | {
| |
− | t1=sqrt(abs((-y1+2.0*y2)/(g+(k/m)*Vyn*V)));
| |
− | x3=2.0*x2-x1-(k/m)*Vxn*V*pow((t+t1),2);
| |
− | fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
| |
− | }
| |
− | | |
− | | |
− | T=T+t;
| |
− | x1=x2;
| |
− | y1=y2;
| |
− | x2=x3;
| |
− | y2=y3;
| |
− | | |
− | }
| |
− | | |
− | }
| |
− | | |
− | | |
− | int main()
| |
− | {
| |
− | | |
− | setlocale(LC_ALL, "rus");
| |
− | cout<<"Введите скорость тела и угол"<<endl;
| |
− | cin>>v>>a;
| |
− | | |
− | while (1>0){
| |
− | cout<<"Выберите режим работы программы:"<<endl;
| |
− | cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
| |
− | cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
| |
− | cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
| |
− | cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
| |
− | cout<<"5 - Выйти";
| |
− | cin>>o;
| |
− | | |
− | if (o==1)
| |
− | rez_1(v,a);
| |
− | if (o==2)
| |
− | {
| |
− | cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
| |
− | cin>>m>>k;
| |
− | rez_2(v,a,k,m);
| |
− | }
| |
− | | |
− | if (o==3)
| |
− | {
| |
− | cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
| |
− | cin>>m>>k;
| |
− | rez_3(v,a,k,m);
| |
− | }
| |
− | if (o==4)
| |
− | {
| |
− | cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
| |
− | cin>>m>>k;
| |
− | rez_4(v,a,k,m);
| |
− | }
| |
− | if (o==5)
| |
− | break;
| |
− | | |
− | }
| |
− | }
| |
− | | |
− | | |
− | </syntaxhighlight>
| |
− | </div>
| |
− | | |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | '''[[Тимошенко Валентина]]'''
| |
− | | |
− | '''Описание программы''': при запуске пользователь вводит шаг функции, угол, под которым бросают тело, массу тела, сопротивление воздуха и скорость.
| |
− | Программа записывает в четыре файла результаты вычисления:
| |
− | #Координаты, рассчитанные по формуле для движения без сопротивления воздуха;
| |
− | #Координаты, рассчитанные по формуле для движения с учетом сопротивления воздуха;
| |
− | #Координаты, полученные методом Верле при квадратичной зависимости силы сопротивления воздуха от скорости.
| |
− | #Координаты, полученные методом Верле при линейной зависимости силы сопротивления воздуха от скорости;
| |
− | | |
− | Скачать можно [http://tm.spbstu.ru/Файл:motion.zip тут.]
| |
− | | |
− | <div class="mw-collapsible-content">
| |
− | | |
− | '''Визуализированный результат работы программы'''
| |
− | [[File:Grafics.png]]
| |
− | | |
− | Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
| |
− | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | | |
− | #include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
| |
− | #include <fstream> /// и для движений с учётом сопротивления и без его учёта
| |
− | #include <math.h>
| |
− | #include<stdlib.h>
| |
− | using namespace std;
| |
− | | |
− | int main()
| |
− | {
| |
− | double a, step, Pi, g, Vo, m, r;
| |
− | ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
| |
− | | |
− | double x, y, x_0, y_0, x0, y0, Vx, Vy;
| |
− | ///переменные для движения точки без учёта сопротивления и с его учётом
| |
− | ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
| |
− | ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
| |
− | ///Vx - скорость тела по оси Ох, Vу - скорость тела по оси Оу
| |
− | ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
| |
− | | |
− | double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
| |
− | ///переменные для 1го варианта метода Верле
| |
− | ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
| |
− | ///у1 - координата тела по оси Оу на (n-1) шаге, у2 - координата тела по оси Оу на (n) шаге, у3 - координата тела по оси Оу на (n+1) шаге
| |
− | ///Vx0 - начальная скорость тела по оси Ох, Vy0 - начальная скорость тела по оси Оу
| |
− | ///Vxn - скорость тела в данный момент времени по оси Ох, Vyn - скорость тела в данный момент времени по оси Оу
| |
− | | |
− | double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
| |
− | ///переменные для 2го варианта метода Верле
| |
− | ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
| |
− | ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
| |
− | ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
| |
− | | |
− | g=10; ///значение ускорения свободного падения
| |
− | Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
| |
− | | |
− | do ///цикл, запрашивающий ввод пользователем значения шага функции
| |
− | {
| |
− | cout << "Input the step, it must be less than 1" << endl; ///ввод с клавиатуры шага(то же самое, что дельта t), шаг должен быть маленьким (меньше 1)
| |
− | cin >> step; ///вывод величины шага на экран
| |
− | }
| |
− | while (step>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
| |
− | | |
− | cout << '\n' << "Input the corner in degrees,the corner is in the range from 0 to 90 degrees" << endl; ///ввод с клавиатуры угла в радианах (угол от 0 до 90 градусов)
| |
− | cin >> a; ///вывод значение угла на экран
| |
− | a=(Pi*a)/180.0;
| |
− | cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
| |
− | cin >> m; ///вывод величины массы на экран
| |
− | | |
− | do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
| |
− | {
| |
− | cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
| |
− | cin >> r; ///вывод значения сопротивления на экран
| |
− | }
| |
− | while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
| |
− | | |
− | cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
| |
− | cin >> Vo; ///вывод значения скорости на экран
| |
− | | |
− | ///для движения без учёта сопротивления
| |
− | x0=0; ///обнуление переменных
| |
− | y0=0;
| |
− | x=0;
| |
− | y=0;
| |
− | | |
− | ///для движения с учётом сопротивления
| |
− | x_0=0; ///обнуление переменных
| |
− | y_0=0;
| |
− | | |
− | ///для 1го варианта метода Верле
| |
− | | |
− | Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
| |
− | Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
| |
− | | |
− | x2=0; ///обнуление переменных
| |
− | y2=0;
| |
− | x3=0;
| |
− | y3=0;
| |
− | | |
− | y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
| |
− | x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
| |
− | | |
− | ///для 2го варианта метода Верле
| |
− | | |
− | x_2=0; ///обнуление переменных
| |
− | y_2=0;
| |
− | x_3=0;
| |
− | y_3=0;
| |
− | | |
− | Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
| |
− | Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
| |
− | | |
− | y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
| |
− | x_1=-Vo*cos(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Ох
| |
− | | |
− | ofstream out("For method without resistance.txt");
| |
− | ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
| |
− | | |
− | for (int i=0; y>=0; ++i) ///цикл для подсчета координат при движении тела без учёта сопротивления
| |
− | {
| |
− | x=Vo*step*i*cos(a); ///расчет координаты тела по оси х
| |
− | y=Vo*sin(a)*i*step-(g*i*step*i*step)*0.5; ///расчет координаты тела по оси y
| |
− | | |
− | out << x << " " << y <<'\n'; ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
| |
− | }
| |
− | out.close();
| |
− | | |
− | ofstream out1 ("For method with resistance.txt");
| |
− | ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
| |
− | | |
− | for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
| |
− | {
| |
− | Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
| |
− | Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
| |
− | x_0=x0+(m/r)*Vx*(1.0 - exp((-r*i*step)/m)); ///расчет координаты тела по оси х
| |
− | y_0=y0+(m/r)*(Vy+g*(m/r))*(1.0 - exp((-r*i*step)/m))-g*i*step*(m/r); ///расчет координаты тела по оси y
| |
− | | |
− | out1 << x_0 << " " << y_0 <<'\n'; ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
| |
− | }
| |
− | out1.close();
| |
− | | |
− | ofstream out2 ("For method Verle 1.txt");
| |
− | ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
| |
− | | |
− | for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
| |
− | {
| |
− | x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
| |
− | y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
| |
− | Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
| |
− | Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
| |
− | Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
| |
− | | |
− | x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
| |
− | x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
| |
− | y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
| |
− | y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
| |
− | | |
− | out2 << x3 << " " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
| |
− | }
| |
− | out2.close();
| |
− | | |
− | ofstream out3 ("For method Verle 2.txt");
| |
− | ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
| |
− | | |
− | for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
| |
− | {
| |
− | x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
| |
− | y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
| |
− | Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
| |
− | Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
| |
− | | |
− | x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
| |
− | x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
| |
− | y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
| |
− | y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
| |
− | | |
− | out3 << x_3 << " " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
| |
− | | |
− | }
| |
− | out3.close();
| |
− | | |
− | cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
| |
− | cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
| |
− | return 0;
| |
− | }
| |
− | </syntaxhighlight>
| |
− | </div>
| |
− | | |
− | <div class="mw-collapsible mw-collapsed" style="width:100%" >
| |
− | '''[[Уманский Александр]]'''
| |
− | | |
− | '''Описание программы''': программа записывает в четыре файла результаты вычисления:
| |
− | # Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
| |
− | # Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
| |
− | # Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
| |
− | | |
− | <div class="mw-collapsible-content">
| |
− | | |
− | [[File:Methods.rar|Скачать архив]]
| |
− | | |
− | [[File:1.png]]
| |
− | | |
− | <syntaxhighlight lang="cpp" line start="1" enclose="div">
| |
− | | |
− | </syntaxhighlight>
| |
− | </div>
| |