Информатика: Движение тела в среде — различия между версиями

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
 
(не показано 12 промежуточных версий 8 участников)
Строка 1: Строка 1:
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
<div>
'''[[Лебедев Станислав]]'''  
+
'''[[Абрамов Игорь]]'''  
 +
 
 +
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
 +
 
 +
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
 +
 
 +
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
</div>
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Шарик.rar тут].
 
  
<div class="mw-collapsible-content">
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Андреева Полина]]'''
  
[[File:1.png]]
+
'''Краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл.
  
 +
''' Инструкция ''':
 +
Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
  
'''Визуализированный результат работы программы'''
+
Скачать можно  [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут].
[[File:graph.png]]
 
  
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
<div class="mw-collapsible-content">
  
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 
  
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
+
'''Визуализированный результат работы программы'''
  
Файл "'''main.cpp'''"
+
[[:File:graphAP.png]]
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
 
 +
Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;
 +
 
 +
# "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# "MyFile.txt" using 3 : 4 -  Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
 +
 
 +
 
 +
 
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <iostream>
#include <math.h>
 
#include "Vector.h"
 
#include <cstring>
 
#include <cmath>
 
#include <malloc.h>
 
 
#include <fstream>
 
#include <fstream>
 
+
#include "math.h"
 +
#include <iomanip>
 
using namespace std;
 
using namespace std;
 
+
class func
int n = 100;
 
ofstream outfile;
 
 
 
class Ball                                          //класс бросаемого тела
 
 
{
 
{
    private:
 
        double angle,m,k;                          //угол броска,масса,коэффицент сопротивления воздуха
 
        Vector3D r,v,a;                            //радиус-вектор,вектор скорости,ускорения
 
    public:
 
  
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
+
private:
        Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
+
    double speed0, angle0, step ;
        {
+
  double time;
            angle = _angle;
+
 
            r    = _r;
+
  public:
            v    = _v;
+
      double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
            a    = _a;
+
      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;///подсчет полного времени полета
         Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
+
         amount = (time/step) + 1;///количество точек для траектории
         {
+
         amountint = static_cast<int> (amount) ;
            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 SaveFile(char filename[])
         void WVTF(Vector3D v,char s[])
+
    {
 +
        double x0=0, y0=0;
 +
        double xv1=0, x1=0, y1=0, Vx1=speed0*cos(angle0),Vy1=speed0*sin(angle0), V1=speed0, yv1=0;
 +
         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++)
 
         {
 
         {
             outfile.open(s,ios :: app);
+
             ///Верле линейная зависимость
             outfile << v.x << "          " << v.y << endl;
+
            x2=2*xv2-xm2-(n/m)*step*step*Vx2;
             outfile.close();
+
            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;
  
        //"пересчет" координаты по Верле(Линейная зависмость)
+
            ///точное решение
        void changeR(Vector3D r1, double dt)
+
            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;
            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)
+
             x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
        {
+
            y1=2*yv1-ym1-(g+(n/m)*V1*Vy1)*step*step;
             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 );
+
            Vx1=(x1-xm1) / (2.0*step);
        }
+
             Vy1=(y1-ym1) / (2.0*step);
        //пересчет скорости по Верле
+
            V1=sqrt(Vx1*Vx1+Vy1*Vy1);
        void changeV(Vector3D r1,double dt)
+
            xm1=xv1;
        {
+
            xv1=x1;///запоминание предыдущего шага
             v =VS((VmV(r,r1)),1/(2*dt));
+
            ym1=yv1;
        }
+
            yv1=y1;
  
        //рассчет предыдущегт к 0ому элементу
 
        Vector3D MR1(double dt)
 
        {
 
            return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
 
        }
 
  
        //возращает координату тела
 
        Vector3D getR()
 
        {
 
            return r;
 
        }
 
  
        //рассчет времени полета
+
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";
        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);
 
 
         }
 
         }
 +
        fout.close();
 +
    }
  
 
};
 
};
 +
  
 
int main()
 
int main()
 
{
 
{
     //задание начальных параметров
+
     double V0, angle, step;
     Vector3D g = {0,-9.8,0};
+
    cout << " enter V0 = ";///введите начальную скорость
     double a,dt = 0;
+
     cin >> V0;
     char s[20];
+
    cout << " enter an angle , 0 < angle <= 90, angle = " ;///введите угол в диапозоне от 0 до 90 градусов
 +
    cin >> angle;
 +
     cout << "\n enter step ";///введите шаг, с которым будут рассчитываться координаты
 +
    cin >> step; cout << endl;
 +
     func f1(V0,angle,step);///создание траектории
 +
    f1.SaveFile("Myfile.txt");///запись в файл
  
//    cin >> dt;
 
  
     dt = 0.1;
+
     return 0;
    a = (M_PI * 30)/180;
+
}
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
+
</syntaxhighlight>
 +
</div>
 +
 
 +
<div>
 +
 
 +
'''[[Бальцер Анастасия]]'''
 +
 
 +
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
  
    double tof = b1.TimeOfFly()+1;   //единичка прибавлена,чтобы график красивым был
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
    //Без сопротивления возлуха
+
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
    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);
 
    }
 
  
 +
</div>
  
    //Верле(Линейная зависимость)
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    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,"");
+
Скачать можно  [http://tm.spbstu.ru/Файл:задача_3.zip тут].
    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);
 
    }
 
  
 +
<div class="mw-collapsible-content">
  
    //Верле (Квадратичная зависимость)
+
[[File:формулы.png]]
    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");
+
[[File:graph1.png]]
    outfile.open(s, ios :: trunc);
+
 
    outfile.close();
+
Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01;
    r1 = b4.MR1(dt);
+
 
    for (double i = 0; i <= 20; i += dt)
+
# "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
    {
+
# "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
        rp = b4.getR();
+
# "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
        b4.writePosToFile(s);
+
# "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
        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">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
#ifndef VECTOR_H_INCLUDED
+
#include <iostream>
#define VECTOR_H_INCLUDED
+
#include <locale.h>
 +
#include <math.h>
 +
#include <fstream>
 +
#include<iomanip>
 +
#include <cmath>
 +
 
 +
using namespace std;
  
struct Vector3D
+
class fly ///создаем класс полета тела
 
{
 
{
  double x,y,z;
 
};
 
  
Vector3D VmV(Vector3D v1,Vector3D v2)              //векторное вычитание
+
private: ///объявляем тип переменных в привате
{
+
     double Vo, Agrad, Brad, time, step, amountdouble; ///Vo-начальная скорость тела; Agrad-угол, под которым летит тело, в градусах;
     Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
+
                                                      ///Brad-угол, под которым летит тело, в радианах; time-время полета тела; step-шаг;
    return v;
+
                                                      ///amountdouble-количество точек (типа double)
};
 
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)              //скалярное умножение
+
public: ///объявляем переменные в паблике
{
+
    int amount; ///amoun-количество точек (типа int)
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
 
}
 
  
Vector3D VxV(Vector3D v1,Vector3D v2)               //векторное умножение
+
fly (double _step, double _Agrad, double _Vo):step(_step),Agrad(_Agrad),Vo(_Vo) ///создаем конструктор функции с объявлением переменных
 
{
 
{
  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)
+
    double g=9.8; ///объявляем тип и значение переменной g(ускорение свободного падения)
{
+
    Brad=3.14159*Agrad/180.0; ///переводим значение угла из градусов в радианы
  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)
+
    time=2*Vo*sin(Brad)/g; ///рассчитываем время полета тела
{
+
     amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом
     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
+
     amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
     return v;
 
}
 
  
double Length(Vector3D v1)
 
{
 
    return sqrt(VV(v1,v1));
 
 
}
 
}
 
+
void zapis (char Zapis[]) ///создаем функцию записи
Vector3D MakeVector(double x,double y,double z)
 
 
{
 
{
     Vector3D v = {x,y,z};
+
     double g=9.8, m=1, n=0.05; ///объявляем тип и значения переменных g (ускорение свободного падения), m (масса тела), n(коэффициэнт сопротивления)
     return v;
+
     double Xb, Yb; ///объявляем тип переменных для полёта тела без сопротивления ветра Xb(координата тела по Х), Yb(координата тела по У)
}
+
    double V=Vo, Vxv=Vo*cos(Brad), Vyv=Vo*sin(Brad), Xo=0, Yo=0, Xv=0, Yv=0, Y_1=Yo-Vo*sin(Brad)*step, X_1=Xo-Vo*cos(Brad)*step, Y=0, X=0;
 +
          ///объявляем тип переменных для метода ВерлеI V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 +
          ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 +
          ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 +
          ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 +
          ///X (координата тела на n-ом шаге на оси Х);
 +
    double Vxv2=Vo*cos(Brad), Vyv2=Vo*sin(Brad), Xo2=0, Yo2=0, Xv2=0, Yv2=0, Y_12=Yo2-Vo*sin(Brad)*step, X_12=Xo-Vo*cos(Brad)*step, Y2=0, X2=0;
 +
          ///объявляем тип переменных для метода ВерлеII V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 +
          ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 +
          ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 +
          ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 +
          ///X (координата тела на n-ом шаге на оси Х);
 +
    double Yt=0, Xt=0, Yot=0, Xot=0, Voxt=Vo*cos(Brad), Voyt=Vo*sin(Brad);
  
Vector3D MakeVector(double length,double angle)
+
    ofstream outfile("Zapis.txt"); ///запись элементов функции в фаил "Zapis.txt"
{
+
    outfile<<setw(20)<<"Xb"<<setw(20)<<"Yb"<<setw(20)<<"Xt"<<setw(20)<<"Yt"<<setw(20)<<"Xv"<<setw(20)<<"Yv"<<setw(20)<<"Xv2"<<setw(20)<<"Yv2"<<" \n"; ///вывод на экран по столбцам
    Vector3D v = {length * cos(angle), length * sin(angle),0};
+
                                                                                  ///X (координата тела на оси Х без ветра),
    return v;
+
                                                                                  ///Y (координата тела на оси У без ветра),
}
+
                                                                                  ///Xv (координата тела на оси Х с ветром для метода Верле),
 +
                                                                                  ///Yv (координата тела на оси У с ветром для метода Верле)
 +
                                                                                  ///setw() размер столбиков
  
double Proection(Vector3D base, Vector3D dir)
+
    for (int l=0; Yb>=0; ++l) ///создаем цикл от 0 до тех пор пока У больше нуля
{
+
    {
    return (VV(base,dir)/Length(base));
+
        outfile<<setw(20)<<Xb<<setw(20)<<Yb<<setw(20)<<Xt<<setw(20)<<Yt<<setw(20)<<Xv<<setw(20)<<Yv<<setw(20)<<Xv2<<setw(20)<<Yv2<<" \n";
}
+
            ///вывод на экран по столбцам Xv, Yv;
#endif // VECTOR_H_INCLUDED
 
</syntaxhighlight>
 
</div>
 
  
 +
        ///полёт без ветра
 +
        Xb=Vo*cos(Brad)*l*step;
 +
        Yb=Vo*sin(Brad)*l*step-(9.8*l*step*l*step*0.5);
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
        ///точный метод
'''[[Белоусова Екатерина]]'''
+
        Xt=Xot+(m/n)*Voxt*(1.0 - exp((-n*l*step)/m));
 +
        Yt=Yot+(m/n)*(Voyt+g*(m/n))*(1.0 - exp((-n*l*step)/m))-g*l*step*(m/n);
  
'''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки.  
+
        ///метод Верле I
 +
        Xv=2*X-X_1-(n/m)*V*Vxv*step*step; ///расчитываем координату Х в момент времени t для метода Верле
 +
        Yv=2*Y-Y_1-(g+(n/m)*V*Vyv)*step*step; ///расчитываем координату У в момент времени t для метода Верле
 +
        Vxv=(Xv-X_1)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
 +
        Vyv=(Yv-Y_1)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 +
        V=sqrt(Vxv*Vxv+Vyv*Vyv); ///рассчитываем скорость тела по модулю
 +
        X_1=X; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 +
        X=Xv;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 +
        Y_1=Y; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 +
        Y=Yv;  ///присваиваем значению координаты У на n-ом шаге значение координаты У
  
Программа записывает в один файл результаты вычисления:
+
        ///метод Верле II
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
        Xv2=2*X2-X_12-(n/m)*Vxv2*step*step; ///расчитываем координату Х в момент времени t для метода Верле
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
        Yv2=2*Y2-Y_12-(g+(n/m)*Vyv2)*step*step; ///расчитываем координату У в момент времени t для метода Верле
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
        Vxv2=(Xv2-X_12)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
        Vyv2=(Yv2-Y_12)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 +
        X_12=X2; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 +
        X2=Xv2;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 +
        Y_12=Y2; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 +
        Y2=Yv2; ///присваиваем значению координаты У на n-ом шаге значение координаты У
  
Скачать можно  [http://tm.spbstu.ru/Файл:задача_3.zip тут].
+
    }
  
<div class="mw-collapsible-content">
+
    outfile.close();
  
[[File:формулы.png]]
+
}
  
'''Визуализированный результат работы программы'''
+
};
[[File:graph1.png]]
 
  
Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01;
+
int main()
 +
{
  
# "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
    setlocale(LC_ALL,"RUS"); ///функция, позволяющая с++ распознавать русский язык
# "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
 
# "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
    double Vo, Agrad, Brad, time, step; ///объявляем тип переменных Vo (начальная скорость тела), Agrad (угол, под которым летит тело, в градусах);
 +
                                        ///Brad (угол, под которым летит тело, в радианах); time (время полета тела); step (шаг)
 +
    cout<<"Задайте начальную скорость тела в м/с: Vo="; ///на экран выводится сообщение с просьюой задать начальную скорость тела
 +
    cin>>Vo; ///пользователь вводит начальную скорость тела
 +
    cout<<'\n'<<"Задайте в градусах угол, под которым брошено тело (угол должен принимать значения от 0 до 90): a=";
 +
                                                        ///на экран выводится сообщение с просьбой задать угол, под которым летит тело, в градусах
 +
    cin>>Agrad; ///пользователь вводит угол, под которым летит тело
 +
    cout<<'\n'<<"Задайте шаг (шаг должен быть очень маленьким): шаг="; ///на экран выводится сообщение с просьбой ввести шаг
 +
    cin>>step; ///пользователь вводит шаг
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    fly X(step,Agrad,Vo); ///объявление коструктора, создание функции Х, зависящей от step,Agrad,Vo
#include <iostream>
+
    X.zapis("координаты.txt"); ///запись элементов функции в файл
#include <locale.h>
 
#include <math.h>
 
#include <fstream>
 
#include<iomanip>
 
#include <cmath>
 
  
using namespace std;
+
    return 0; ///конец программы
  
class fly ///создаем класс полета тела
+
}
{
+
</syntaxhighlight>
 +
</div>
  
private: ///объявляем тип переменных в привате
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    double Vo, Agrad, Brad, time, step, amountdouble; ///Vo-начальная скорость тела; Agrad-угол, под которым летит тело, в градусах;
+
'''[[Васильева Анастасия]]'''
                                                      ///Brad-угол, под которым летит тело, в радианах; time-время полета тела; step-шаг;
 
                                                      ///amountdouble-количество точек (типа double)
 
  
public: ///объявляем переменные в паблике
+
'''Описание программы''': пользователь вводит начальную скорость полета, угол падения и шаг, с которым будут рассчитаны точки.
    int amount; ///amoun-количество точек (типа int)
 
  
fly (double _step, double _Agrad, double _Vo):step(_step),Agrad(_Agrad),Vo(_Vo) ///создаем конструктор функции с объявлением переменных
+
Программа записывает в один файл результаты вычисления:
{
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные при численном интегрировании - метод Эйлера;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  
    double g=9.8; ///объявляем тип и значение переменной g(ускорение свободного падения)
+
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
    Brad=3.14159*Agrad/180.0; ///переводим значение угла из градусов в радианы
 
  
    time=2*Vo*sin(Brad)/g; ///рассчитываем время полета тела
 
    amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом
 
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
 
  
}
+
<div class="mw-collapsible-content">
void zapis (char Zapis[]) ///создаем функцию записи
 
{
 
    double g=9.8, m=1, n=0.05; ///объявляем тип и значения переменных g (ускорение свободного падения), m (масса тела), n(коэффициэнт сопротивления)
 
    double Xb, Yb; ///объявляем тип переменных для полёта тела без сопротивления ветра Xb(координата тела по Х), Yb(координата тела по У)
 
    double V=Vo, Vxv=Vo*cos(Brad), Vyv=Vo*sin(Brad), Xo=0, Yo=0, Xv=0, Yv=0, Y_1=Yo-Vo*sin(Brad)*step, X_1=Xo-Vo*cos(Brad)*step, Y=0, X=0;
 
          ///объявляем тип переменных для метода ВерлеI V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 
          ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 
          ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 
          ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 
          ///X (координата тела на n-ом шаге на оси Х);
 
    double Vxv2=Vo*cos(Brad), Vyv2=Vo*sin(Brad), Xo2=0, Yo2=0, Xv2=0, Yv2=0, Y_12=Yo2-Vo*sin(Brad)*step, X_12=Xo-Vo*cos(Brad)*step, Y2=0, X2=0;
 
          ///объявляем тип переменных для метода ВерлеII V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 
          ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 
          ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 
          ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 
          ///X (координата тела на n-ом шаге на оси Х);
 
    double Yt=0, Xt=0, Yot=0, Xot=0, Voxt=Vo*cos(Brad), Voyt=Vo*sin(Brad);
 
  
    ofstream outfile("Zapis.txt"); ///запись элементов функции в фаил "Zapis.txt"
 
    outfile<<setw(20)<<"Xb"<<setw(20)<<"Yb"<<setw(20)<<"Xt"<<setw(20)<<"Yt"<<setw(20)<<"Xv"<<setw(20)<<"Yv"<<setw(20)<<"Xv2"<<setw(20)<<"Yv2"<<" \n"; ///вывод на экран по столбцам
 
                                                                                  ///X (координата тела на оси Х без ветра),
 
                                                                                  ///Y (координата тела на оси У без ветра),
 
                                                                                  ///Xv (координата тела на оси Х с ветром для метода Верле),
 
                                                                                  ///Yv (координата тела на оси У с ветром для метода Верле)
 
                                                                                  ///setw() размер столбиков
 
  
    for (int l=0; Yb>=0; ++l) ///создаем цикл от 0 до тех пор пока У больше нуля
+
'''Визуализированный результат работы программы'''
    {
+
[[File:graphick.png]]
        outfile<<setw(20)<<Xb<<setw(20)<<Yb<<setw(20)<<Xt<<setw(20)<<Yt<<setw(20)<<Xv<<setw(20)<<Yv<<setw(20)<<Xv2<<setw(20)<<Yv2<<" \n";
 
            ///вывод на экран по столбцам Xv, Yv;
 
  
        ///полёт без ветра
+
Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;
        Xb=Vo*cos(Brad)*l*step;
 
        Yb=Vo*sin(Brad)*l*step-(9.8*l*step*l*step*0.5);
 
  
        ///точный метод
+
# "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
        Xt=Xot+(m/n)*Voxt*(1.0 - exp((-n*l*step)/m));
+
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
        Yt=Yot+(m/n)*(Voyt+g*(m/n))*(1.0 - exp((-n*l*step)/m))-g*l*step*(m/n);
+
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
 +
# "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
  
        ///метод Верле I
 
        Xv=2*X-X_1-(n/m)*V*Vxv*step*step; ///расчитываем координату Х в момент времени t для метода Верле
 
        Yv=2*Y-Y_1-(g+(n/m)*V*Vyv)*step*step; ///расчитываем координату У в момент времени t для метода Верле
 
        Vxv=(Xv-X_1)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
 
        Vyv=(Yv-Y_1)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 
        V=sqrt(Vxv*Vxv+Vyv*Vyv); ///рассчитываем скорость тела по модулю
 
        X_1=X; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 
        X=Xv;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 
        Y_1=Y; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 
        Y=Yv;  ///присваиваем значению координаты У на n-ом шаге значение координаты У
 
  
        ///метод Верле II
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
        Xv2=2*X2-X_12-(n/m)*Vxv2*step*step; ///расчитываем координату Х в момент времени t для метода Верле
 
        Yv2=2*Y2-Y_12-(g+(n/m)*Vyv2)*step*step; ///расчитываем координату У в момент времени t для метода Верле
 
        Vxv2=(Xv2-X_12)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
 
        Vyv2=(Yv2-Y_12)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 
        X_12=X2; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 
        X2=Xv2;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 
        Y_12=Y2; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 
        Y2=Yv2;  ///присваиваем значению координаты У на n-ом шаге значение координаты У
 
  
    }
+
#include <iostream>
 +
#include <fstream>
 +
#include <iomanip>
 +
#include <time.h>
 +
#include <conio.h>
 +
#include <stdlib.h>
 +
#include <math.h>
 +
#include <cstring>
 +
using namespace std;
  
    outfile.close();
+
class pad ///создаем класс
 
 
}
 
 
 
};
 
 
 
int main()
 
 
{
 
{
 +
private: ///в закрытом доступе
 +
    double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
 +
    double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
 +
    int Size; ///размер массива- сколько точек считать в первом способе
 +
    double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
  
     setlocale(LC_ALL,"RUS"); ///функция, позволяющая с++ распознавать русский язык
+
     void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
 +
    {
 +
        g = 9.8;///коэфф свободного падения
 +
        float t = 0; ///время
 +
        X = new double [Size];///создаем массив для координат по х для простого падения
 +
        E = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
 +
        X[0] = 0; ///задаем значение по х в нуле
 +
        E[0] = 0 ; ///задаем значение по х в нуле по эйлеру
 +
        for (int i = 1; i < Size; i++) ///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
 +
        {
 +
            t += shag; ///каждый раз прибавляем по времени шаг
 +
            X[i] = v * cos(a) * t; ///координаты по х для простого падения
 +
            E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
 +
        }
 +
    }
  
     double Vo, Agrad, Brad, time, step; ///объявляем тип переменных Vo (начальная скорость тела), Agrad (угол, под которым летит тело, в градусах);
+
     void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
                                        ///Brad (угол, под которым летит тело, в радианах); time (время полета тела); step (шаг)
+
    {
    cout<<"Задайте начальную скорость тела в м/с: Vo="; ///на экран выводится сообщение с просьюой задать начальную скорость тела
+
        g = 9.8; ///коэфф свободного падения
    cin>>Vo; ///пользователь вводит начальную скорость тела
+
        double Vy; /// переменная для значение скорости по у для метода эйлера
    cout<<'\n'<<"Задайте в градусах угол, под которым брошено тело (угол должен принимать значения от 0 до 90): a=";
+
        float t = 0; ///время
                                                        ///на экран выводится сообщение с просьбой задать угол, под которым летит тело, в градусах
+
        Y = new double [Size];///создаем массив для координат по у для простого падения
    cin>>Agrad; ///пользователь вводит угол, под которым летит тело
+
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
    cout<<'\n'<<"Задайте шаг (шаг должен быть очень маленьким): шаг="; ///на экран выводится сообщение с просьбой ввести шаг
+
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
    cin>>step; ///пользователь вводит шаг
+
        Y[0] = 0;///задаем значение по у в нуле
 +
        G[0] = 0;///задаем значение по у в нуле по эйлеру
 +
        for (int i = 1; i < Size; i++)///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
 +
        {
 +
            t += shag; ///каждый раз прибавляем по времени шаг
 +
            Y[i] = v * sin (a) *t - (g * t * t) * 0.5; ///координаты по у для простого падения
 +
            Vy -= g * shag; ///значение скорости по у для метода эйлера
 +
            G[i] = G[i-1] + Vy  * shag;///у из интегрирования по эйлеру
 +
        }
 +
    }
  
     fly X(step,Agrad,Vo); ///объявление коструктора, создание функции Х, зависящей от step,Agrad,Vo
+
     void SetVerle() ///функция для метода верле
    X.zapis("координаты.txt"); ///запись элементов функции в файл
+
    {
 
+
        double k = 0.1, m = 0.5; ///коэфф сопротивления водуха, масса тела
     return 0; ///конец программы
+
        g = 9.8; /// коэфф свободного падения
 
+
        uint32_t Size1 = 1000000.0; ///размер массива
}
+
        S = new double [Size1]; ///создаем массив для значений по х для метода верле
</syntaxhighlight>
+
        Z = new double [Size1]; ///создаем массив для значений по у для метода верле
</div>
+
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
 
+
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
 
+
        S[1] = 0; ///значение х метод верле
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
        S[0] = -vx * shag; ///значение в нуле
'''[[Васильева Анастасия]]'''
+
        Z[1] = 0; ///значение у метод верле
 +
        Z[0] = -vy * shag; ///значение в нуле
 +
        for (int i = 0; i < Size1-2; i++) ///задаем цикл
 +
        {
 +
            S[i+2] = 2.0 * S[i+1] - S[i] - (k / m) * v * vx * shag * shag;///значения по х для верле
 +
            vx = 0.5 * ( 1.0 / shag )* ( S[i+2] - S[i]);///считаем значения скорости по оси х
 +
            Z[i+2] = 2.0 * Z[i+1] - Z[i] - ( g + (k / m) * v * vy ) * shag * shag;///значения по х для верле
 +
            vy = 0.5 * ( 1.0 / shag )* ( Z[i+2] - Z[i]);///считаем значения скорости по оси х
 +
            v = sqrt (vx * vx + vy * vy); ///модуль общей скорости
 +
        }
 +
    }
 +
    void SetVerleLast() ///функция для точного метода верле
 +
     {
 +
        double k = 0.1, m = 0.5;///коэфф сопротивления водуха, масса тела
 +
        g = 9.8; /// коэфф свободного падения
 +
        uint32_t Size2 = 1000000.0; ///размер массива
 +
        float t = 0; ///время
 +
        V = new double [Size2]; ///создаем массив для значений по х для точного метода верле
 +
        U = new double [Size2]; ///создаем массив для значений по у для точного метода верле
 +
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
 +
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
 +
        ///double e = 2.7 ;///значение экспоненты
 +
        V[0] = 0; ///значение х точный метод верле
 +
        U[0] = 0; ///значение у точный метод верле
 +
        for (int i = 1; i < Size2; i++)
 +
        {
 +
            t += shag; ///увеличиваем время на шаг
 +
            V[i] = vx * (m / k) * (1.0 - exp(((-k) / m) * t)); ///значения по х для точного верле
 +
            U[i] = (m / k) * (vy +  g * (m / k)) * (1.0 -  (exp(((-k) / m) * t))) - g * t * (m / k);///значения по х для точного верле
 +
        }
 +
    }
  
'''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки.  
+
public: ///в открытом
 +
    pad()
 +
    {
 +
        X = 0; ///зануляем значения
 +
        Y = 0;
 +
        Size = 0;
 +
        v = 0;
 +
        shag = 0;
 +
        b = 0;
 +
    }
 +
    pad(double _v, double _shag, double _b) ///конструктор с параметрами
 +
    {
 +
        pi = M_PI; ///значение числа пи
 +
        g = 9.8; ///коэфф свободного падения
 +
        v = _v;/// присваиваем значения переменных значению параметров в конструкторе
 +
        shag = _shag;
 +
        b = _b;
 +
        a = (pi * b) / 180.0 ; ///вычисляем значение угла в радианах
 +
        double t = (2.0 * v * sin(a)) / g; /// считаем значение времени
 +
        Size = abs( t / shag )+1;///ищем значение размера массива
 +
        SetX(); ///вызываем функции зависящие от параметров конструктора
 +
        SetY();
 +
        SetVerle();
 +
        SetVerleLast();
 +
    }
  
Программа записывает в один файл результаты вычисления:
+
    void FilePrint() ///функция записи в файл
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
    {
# Координаты, полученные при численном интегрировании - метод Эйлера;
+
        ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
        fout << "X:    " << "    Y:    " << "    E:  " << "  G:  " << "  S:  " << "  Z:  "<< "  V:  "<< "    U:   "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
        for (int i = 0; i < Size; i++) ///цикл
 +
        fout << X[i] << "    " << Y[i] << "    " << E[i] << "    "  << G[i] << "  " << S[i] << "  " << Z[i] << "  " << V[i] <<"    "<< U[i] <<"\n"; ///забивает сами значения массивов
 +
        fout.close();///закрываем файл
 +
    };
 +
};
  
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
+
int main()/// основная функция
 +
{
 +
    double shag, b, v; ///шаг, угол в градусах, скорость начальная
 +
    cout << "vvedite v "; ///просим пользователя ввести значение скорости начальной
 +
    cin >> v; ///считываем начальную скорость
 +
    cout << "vvedite ygol ";///просим пользователя ввести угол в градусах
 +
    cin >> b;/// считываем угол
 +
    cout << "vvedite shag ";///просим пользователя ввести шаг по времени
 +
    cin >> shag; ///считываем значение шага
 +
    pad F1(v, shag, b); ///объявление коструктора, создание функции F1 с переменными v, shag, b
 +
    F1.FilePrint(); ///вызываем функцию для записи файла
 +
}
 +
</syntaxhighlight>
 +
</div>
  
 +
'''[[Гильманов Илья]]'''
  
<div class="mw-collapsible-content">
+
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 +
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  
 +
Скачать можно [[http://mech.spbstu.ru/File:Движение_тела_в_среде.rar тут]]
  
'''Визуализированный результат работы программы'''
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
[[File:graphick.png]]
+
'''[[Демченко Артём]]'''
 +
 
 +
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;
+
''' Инструкция ''':
 +
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
  
# "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
 
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
 
# "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
<div class="mw-collapsible-content">
 +
 +
 +
 +
'''Визуализированный результат работы программы'''
 +
 +
[[:File:Throws.png]]
  
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
 
#include <iostream>
 
#include <iostream>
 +
#include <math.h>
 +
#include <iomanip>
 
#include <fstream>
 
#include <fstream>
#include <iomanip>
 
#include <time.h>
 
 
#include <conio.h>
 
#include <conio.h>
#include <stdlib.h>
+
#include <stdio.h>
#include <math.h>
+
 
#include <cstring>
+
 
 
using namespace std;
 
using namespace std;
  
class pad ///создаем класс
+
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
 +
 
 +
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
 
{
 
{
private: ///в закрытом доступе
+
     FILE *Coord;
     double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
+
  Coord = fopen ("Throws Without Resistance.txt", "w");
    double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
+
    double X = 0, Y = 0; // Координаты начала
    int Size; ///размер массива- сколько точек считать в первом способе
+
 
    double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
+
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
 +
    {
  
    void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
+
      X =  Vo*t*cos(alpha);
    {
+
      Y =  Vo*t*sin(alpha) - (g*t*t)*0.5;
        g = 9.8;///коэфф свободного падения
+
      t+= dt;
        float t = 0; ///время
+
    if (Y > Yo )
         X = new double [Size];///создаем массив для координат по х для простого падения
+
         fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
        E = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
+
    else
         X[0] = 0; ///задаем значение по х в нуле
+
         fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
        E[0] = 0 ; ///задаем значение по х в нуле по эйлеру
+
    }
        for (int i = 1; i < Size; i++) ///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
+
 
        {
+
}
            t += shag; ///каждый раз прибавляем по времени шаг
+
 
            X[i] = v * cos(a) * t; ///координаты по х для простого падения
+
int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
            E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
+
{                                                                                         // для линейной зависимости
        }
+
    FILE *Coord;
     }
+
  Coord = fopen ("ExactForm.txt", "w");
 +
     double X, Y = 0, Vx, Vy;
  
     void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
+
     while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
    {
+
    {
        g = 9.8; ///коэфф свободного падения
+
 
        double Vy; /// переменная для значение скорости по у для метода эйлера
+
      X = ((m*Vx)/R) * (1 - exp(((-1)*R*t)/m));
        float t = 0; ///время
+
      Y = (m/R)*((Vy + (g*m)/R)*(1 - exp((-1)*R*t/m))) - (g*t*m)/R;
        Y = new double [Size];///создаем массив для координат по у для простого падения
+
      Vx = Vo*cos(alpha);
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
+
      Vy = Vo*sin(alpha);
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
+
      t+= dt;
        Y[0] = 0;///задаем значение по у в нуле
+
    if (Y > Yo )
        G[0] = 0;///задаем значение по у в нуле по эйлеру
+
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
        for (int i = 1; i < Size; i++)///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
+
    else
        {
+
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
            t += shag; ///каждый раз прибавляем по времени шаг
+
      }
            Y[i] = v * sin (a) *t - (g * t * t) * 0.5; ///координаты по у для простого падения
+
}
            Vy -= g * shag; ///значение скорости по у для метода эйлера
 
            G[i] = G[i-1] + Vy  * shag;///у из интегрирования по эйлеру
 
        }
 
    }
 
  
    void SetVerle() ///функция для метода верле
+
int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
    {
+
{                                                                                                   // для Квадратичной зависимости сопротивления от скорости
        double k = 0.1, m = 0.5; ///коэфф сопротивления водуха, масса тела
+
    FILE *Coord;
        g = 9.8; /// коэфф свободного падения
+
  Coord = fopen ("VerleSq.txt", "w");
        uint32_t Size1 = 1000000.0; ///размер массива
+
 
        S = new double [Size1]; ///создаем массив для значений по х для метода верле
+
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
        Z = new double [Size1]; ///создаем массив для значений по у для метода верле
+
                                                                  // Xop, Yop - вспомогательные координаты для (-1)-го шага
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
 
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
 
        S[1] = 0; ///значение х метод верле
 
        S[0] = -vx * shag; ///значение в нуле
 
        Z[1] = 0; ///значение у метод верле
 
        Z[0] = -vy * shag; ///значение в нуле
 
        for (int i = 0; i < Size1-2; i++) ///задаем цикл
 
        {
 
            S[i+2] = 2.0 * S[i+1] - S[i] - (k / m) * v * vx * shag * shag;///значения по х для верле
 
            vx = 0.5 * ( 1.0 / shag )* ( S[i+2] - S[i]);///считаем значения скорости по оси х
 
            Z[i+2] = 2.0 * Z[i+1] - Z[i] - ( g + (k / m) * v * vy ) * shag * shag;///значения по х для верле
 
            vy = 0.5 * ( 1.0 / shag )* ( Z[i+2] - Z[i]);///считаем значения скорости по оси х
 
            v = sqrt (vx * vx + vy * vy); ///модуль общей скорости
 
        }
 
    }
 
    void SetVerleLast() ///функция для точного метода верле
 
     {
 
        double k = 0.1, m = 0.5;///коэфф сопротивления водуха, масса тела
 
        g = 9.8; /// коэфф свободного падения
 
        uint32_t Size2 = 1000000.0; ///размер массива
 
        float t = 0; ///время
 
        V = new double [Size2]; ///создаем массив для значений по х для точного метода верле
 
        U = new double [Size2]; ///создаем массив для значений по у для точного метода верле
 
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
 
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
 
        ///double e = 2.7 ;///значение экспоненты
 
        V[0] = 0; ///значение х точный метод верле
 
        U[0] = 0; ///значение у точный метод верле
 
        for (int i = 1; i < Size2; i++)
 
        {
 
            t += shag; ///увеличиваем время на шаг
 
            V[i] = vx * (m / k) * (1.0 - exp(((-k) / m) * t)); ///значения по х для точного верле
 
            U[i] = (m / k) * (vy +  g * (m / k)) * (1.0 -  (exp(((-k) / m) * t))) - g * t * (m / k);///значения по х для точного верле
 
        }
 
    }
 
  
public: ///в открытом
+
    Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
     pad()
+
    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 получаем все необходимые данные для выполнения алгоритма.
 
     {
 
     {
        X = 0; ///зануляем значения
+
    Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
        Y = 0;
+
    Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
        Size = 0;
+
    Ynext = 2.0*Y - Yprev - (g +(R/m)*V*Vy)*(dt*dt);
        v = 0;
+
    Vy = (1.0/(2.0*dt))*(Ynext - Yprev);
        shag = 0;
+
    V = sqrt((Vx*cos(alpha)*Vx*cos(alpha)) + (Vy*sin(alpha) - g*dt)*(Vy*sin(alpha) - g*dt));
        b = 0;
+
    if (Ynext > Yo )
    }
+
         fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
    pad(double _v, double _shag, double _b) ///конструктор с параметрами
+
    else
    {
+
 
        pi = M_PI; ///значение числа пи
+
      fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
        g = 9.8; ///коэфф свободного падения
+
 
        v = _v;/// присваиваем значения переменных значению параметров в конструкторе
+
    Xprev = X;
        shag = _shag;
+
    X = Xnext;
        b = _b;
+
    Yprev = Y;
        a = (pi * b) / 180.0 ; ///вычисляем значение угла в радианах
+
    Y = Ynext;
        double t = (2.0 * v * sin(a)) / g; /// считаем значение времени
 
        Size = abs( t / shag )+1;///ищем значение размера массива
 
        SetX(); ///вызываем функции зависящие от параметров конструктора
 
         SetY();
 
        SetVerle();
 
        SetVerleLast();
 
 
     }
 
     }
  
    void FilePrint() ///функция записи в файл
+
}
     {
+
int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
        ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
+
{                                                                                                  // для линейной зависимости сопротивления от скорости
        fout << "X:    " << "    Y:    " << "    E:  " << "  G:  " << "  S:  " << "  Z:  "<< "  V:  "<< "    U:    "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
+
     FILE *Coord;
        for (int i = 0; i < Size; i++) ///цикл
+
  Coord = fopen ("VerleL.txt", "w");
        fout << X[i] << "    " << Y[i] << "    " << E[i] << "    "  << G[i] << "  " << S[i] << "  " << Z[i] << "  " << V[i] <<"    "<< U[i] <<"\n"; ///забивает сами значения массивов
+
 
        fout.close();///закрываем файл
+
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,Yop, Xop; // Комментарии аналогичны переменным и формулам в VtrleSq
    };
 
};
 
  
int main()/// основная функция
+
    Yop = Yo - Vo*sin(alpha)*dt;
{
+
     Xop = Xo - Vo*cos(alpha)*dt;
     double shag, b, v; ///шаг, угол в градусах, скорость начальная
+
     X = Xo;
     cout << "vvedite v "; ///просим пользователя ввести значение скорости начальной
+
     Y = Yo;
     cin >> v; ///считываем начальную скорость
+
     Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
     cout << "vvedite ygol ";///просим пользователя ввести угол в градусах
+
     Vx = (1.0/(2.0*dt))*(Xnext - Xop);
     cin >> b;/// считываем угол
+
     Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
     cout << "vvedite shag ";///просим пользователя ввести шаг по времени
+
     Vy =  (1.0/(2.0*dt))*(Ynext - Yop);
     cin >> shag; ///считываем значение шага
+
     V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
    pad F1(v, shag, b); ///объявление коструктора, создание функции F1 с переменными v, shag, b
 
     F1.FilePrint(); ///вызываем функцию для записи файла
 
}
 
</syntaxhighlight>
 
</div>
 
  
 +
    fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    Xprev = X;
'''[[Андреева Полина]]'''
+
    X = Xnext;
 
+
    Yprev = Y;
'''Краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл.
+
    Y = Ynext;
  
''' Инструкция ''':
 
Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут].
+
    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;
 +
    }
  
<div class="mw-collapsible-content">
+
}
  
 +
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:graphAP.png]]
 
  
Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;
+
    FILE *Gnu;
 +
    Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
  
# "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
switch ( i )
# "MyFile.txt" using 3 : 4 -  Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
{
# "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
case 1:
# "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
+
    {
 
+
    WoutR(alpha,dt,t,Yo,Vo);
 
+
    fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
 
+
    break;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    }
#include <iostream>
+
case 2:
#include <fstream>
+
    {
#include "math.h"
+
    ExactForm(alpha,dt,t,Yo,Vo,R,m);
#include <iomanip>
+
    fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
using namespace std;
+
    break;
class func
+
    }
{
+
case 3:
 
+
    {
  private:
+
    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
     double speed0, angle0, step ;
+
    fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
  double time;
+
    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;
 +
}
  
  public:
+
</syntaxhighlight>
      double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
+
</div>
      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;///подсчет полного времени полета
 
        amount = (time/step) + 1;///количество точек для траектории
 
        amountint =  static_cast<int> (amount) ;
 
  
 +
'''[[Иванова Яна]]'''
  
    }
+
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
 +
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
  
 +
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
  
 +
<div class="mw-collapsible-content">
 +
'''Визуализированный результат работы программы'''[[File:graph.png]]
  
      void SaveFile(char filename[])
+
[[:File:graph.png]]
    {
 
        double x0=0, y0=0;
 
        double xv1=0, x1=0, y1=0, Vx1=speed0*cos(angle0),Vy1=speed0*sin(angle0), V1=speed0, yv1=0;
 
        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;
 
  
            ///точное решение
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
            x3=x0+speed0*cos(angle0)*(m/n)*(1.0-exp(-(n/m)*i*step));
+
#include <iostream>
            y3=y0+(m/n)*(speed0*sin(angle0) + g*(m/n))*(1.0-exp(-(n/m)*i*step))-g*(m/n)*i*step;
+
#include <math.h>
 +
#include <iomanip>
 +
#include <fstream>
 +
#include <conio.h>
  
            ///метод Верле, квадратичная зависимость
 
            x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
 
            y1=2*yv1-ym1-(g+(n/m)*V1*Vy1)*step*step;
 
            Vx1=(x1-xm1) / (2.0*step);
 
            Vy1=(y1-ym1) / (2.0*step);
 
            V1=sqrt(Vx1*Vx1+Vy1*Vy1);
 
            xm1=xv1;
 
            xv1=x1;///запоминание предыдущего шага
 
            ym1=yv1;
 
            yv1=y1;
 
  
 +
using namespace std;
  
 +
ofstream outfile;
  
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";
+
double perevod (double angle) //перевод из градусов в радианы
 +
{
 +
    return (angle * M_PI / 180 );
 +
}
  
        }
 
        fout.close();
 
    }
 
  
};
+
int main()
 +
{
 +
    //объявление переменных и задание начальных значений
 +
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
 +
    m = 1 , dt = 0.1 , g = 9.8,t = 0,
 +
    ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
  
 +
    alpha = perevod (ugol);
  
int main()
+
     //точное решение для случая движения без сопротивления воздуха
{
+
     Y = Yo;
    double V0, angle, step;
+
     X = Xo;
     cout << " enter V0 = ";///введите начальную скорость
 
     cin >> V0;
 
     cout << " enter an angle , 0 < angle <= 90, angle = " ;///введите угол в диапозоне от 0 до 90 градусов
 
    cin >> angle;
 
    cout << "\n enter step ";///введите шаг, с которым будут рассчитываться координаты
 
    cin >> step; cout << endl;
 
    func f1(V0,angle,step);///создание траектории
 
    f1.SaveFile("Myfile.txt");///запись в файл
 
  
 +
    outfile.open("1.txt");
  
     return 0;
+
     while (Y >= Yo)
}
+
    {
</syntaxhighlight>
+
        X = Xo + Vo * cos(alpha) * t;
</div>
+
        Vx = Vo * cos(alpha);
 +
        Y = Yo + Vo * sin(alpha) * t  - 0.5 * g * t * t;
 +
        Vy = Vo * sin(alpha) - g * t;
 +
        t += dt;
  
 +
        outfile << X << ' ' << Y << endl;
 +
    }
 +
    outfile.close();
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    //начальные условия для квадратичной зависимости (метод Верле)
'''[[Иванова Яна]]'''
+
    Yprev = Yo - Vo*sin(alpha)*dt;
 +
    Xprev = Xo - Vo*cos(alpha)*dt;
 +
    X = Xo;
 +
    Y = Yo;
 +
    V = Vo;
 +
    Vx = Vo * cos(alpha);
 +
    Vy = Vo * sin(alpha);
  
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
+
    outfile.open("2.txt");
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
 
  
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
+
    while (Y >= Yo)
 +
    {
 +
        Xnext = 2.0 * X - Xprev - (R / m) * V * Vx * (dt * dt);
 +
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 +
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * V * Vy) * (dt * dt);
 +
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 +
        V = sqrt(Vy*Vy + Vx*Vx );
 +
        outfile << X << ' ' << Y << endl;
  
<div class="mw-collapsible-content">
+
        Xprev = X;
'''Визуализированный результат работы программы'''[[File:graph.png]]
+
        X = Xnext;
 +
        Yprev = Y;
 +
        Y = Ynext;
 +
    }
 +
    outfile.close();
  
[[:File:graph.png]]
+
    //начальные условия для линейной зависимости (метод Верле)
 +
    Yprev = Yo - Vo*sin(alpha)*dt;
 +
    Xprev = Xo - Vo*cos(alpha)*dt;
 +
    X = Xo;
 +
    Y = Yo;
 +
    V = Vo;
 +
    Vx = Vo * cos(alpha);
 +
    Vy = Vo * sin(alpha);
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    outfile.open("3.txt");
#include <iostream>
 
#include <math.h>
 
#include <iomanip>
 
#include <fstream>
 
#include <conio.h>
 
  
 +
    while (Y >= Yo)
 +
    {
 +
        Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
 +
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 +
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
 +
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 +
        V = sqrt(Vy*Vy + Vx*Vx );
 +
        outfile << X << ' ' << Y << endl;
  
using namespace std;
+
        Xprev = X;
 
+
        X = Xnext;
ofstream outfile;
+
        Yprev = Y;
 +
        Y = Ynext;
 +
    }
 +
    outfile.close();
  
double perevod (double angle) //перевод из градусов в радианы
+
     //точное решения для линейной зависимости
{
 
    return (angle * M_PI / 180 );
 
}
 
 
 
 
 
int main()
 
{
 
    //объявление переменных и задание начальных значений
 
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
 
    m = 1 , dt = 0.1 , g = 9.8,t = 0,
 
    ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
 
 
 
    alpha = perevod (ugol);
 
 
 
     //точное решение для случая движения без сопротивления воздуха
 
 
     Y = Yo;
 
     Y = Yo;
 
     X = Xo;
 
     X = Xo;
 +
    t = 0;
  
     outfile.open("1.txt");
+
     outfile.open("4.txt");
  
 
     while (Y >= Yo)
 
     while (Y >= Yo)
 
     {
 
     {
        X = Xo + Vo * cos(alpha) * t;
 
 
         Vx = Vo * cos(alpha);
 
         Vx = Vo * cos(alpha);
         Y = Yo + Vo * sin(alpha) * - 0.5 * g * t * t;
+
         Vy = Vo * sin(alpha);
         Vy = Vo * sin(alpha) - g * t;
+
        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);
 
         t += dt;
 
         t += dt;
 
 
         outfile << X << ' ' << Y << endl;
 
         outfile << X << ' ' << Y << endl;
 
     }
 
     }
 
     outfile.close();
 
     outfile.close();
  
     //начальные условия для квадратичной зависимости (метод Верле)
+
     return 0;
    Yprev = Yo - Vo*sin(alpha)*dt;
+
 
    Xprev = Xo - Vo*cos(alpha)*dt;
+
}
    X = Xo;
+
 
    Y = Yo;
+
</syntaxhighlight>
    V = Vo;
+
</div>
    Vx = Vo * cos(alpha);
 
    Vy = Vo * sin(alpha);
 
  
    outfile.open("2.txt");
+
<div>
  
    while (Y >= Yo)
+
'''[[Капитанюк Светлана]]'''
    {
 
        Xnext = 2.0 * X - Xprev - (R / m) * V * Vx * (dt * dt);
 
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * V * Vy) * (dt * dt);
 
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 
        V = sqrt(Vy*Vy + Vx*Vx );
 
        outfile << X << ' ' << Y << endl;
 
  
        Xprev = X;
+
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
        X = Xnext;
 
        Yprev = Y;
 
        Y = Ynext;
 
    }
 
    outfile.close();
 
  
    //начальные условия для линейной зависимости (метод Верле)
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
    Yprev = Yo - Vo*sin(alpha)*dt;
+
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
    Xprev = Xo - Vo*cos(alpha)*dt;
+
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
    X = Xo;
+
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
    Y = Yo;
 
    V = Vo;
 
    Vx = Vo * cos(alpha);
 
    Vy = Vo * sin(alpha);
 
  
    outfile.open("3.txt");
+
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
  
    while (Y >= Yo)
+
</div>
    {
 
        Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
 
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
 
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 
        V = sqrt(Vy*Vy + Vx*Vx );
 
        outfile << X << ' ' << Y << endl;
 
  
        Xprev = X;
+
<div>
        X = Xnext;
+
'''[[Киселёв Лев]]'''
        Yprev = Y;
 
        Y = Ynext;
 
    }
 
    outfile.close();
 
  
    //точное решения для линейной зависимости
+
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
    Y = Yo;
+
#  Полет тела без сопротивления воздуха;
    X = Xo;
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
    t = 0;
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  
    outfile.open("4.txt");
+
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
 
 
    while (Y >= Yo)
 
    {
 
        Vx = Vo * cos(alpha);
 
        Vy = Vo * sin(alpha);
 
        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);
 
        t += dt;
 
        outfile << X << ' ' << Y << endl;
 
    }
 
    outfile.close();
 
 
 
    return 0;
 
 
 
}
 
 
 
</syntaxhighlight>
 
 
</div>
 
</div>
 
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
'''[[Уманский Александр]]'''  
+
'''[[Лебедев Станислав]]'''  
  
 
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
Строка 911: Строка 901:
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
 +
Скачать можно  [http://tm.spbstu.ru/Файл:Шарик.rar тут].
  
 
<div class="mw-collapsible-content">
 
<div class="mw-collapsible-content">
 
[[File:Methods.rar|Скачать архив]]
 
  
 
[[File:1.png]]
 
[[File:1.png]]
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
  
</syntaxhighlight>
+
'''Визуализированный результат работы программы'''
</div>
+
[[File:graph.png]]
  
 +
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''[[Лосева Татьяна ]]'''
 
  
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела  и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
+
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
<div class="mw-collapsible-content">
+
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
  
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
+
Файл "'''main.cpp'''"
 
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
[[File:загружено (1).png]][[:File:загружено (1).png]]
+
#include <iostream>
 +
#include <math.h>
 +
#include "Vector.h"
 +
#include <cstring>
 +
#include <cmath>
 +
#include <malloc.h>
 +
#include <fstream>
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include<iostream>
 
 
using namespace std;
 
using namespace std;
#define N 1
 
#define PI 3.14159265
 
#include <fstream>
 
#include<cmath>
 
double g=9.8;
 
double step=0.01;
 
#include<math.h>
 
  
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
int n = 100;
 +
ofstream outfile;
  
 +
class Ball                                          //класс бросаемого тела
 
{
 
{
double x,y;
+
    private:
+
        double angle,m,k;                           //угол броска,масса,коэффицент сопротивления воздуха
ofstream fout;//открытие файла
+
        Vector3D r,v,a;                             //радиус-вектор,вектор скорости,ускорения
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
+
    public:
cout<<"method1"<<endl;
 
  
  for(double t=0.01;t<N;t=t+0.01)
+
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
{
+
        Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
y=v*t*sin(r*PI/ 180)-g*t*t/2;//координата y
+
        {
x=v*t*cos(r*PI / 180);//координата х
+
            angle = _angle;
 
+
            r    = _r;
fout<<x<<"  ";//запись в файл х
+
            v    = _v;
cout<<"X="<<x<<endl;//вывод на экран
+
            a    = _a;
    fout<<y<<"    ";//запись в файл
+
        }
cout<<"Y="<<y<<endl<<endl;//вывод на экран
 
fout<<endl;
 
  }
 
}
 
 
 
void Verle1( double n,double m ,double v0,double r)//Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
{
+
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
double x,y,x0=0,y0=0,xn_1,yn_1;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
+
        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;
 +
        }
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
+
        //точная формула зависимости координаты от времени
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
+
        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 );
 +
        }
  
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
+
         //вывод положения на экран
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
+
         void writePosToScreen()
  ofstream fout;//открытие файла
+
        {
fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
+
            cout << r.x << "   " << r.y << "   " << r.z << endl;
cout<<"Verle1"<<endl<<endl;
+
        }
for(double t=0.02;t<N;t=t+step)
 
{
 
x=2*x0-xn_1-(n*vx*step*step)/m;//считаем Хn+1
 
vx=(x-xn_1)/(2*step);
 
         xn_1=x0;//для следущего шага Xn-1=Xn
 
         x0=x;//для следущего шага Xn=Xn+1
 
 
y=2*y0-yn_1-(g+(n*vy)/m)*step*step;//Yn+1
 
vy=(y-yn_1)/(2*0.01);//скорость
 
yn_1=y0;//для следущего шага Yn-1=Yn
 
y0=y;//для следущего шага Yn=Yn+1
 
    cout<<"X="<<x<<endl;
 
cout<<"Y="<<y<<endl<<endl;
 
    fout<<x<<" ";
 
fout<<y<<"  ";
 
fout<<endl;  
 
 
  
}
+
        //вывод положения в файл
}
+
        void writePosToFile(char s[])
 +
        {
 +
            outfile.open(s,ios :: app);
 +
            outfile << r.x << "          " << r.y << endl;
 +
            outfile.close();
 +
        }
  
void Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
        //вывод произвольного вектора на экран
 +
        void WVTS(Vector3D v)
 +
        {
 +
            cout.width(15);
 +
            cout << v.x;
 +
            cout.width(15);
 +
            cout << v.y;
 +
            cout.width(15);
 +
            cout << v.z << endl;
 +
        }
  
{
+
        //вывод произвольного вектора в файл
double x,y,x0=0,y0=0,xn_1,yn_1,v;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
+
        void WVTF(Vector3D v,char s[])
 +
        {
 +
            outfile.open(s,ios :: app);
 +
            outfile << v.x << "          " << v.y << endl;
 +
            outfile.close();
 +
        }
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
+
        //"пересчет" координаты по Верле(Линейная зависмость)
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
+
        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 );
 +
        }
  
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
+
        //"пересчет" координаты по Верле(Квадратичная зависимость)
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
+
        void changeRSQ(Vector3D r1, double dt)
  ofstream fout;//открытие файла
+
        {
  fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
+
            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 );
cout<<"Verle2"<<endl<<endl;
+
        }
for(double t=0.02;t<N;t=t+step)
+
        //пересчет скорости по Верле
{
+
        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);
 +
        }
  
  v=sqrt(vx*vx+vy*vy);//скорость V
+
        //возращает координату тела
 +
        Vector3D getR()
 +
        {
 +
            return r;
 +
        }
  
x=2*x0-xn_1-(n*v*vx*step*step)/m;//Xn+1
+
        //рассчет времени полета
vx=(x-xn_1)/(2*step);//скорость Vx
+
        double TimeOfFly()
         xn_1=x0;//для следущего шага Xn-1=Xn
+
        {
x0=x;//для следущего шага Xn=Xn+1
+
            return (2*Length(v)*sin(angle)/Length(a));
+
        }
y=2*y0-yn_1-(g+(n*vy*v)/m)*step*step;//Yn+1
+
 
vy=(y-yn_1)/(2*0.01);//скорость Vy
+
        //рассчет координаты по точной формуле. без сопротивления воздуха.
yn_1=y0;//для следущего шага Yn-1=Yn
+
        Vector3D position(double t)
y0=y;//для следущего шага Yn=Yn+1
+
         {
cout<<"X="<<x<<endl;
+
            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);
cout<<"Y="<<y<<endl<<endl;
+
        }
fout<<x<<" ";
+
 
fout<<y<<"  ";
+
};
fout<<endl;
 
}
 
 
}
 
  
void method4(double n,double m ,double v0,double r)//Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
int main()
 
{
 
{
double x,y,x0=0,y0=0;//x0,y0 начальные значения;
+
    //задание начальных параметров
 +
    Vector3D g = {0,-9.8,0};
 +
    double a,dt = 0;
 +
    char s[20];
 +
 
 +
//   cin >> dt;
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vx
+
    dt = 0.1;
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vy
+
    a = (M_PI * 30)/180;
 
+
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
  ofstream fout;//открытие файла
+
 
  fout.open("C:\\Users\\Light\\Desktop\\4.txt");
+
    double tof = b1.TimeOfFly()+1;   //единичка прибавлена,чтобы график красивым был
cout<<"4"<<endl<<endl;
 
for(double t=0.01;t<N;t=t+step)
 
{
 
x=x0+m*vx*(1-(exp((-1*n)*t/m)))/n;//координата х
 
 
y = y0+(m/n)*((vy + g * m / n)*(1 - exp(-1 * n * t / m))) - g * t*m/n;//координата у
 
  
//вывод в файл  и на экран
+
    //Без сопротивления возлуха
    cout<<"X="<<x<<endl;
+
    strcpy(s,"");
cout<<"Y="<<y<<endl<<endl;
+
    strcat(s, "o1.txt");
fout<<x<<" ";
+
    outfile.open(s, ios :: trunc);
fout<<y<<" ";
+
    outfile.close();
fout<<endl;  
+
    for (double i = 0; i <= tof; i += dt)
 +
    {
 +
        b1.WVTS(b1.position(i));
 +
        b1.WVTF(b1.position(i), s);
 +
    }
  
}
 
}
 
 
 
int main(void)
 
{
 
  
double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
+
    //Верле(Линейная зависимость)
 +
    dt = 0.1;
 +
    a = (M_PI * 30)/180;
 +
    Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
  
cout<<"Enter  start speed:"<<endl;
+
    strcpy(s,"");
cin>>v0;
+
    strcat(s, "o2.txt");
cout<<"Enter angle less than 90 deg:"<<endl;
+
    outfile.open(s,ios :: trunc);
cin>>r;
+
    outfile.close();
cout<<"Enter mass:"<<endl;
+
    Vector3D r1 = b2.MR1(dt),rp;
cin>>m;
+
    for (double i = 0; i <= 20; i += dt)
cout<<"Coefficient of resistance:"<<endl;
+
    {
cin>>n;
+
        rp = b2.getR();
+
        b2.writePosToFile(s);
Func(v0,r);
+
        b2.writePosToScreen();
Verle1(n,m,v0,r);
+
        b2.changeR(r1,dt);
Verle2(n,m,v0,r);
+
        b2.changeV(r1,dt);
method4(n,m,v0,r);
+
        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);
 +
    }
  
int k;
+
 
cin>>k;
+
    //Верле (Квадратичная зависимость)
return 0;
+
    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>
 
</syntaxhighlight>
</div>
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
+
Файл "'''Vector.h'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#ifndef VECTOR_H_INCLUDED
 +
#define VECTOR_H_INCLUDED
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
struct Vector3D
'''[[Степанянц Степан]]'''
+
{
 
+
  double x,y,z;
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
};
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
+
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;
 +
}
  
<div class="mw-collapsible-content">
+
double VV(Vector3D v1,Vector3D v2)              //скалярное умножение
[[File:graph239.png]]
+
{
 +
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
 +
}
  
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
+
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)
Файл "'''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;
+
     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
int u0=50;
+
    return v;
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;
+
}
a=a1*M_PI/180; //Градусы в радианы
 
t=0;
 
  
//Движение без сопротивления воздуха
+
double Length(Vector3D v1)
F.open("C:\\1.txt",ios::out);
 
while(y>=0)
 
 
{
 
{
     x=x0+u0*cos(M_PI/6)*t;
+
     return sqrt(VV(v1,v1));
    y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t;
+
}
  F<<x<<" "<<y<<endl;
 
  t=t+dt;
 
  
 +
Vector3D MakeVector(double x,double y,double z)
 +
{
 +
    Vector3D v = {x,y,z};
 +
    return v;
 
}
 
}
  
F.close();
+
Vector3D MakeVector(double length,double angle)
//Точное решение для линейной зависимости
 
F.open("C:\\2.txt",ios::out);
 
y=y0;
 
x=x0;
 
t=0;
 
while(y>=0)
 
 
{
 
{
        ux = u0 * cos(a);
+
    Vector3D v = {length * cos(angle), length * sin(angle),0};
        uy = u0 * sin(a);
+
    return v;
        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;
+
double Proection(Vector3D base, Vector3D dir)
 +
{
 +
    return (VV(base,dir)/Length(base));
 +
}
 +
#endif // VECTOR_H_INCLUDED
 +
</syntaxhighlight>
 +
</div>
  
      F << x << ' ' << y << endl;
 
  
 +
<div>
 +
'''[[Лобанов Илья]]'''
  
 +
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
  
}
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  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);
 
        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;
 
    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;
+
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
        x = xsl;
+
[[http://tm.spbstu.ru/File:phys.rar тут]]
        ypr = y;
 
        y = ysl;
 
    }
 
    F.close();
 
  
 +
</div>
  
return 0;
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Лосева Татьяна ]]'''
  
 +
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела  и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  
}
+
<div class="mw-collapsible-content">
  
 +
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
  
</syntaxhighlight>
+
[[File:загружено (1).png]][[:File:загружено (1).png]]
</div>
 
  
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include<iostream>
 +
using namespace std;
 +
#define N 1
 +
#define PI 3.14159265
 +
#include <fstream>
 +
#include<cmath>
 +
double g=9.8;
 +
double step=0.01;
 +
#include<math.h>
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
'''[[Александр Сюрис]]'''
 
  
'''Описание программы''':
+
{
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
+
double x,y;
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
+
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении          воздуха от скорости
+
ofstream fout;//открытие файла
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
+
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
+
cout<<"method1"<<endl;
Скачать можно  [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">
+
  for(double t=0.01;t<N;t=t+0.01)
[[File:Снимок.PNG]]
+
{
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
+
y=v*t*sin(r*PI/ 180)-g*t*t/2;//координата y
Файл "'''main.cpp'''"
+
x=v*t*cos(r*PI / 180);//координата х
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
 
#include <iostream>
+
fout<<x<<"   ";//запись в файл х
#include <fstream>
+
cout<<"X="<<x<<endl;//вывод на экран
#include <math.h>
+
    fout<<y<<"   ";//запись в файл
#include <cmath>
+
cout<<"Y="<<y<<endl<<endl;//вывод на экран
using namespace std;
+
fout<<endl;
int o;
+
  }
double v,a,m,k;
+
}
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
+
 
 +
void Verle1( double n,double m ,double v0,double r)//Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  
 +
{
 +
double x,y,x0=0,y0=0,xn_1,yn_1;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
  
 +
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
 +
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
  
int rez_1(double v, double a)
+
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
{
+
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
    fout<<"---------------Первый режим-------------------------"<<endl;
+
  ofstream fout;//открытие файла
    fout<<" T=0 x=0 y=0";
+
fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
    fout<<endl;
+
cout<<"Verle1"<<endl<<endl;
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
+
for(double t=0.02;t<N;t=t+step)
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
+
{
    V0y=v*sin(a/180*M_PI);
+
x=2*x0-xn_1-(n*vx*step*step)/m;//считаем Хn+1
    Ty=2*V0y/g;//время полета
+
vx=(x-xn_1)/(2*step);
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
+
        xn_1=x0;//для следущего шага Xn-1=Xn
    {
+
        x0=x;//для следущего шага Xn=Xn+1
        x=x+V0x*t;               //ф-лы для рассчета x и y в данный момент времени
+
        y=y+V0y*t-g*pow(t,2)/2;
+
y=2*y0-yn_1-(g+(n*vy)/m)*step*step;//Yn+1
 +
vy=(y-yn_1)/(2*0.01);//скорость
 +
yn_1=y0;//для следущего шага Yn-1=Yn
 +
y0=y;//для следущего шага Yn=Yn+1
 +
    cout<<"X="<<x<<endl;
 +
cout<<"Y="<<y<<endl<<endl;
 +
    fout<<x<<" ";
 +
fout<<y<<"  ";
 +
fout<<endl;  
 +
 +
 
 +
}
 +
}
  
        if (y<0) //если y<0
+
void Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
            {
+
 
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
+
{  
                x=x+V0x*t1;//используя это время находим координату по х
+
double x,y,x0=0,y0=0,xn_1,yn_1,v;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
                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;//увел время на шаг
 
                }
 
    }
 
  
 +
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
 +
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
  
}
+
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
 
+
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
 
+
  ofstream fout;//открытие файла
int rez_2(double v, double a, double k, double m)
+
  fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
{
+
cout<<"Verle2"<<endl<<endl;
    fout<<"---------------Второй режим работы-------------------------"<<endl;
+
for(double t=0.02;t<N;t=t+step)
    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;
 
    }
 
  
 +
  v=sqrt(vx*vx+vy*vy);//скорость V
  
 +
x=2*x0-xn_1-(n*v*vx*step*step)/m;//Xn+1
 +
vx=(x-xn_1)/(2*step);//скорость Vx
 +
        xn_1=x0;//для следущего шага Xn-1=Xn
 +
x0=x;//для следущего шага Xn=Xn+1
 +
 +
y=2*y0-yn_1-(g+(n*vy*v)/m)*step*step;//Yn+1
 +
vy=(y-yn_1)/(2*0.01);//скорость Vy
 +
yn_1=y0;//для следущего шага Yn-1=Yn
 +
y0=y;//для следущего шага Yn=Yn+1
 +
cout<<"X="<<x<<endl;
 +
cout<<"Y="<<y<<endl<<endl;
 +
fout<<x<<" ";
 +
fout<<y<<"  ";
 +
fout<<endl;
 +
}
 +
 
}
 
}
  
 
+
void method4(double n,double m ,double v0,double r)//Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
 
int rez_3(double v, double a, double k, double m)
 
 
{
 
{
  fout<<"---------------Третий режим работы-------------------------"<<endl;
+
double x,y,x0=0,y0=0;//x0,y0 начальные значения;
    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,
 
  
 +
double vx=v0*cos(r*PI / 180);//рассчитваем Vx
 +
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vy
 +
 
 +
  ofstream fout;//открытие файла
 +
  fout.open("C:\\Users\\Light\\Desktop\\4.txt");
 +
cout<<"4"<<endl<<endl;
 +
for(double t=0.01;t<N;t=t+step)
 +
{
 +
x=x0+m*vx*(1-(exp((-1*n)*t/m)))/n;//координата х
 +
 +
y = y0+(m/n)*((vy + g * m / n)*(1 - exp(-1 * n * t / m))) - g * t*m/n;//координата у
  
    x3=2*x2-x1-k/m*Vxn*pow(t,2);  //координаты в момент времени T
+
//вывод в файл  и на экран
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
+
    cout<<"X="<<x<<endl;
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
+
cout<<"Y="<<y<<endl<<endl;
    Vyn=(y3-y1)/(2.0*t);
+
fout<<x<<" ";
    x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
+
fout<<y<<" ";
    y1=y2;
+
fout<<endl;  
    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);
+
int main(void)
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
+
{
        }
 
  
        T=T+t;
+
double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
        x1=x2;
 
        y1=y2;
 
        x2=x3;
 
        y2=y3;
 
  
    }
+
cout<<"Enter  start speed:"<<endl;
 +
cin>>v0;
 +
cout<<"Enter angle less than 90 deg:"<<endl;
 +
cin>>r;
 +
cout<<"Enter mass:"<<endl;
 +
cin>>m;
 +
cout<<"Coefficient of resistance:"<<endl;
 +
cin>>n;
 +
 +
Func(v0,r);
 +
Verle1(n,m,v0,r);
 +
Verle2(n,m,v0,r);
 +
method4(n,m,v0,r);
  
}
 
  
  
int rez_4(double v, double a, double k, double m)
+
int k;
{
+
cin>>k;
  fout<<"---------------Четвертый режим работы-------------------------"<<endl;
+
return 0;
    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,
 
  
 +
</syntaxhighlight>
 +
</div>
  
    x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
+
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
    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)
+
<div>
        {
 
            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;
+
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
        y1=y2;
+
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
        x2=x3;
+
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
        y2=y3;
+
</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);
  
int main()
+
// Шар, летящий с сопротивлением воздуха
{
+
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
for (int i = 0; i < 1; i++)
 +
My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
  
setlocale(LC_ALL, "rus");
+
// Шар, летящий с сопротивлением воздуха
cout<<"Введите скорость тела и угол"<<endl;
+
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
cin>>v>>a;
+
for (int i = 0; i < 1; i++)
 +
My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
  
while (1>0){
+
// Шар, летящий с сопротивлением воздуха
cout<<"Выберите режим работы программы:"<<endl;
+
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
+
for (int i = 0; i < 1; i++)
cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
 
cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
// Запуск главного цикла
cout<<"5 - Выйти";
+
  My.Run();
cin>>o;
+
} // End of 'main' function
  
if (o==1)
+
// END OF 'T43ANIM.CPP' FILE
    rez_1(v,a);
+
</syntaxhighlight>
if (o==2)
+
"'''ANIM.CPP'''"
    {
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
+
/* FILENAME: ANIM.CPP
    cin>>m>>k;
+
* LAST UPDATE: 17.01.2016
    rez_2(v,a,k,m);
+
*/
    }
 
  
if (o==3)
+
#include <stdio.h>
    {
+
#include <stdlib.h>
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
+
#include <time.h>
    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;
 
  
            }
+
#include "ANIM.H"
}
 
  
 +
// Единственный экземпляр класса
 +
sagl::anim sagl::anim::Instance;
  
</syntaxhighlight>
+
/* Reshape function */
</div>
+
// Стандартная функция, вызываемая при изменении размеров окна
 +
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;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
  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);
  
Скачать можно  [http://tm.spbstu.ru/Файл:motion.zip тут.]
+
  glLoadIdentity();
 +
  // Позиционирование СК
 +
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
  
<div class="mw-collapsible-content">
+
// Отрисовка объектов
 +
  Instance.Render();
  
'''Визуализированный результат работы программы'''
+
  glFinish();
[[File:Grafics.png]]
+
// Копируем вторичный буфер в окно
 +
glutSwapBuffers();
 +
// Вызываем функцию обновления кадра
 +
glutPostRedisplay();
 +
} // End of 'Display' function
  
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
+
/* 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
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
 
+
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
 
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
 
#include <math.h>
 
#include<stdlib.h>
 
using namespace std;
 
 
 
int main()
 
 
{
 
{
    double a, step, Pi, g, Vo, m, r;
+
// Инициализации OpenGL и GLUT
    ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
+
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 +
 
 +
// Задача размеров и позиции окна
 +
glutInitWindowPosition(0, 0);
 +
  glutInitWindowSize(700, 700);
 +
// Создание окна
 +
glutCreateWindow("T06BALL");
  
    double x, y, x_0, y_0, x0, y0, Vx, Vy;
+
// Установка функций 'обратного вызова'
    ///переменные для движения точки без учёта сопротивления и с его учётом
+
  glutDisplayFunc(Display);
    ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
+
  glutKeyboardFunc(Keyboard);
    ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
+
  glutReshapeFunc(Reshape);
    ///Vx - скорость тела по оси Ох, Vу - скорость тела по оси Оу
 
    ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
 
  
    double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
+
// Установка цвета закраски фона
    ///переменные для 1го варианта метода Верле
+
  glClearColor(0.3, 0.5, 0.7, 1);
    ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
+
  // Включение буфера глубины
    ///у1 - координата тела по оси Оу на (n-1) шаге, у2 - координата тела по оси Оу на (n) шаге, у3 - координата тела по оси Оу на (n+1) шаге
+
glEnable(GL_DEPTH_TEST);
    ///Vx0 - начальная скорость тела по оси Ох, Vy0 - начальная скорость тела по оси Оу
+
  // Включение режима вычисления цвета согласно освещенности от источников света
    ///Vxn - скорость тела в данный момент времени по оси Ох, Vyn - скорость тела в данный момент времени по оси Оу
+
glEnable(GL_LIGHTING);
 +
// Включение источника света
 +
  glEnable(GL_LIGHT0);
 +
// Включение упрощенного режима освещенности для простого способа описания свойств поверхности
 +
  glEnable(GL_COLOR_MATERIAL);
 +
// Приведение нормалей к единичной длине
 +
  glEnable(GL_NORMALIZE);
 +
}
  
    double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
+
// Деструктор
    ///переменные для 2го варианта метода Верле
+
sagl::anim::~anim( void )
    ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
+
{
    ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
+
  // Чистка памяти
     ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
+
for (int i = 0; i < StockSize; i++)
 +
     delete Stock[i];
 +
}
  
    g=10; ///значение ускорения свободного падения
+
/* Render function */
    Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
+
// Отрисовка объектов
 +
void sagl::anim::Render( void )
 +
{
 +
for (int i = 0; i < StockSize; i++)
 +
Stock[i]->Render(*this);
 +
} // End of 'Render' function
  
    do ///цикл, запрашивающий ввод пользователем значения шага функции
+
/* Run function */
    {
+
// Запуск главного цикла
        cout << "Input the step, it must be less than 1" << endl; ///ввод с клавиатуры шага(то же самое, что дельта t), шаг должен быть маленьким (меньше 1)
+
void sagl::anim::Run( void )
        cin >> step;  ///вывод величины шага на экран
+
{
    }
+
// Запуск основного цикла построения
    while (step>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
+
glutMainLoop();
 +
} // End of 'Run' function
  
    cout << '\n' << "Input the corner in degrees,the corner is in the range from 0 to 90 degrees" << endl; ///ввод с клавиатуры угла в радианах (угол от 0 до 90 градусов)
+
// END OF 'ANIM.CPP' FILE
    cin >> a; ///вывод значение угла на экран
+
</syntaxhighlight>
    a=(Pi*a)/180.0;
+
"'''ANIM.H'''"
    cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    cin >> m; ///вывод величины массы на экран
+
/* FILENAME: ANIM.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
    do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
+
#ifndef __ANIM_H_
    {
+
#define __ANIM_H_
        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; ///ввод с клавиатуры значения начальной скорости
+
#include <stdio.h>
    cin >> Vo; ///вывод значения скорости на экран
+
#include <stdlib.h>
 +
#include <time.h>
  
    ///для движения без учёта сопротивления
+
#include <GL\glut.h>
    x0=0; ///обнуление переменных
 
    y0=0;
 
    x=0;
 
    y=0;
 
  
    ///для движения с учётом сопротивления
+
#include "VEC.H"
    x_0=0; ///обнуление переменных
 
    y_0=0;
 
  
    ///для 1го варианта метода Верле
+
// Константы
 +
#define Pi 3.14159265358979323846
 +
#define E 2.71828182845904523536
  
    Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
+
// Собственное пространство имен 'sagl'
    Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
+
namespace sagl
 
+
{
     x2=0; ///обнуление переменных
+
  // Объявления класса анимации наперед
    y2=0;
+
class anim;
    x3=0;
+
 
    y3=0;
+
// Функции получения случайных чисел
 
+
inline double r0( void )
     y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
+
  {
    x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
+
     return rand() / (double)RAND_MAX;
 
+
  }
    ///для 2го варианта метода Верле
+
  inline double r1( void )
 
+
  {
     x_2=0; ///обнуление переменных
+
     return 2.0 * rand() / RAND_MAX - 1;
    y_2=0;
+
  }
     x_3=0;
+
 
    y_3=0;
+
// Класс объектов
 
+
class object
    Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
+
  {
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
+
  public:
 
+
     // Вектора перемещения и скоростей
    y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
+
vec P, V, AbsV;
    x_1=-Vo*cos(a)*step;    ///расчет начального значения координаты на (п-1) шаге по оси Ох
+
      
 
+
// Конструктор
    ofstream out("For method without resistance.txt");
+
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
    ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
 
 
 
    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");
+
virtual void Render( anim &Ani )
    ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
 
 
 
    for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
 
 
     {
 
     {
        Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
+
    } // End of 'Render' function
        Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
+
  }; // end of 'object' class
        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
+
// Класс анимации
 +
class anim
 +
  {
 +
  private:
 +
    // Функции 'обратного вызова'
 +
static void Display( void );
 +
    static void Keyboard( unsigned char Key, int X, int Y );
 +
    static void Reshape( int W, int H );
  
        out1 << x_0 << "    " << y_0 <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
+
    // Единственный экземпляр класса
     }
+
static anim Instance;
     out1.close();
+
      
 +
     // Конструктор
 +
anim( void );
  
     ofstream out2 ("For method Verle 1.txt");
+
// Максимальное количество объектов
     ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
+
    static const int Max = 100;
 
+
     // 'Контейнер' объектов
     for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
+
object *Stock[Max];
 +
     // Размер 'контейнера' объектов
 +
int StockSize;
 +
   
 +
// Переменные, хранящие время в секундах
 +
    long StartTime, OldTime, PauseTime;
 +
      
 +
// Отрисовка объектов
 +
void Render( void );
 +
 +
// Подсчет времени
 +
void Timer( void );
 +
  public:
 +
    // Добавление объектов в 'контейнер'
 +
anim & operator<<( object *Obj )
 
     {
 
     {
        x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
+
      if (StockSize < Max )
         y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
+
         Stock[StockSize++] = Obj;
        Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
+
      else
        Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
+
         delete Obj;
        Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
+
     
 
+
return *this;
        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();
+
      
 +
// Ширина и высота окна
 +
    int WinW, WinH;
  
    ofstream out3 ("For method Verle 2.txt");
+
// Переменные, хранящие время в секундах
    ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
+
    double SyncTime, DeltaTime;
  
     for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
+
     // Переменная, отвечающая за паузу
    {
+
bool IsPause;
        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) шаге
+
~anim( void );
        y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
+
   
        y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
+
// Запуск главного цикла
 +
void Run( void );
 +
   
 +
    // Метод, возвращающий переменную - единственный экземпляр данного типа
 +
static anim & Get( void )
 +
    {
 +
      return Instance;
 +
    }
 +
  }; // end of 'anim' class
 +
} // end of 'sagl' namespace
  
        out3 << x_3 << "  " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
+
#endif /*__ANIM_H_ */
  
    }
+
// END OF 'ANIM.H' FILE
    out3.close();
+
</syntaxhighlight>
 +
"'''VEC.H'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: VEC.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
    cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
+
#ifndef __VEC_H_
    cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
+
#define __VEC_H_
    return 0;
 
}
 
</syntaxhighlight>
 
</div>
 
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
#include <stdlib.h>
'''[[Савельева Ольга]]'''
+
#include <math.h>
  
'''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
+
// Собственное пространство имен 'sagl'
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
namespace sagl
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
 
 
<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)
+
class vec
     {}
+
  {
     Vector(double x, double y):x(x), y(y)
+
  public:
    {}
+
     // Координаты вектора
    const Vector operator+(const Vector &v) const
+
double X, Y, Z;
     {
+
      
        return Vector(this -> x + v.x, this -> y + v.y);
+
// Конструктор
 +
vec( void ) : X(0), Y(0), Z(0)
 +
     {
 +
    }
 +
      
 +
// Конструктор
 +
vec( double A, double B, double C ) : X(A), Y(B), Z(C)
 +
     {
 
     }
 
     }
     const Vector operator-(const Vector &v) const
+
      
 +
// Функции получения случайных чисел
 +
static double R0( void )
 
     {
 
     {
        return Vector(this -> x - v.x, this -> y - v.y);
+
      return rand() / (double)RAND_MAX;
 
     }
 
     }
     const Vector operator*(const double k) const
+
      
 +
static double R1( void )
 
     {
 
     {
        return Vector(this -> x * k, this -> y * k);
+
      return 2 * rand() / (double)RAND_MAX - 1;
 
     }
 
     }
     const Vector operator*(const int k) const
+
      
 +
// Функции получения случайных векторов
 +
static vec Rnd( void )
 
     {
 
     {
        return Vector(this -> x * k, this -> y * k);
+
      return vec(R0(), R0(), R0());
 
     }
 
     }
     const Vector operator/(const double k) const
+
      
 +
static vec Rnd1( void )
 
     {
 
     {
        return Vector(this -> x / k, this -> y / k);
+
      return vec(R1(), R1(), R1());
 
     }
 
     }
};
+
 
+
vec operator+( vec V )
const Vector operator*(const double a, const Vector &v)
+
{
{
+
return vec(X + V.X, Y + V.Y, Z + V.Z);
     return Vector(v.x * a, v.y * a);
+
}
}
+
 +
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
  
const Vector operator*(const int k, const Vector &v)
+
#endif /*__VEC_H_ */
{
 
    return Vector(v.x * k, v.y * k);
 
}
 
  
double abs(const Vector &v)
+
// END OF 'VEC.H' FILE
{
+
</syntaxhighlight>
    return sqrt(v.x * v.x + v.y * v.y);
+
"'''SAMPLE.H'''"
}
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: SAMPLE.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
 +
 
 +
#ifndef __SAMPLE_H_
 +
#define __SAMPLE_H_
  
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
+
#include <math.h>
{
 
    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)
+
#include "ANIM.H"
{
 
    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)
+
// Шар, летящий без сопротивлением воздуха
 +
class ball : public sagl::object
 
{
 
{
    double nowTime = dt;
+
private:
    Vector rsb(0, 0);
+
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
    if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
+
public:
        return rsb; //вернитесь в начальную точку
+
  // Конструктор
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
+
ball( void ) : angle(Pi / 3), v(1)
    Vector r = v * dt;   //вторая точка
+
  {
    Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
    a.y -= g;
+
V.X = 0;
    v = v + a * dt; //скорость во второй точке
+
V.Y = sin(angle) * v;
    a = -windageLinearCoefficient * v; //ускорение во второй точке
+
V.Z = cos(angle) * 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;
+
ball( double angle1, double v1 ) : angle(angle1), v(v1)
        v = (rn - rsb) / (2 * dt); // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
+
{
        rsb = r;    //обновление r(t-dt) and r(t)
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
        r = rn;
+
V.X = 0;
        a = -windageLinearCoefficient * v;  //обновление a(t)
+
V.Y = sin(angle) * v;
        a.y -= g;
+
V.Z = cos(angle) * v;
        nowTime += dt;  //обновленное время
+
}
    }
+
 
    return r;
+
// Отрисовка объекта
}
+
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;
  
Vector calculateForTime(Vector &v, double time)
+
// Ограничения - стенки
{
+
if (P.X > Size / 4)
    Vector r;
+
V.X = -fabs(V.X);
    // x = vx/k*(1-e^(-k*t));
+
if (P.X < -Size / 4)
    r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
+
V.X = fabs(V.X);
    // 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 (P.Y > Size / 4)
{
+
V.Y = -fabs(V.Y);
    if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
+
if (P.Y < -Size / 4)
        return getCoordinatesWithoutWindage(velocity, angle, time);  //вычисляй будто это 0
+
      V.Y = fabs(V.Y);
    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)
+
if (P.Z > Size / 4)
{
+
V.Z = -fabs(V.Z);
    double nowTime = dt;
+
if (P.Z < -Size / 4)
    Vector rsb(0, 0);
+
V.Z = fabs(V.Z);
    if((dt / 2 - time > 0)and(time >= 0))  //если время слишком малое для рсчета
+
        return rsb; //вернитесь в начальную точку
+
    // Запоминание состояния изменения текущей СК
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
+
glPushMatrix();
    Vector r = v * dt;  //вторая точка
+
    Vector a = -abs(v) * v * windageSquareCoefficient; //ускорение в начальной точке
+
// Рисование стенок
    a.y -= g;
+
glutWireCube(Size / 2);
     v = v + a * dt; //скорость во второй точке
+
// Задача перемещения мяча
    a = -abs(v) * v * windageSquareCoefficient; //ускорение во второй точке
+
glTranslated(P.X, P.Y, P.Z);
    a.y -= g;
+
     // Цвет мяча
    while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //когда точка выше нулевой отметки и не достигает заданного времени
+
glColor3d(0, 1, 0);
     {
+
// Рисование мяча
        Vector rn = 2 * r - rsb + a * dt * dt;  // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
+
glutSolidSphere(0.5, 30, 30);
        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;
+
glPopMatrix();
        a = -abs(v) * v * windageSquareCoefficient; //новое a(t)
+
  }
        a.y -= g;
+
}; // end of 'ball' class
        nowTime += dt;  //новое a(t)
+
 
    }
+
// Шар, летящий с сопротивлением воздуха
    return r;
+
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
}
+
class ball_air : public sagl::object
 
 
void err(const char *s) //печатает сообщение об ошибке и завершает работу
 
 
{
 
{
    fputs(s, output);
+
private:
    exit(1);
+
double angle, v, m, n;
}
+
public:
 
+
// Конструктор
int main(int argc, const char *argv[])
+
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
{
+
{
    double velocity, angle;
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
    bool needRead = true;
+
V.X = 0;
    if(argc==3) //если даны 2 аргумента
+
V.Y = sin(angle) * v;
    {
+
V.Z = cos(angle) * v;
        velocity = atof(argv[1]);   //истолкование его как скорости и угла
+
}
        angle = atof(argv[2]);
+
        needRead = false;
+
// Конструктор
    }
+
ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
    if(needRead)
+
{
    {
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
        puts("Enter initial velocity (m/s)");
+
V.X = 0;
        scanf("%lf", &velocity);
+
V.Y = sin(angle) * v;
    }
+
V.Z = cos(angle) * v;
    if(velocity < 0)   //проверка, если скорость меньше 0
+
}
        err("Initial velocity must be above 0");
+
    if(needRead)
+
// Отрисовка объекта
    {
+
void Render( sagl::anim &Ani )
        puts("Enter initial angle (0-180 degrees)");
+
{
        scanf("%lf", &angle);
+
// Вектор ускорения свободного падения и вектор полного ускорения
    }
+
sagl::vec g = sagl::vec(0, -9.8, 0), a;
    if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
+
// Размер комнаты
        err("Initial angle must be from 0 to 180");
+
double Size = 120;
    angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
+
 
    output = fopen("Coordinates.txt", "w"); //открытие результативного файла
+
// Изменение вектора ускорения
    //вычисление и печать 4 значений
+
a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
    printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
+
 
    printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
+
// Изменение вектора скорости
    printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
+
V += a * Ani.DeltaTime;
    printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
+
// Изменение вектора перемещения
    fclose(output); //закрытие файла
+
P += V * Ani.DeltaTime;
    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 здесь]
 
  
 +
// Ограничения - стенки
 +
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);
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
if (P.Z > Size / 4)
'''[[Рубинова Раиса]]'''
+
V.Z = -fabs(V.Z);
 
+
if (P.Z < -Size / 4)
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
+
V.Z = fabs(V.Z);
#  Полет тела без сопротивления воздуха;  
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
+
// Запоминание состояния изменения текущей СК
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
+
glPushMatrix();
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
+
 
+
// Рисование стенок
Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут].
+
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
  
<div class="mw-collapsible-content">
+
// Шар, летящий с сопротивлением воздуха
 
+
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
[[File:Обычный.png]]
+
class ball_air_2 : public sagl::object
[[File:Точный.png]]
+
{
[[File:Верле2.png]]
+
private:
[[File:Верле1.png]]
+
double angle, v, m, n;
 
+
public:
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
// Конструктор
// Первый случай
+
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 
+
{
#include <iostream>
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
#include <math.h>
+
V.X = 0;
#include <cstdlib>
+
V.Y = sin(angle) * v;
#include <fstream>
+
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;
  
using namespace std;
+
// Ограничения - стенки
double a,s,H,p1,p2,X,f;   /// Создание переменных, необходимых для работы:
+
if (P.X > Size / 4)
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
+
V.X = -fabs(V.X);
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
+
if (P.X < -Size / 4)
                                                                                /// H - координата тела по оси Oy;
+
V.X = fabs(V.X);
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
+
 
                                                                                /// X - координата тела по оси Oy;
+
if (P.Y > Size / 4)
                                                                                /// f - шаг по времени;
+
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
  
int main()
+
// Шар, летящий с сопротивлением воздуха
 +
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 +
class ball_air_3 : public sagl::object
 
{
 
{
    cout << "Enter speed and angle and step of time" << endl;  /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
+
private:
    cin >> s >> a >> f;    /// Считывание данных, введенных пользователем, в переменные;
+
double angle, v, m, n;
    double t=s*sin(a*3.14159/180.0)/9.8;        /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
+
public:
    for (double i=f; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
// Конструктор
    {
+
ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
        p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
{
        p2=4.9*i*i;        /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
        H=double(p1)-p2;    /// Вычисление координаты тела по оси Oy;
+
V.X = 0;
        X=s*cos(a*3.14159/180)*i;      /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
V.Y = sin(angle) * v;
        cerr << X << " ";      /// Вывод на экран значения по оси Ox
+
V.Z = cos(angle) * v;
        cerr << H << endl;      /// и по оси Oy;
+
}
    }
+
    ofstream out("zap.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
+
// Конструктор
    for (double i=0; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
    {
+
{
        p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
        p2=4.9*i*i;            /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
V.X = 0;
        H=double(p1)-p2;        /// Вычисление координаты тела по оси Oy;
+
V.Y = sin(angle) * v;
        X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
V.Z = cos(angle) * v;
        out << X << " ";        /// Запись в файл значения по оси Ox
+
}
        out << H << endl;      /// и по оси Oy;
+
    }
+
// Отрисовка объекта
    out.close();        /// Закрываем файл, с которым работали в течение программы;
+
void Render( sagl::anim &Ani )
    return 0;          /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
+
{
}
+
// Вектор ускорения свободного падения и вектор полного ускорения
 +
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);
  
#include <iostream>
+
// Изменение вектора скорости
#include <math.h>
+
V += a * Ani.DeltaTime;
#include <cstdlib>
+
// Изменение вектора перемещения
#include <fstream>
+
P += V * Ani.DeltaTime;
  
/// Программа, позволяющая описать полет точки при помощи точного метода;
+
// Ограничения - стенки
 +
if (P.X > Size / 4)
 +
V.X = -fabs(V.X);
 +
if (P.X < -Size / 4)
 +
V.X = fabs(V.X);
  
using namespace std;
+
if (P.Y > Size / 4)
double v,a,st,m;    /// Создание переменных, необходимых для работы:
+
V.Y = -fabs(V.Y);
                        /// v - модуль скорости, который задает сам пользователь;
+
if (P.Y < -Size / 4)
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
V.Y = fabs(V.Y);
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
 
                        /// m - масса тела, задается пользователем;
+
if (P.Z > Size / 4)
double *V,*X, *Y, *U;   /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
V.Z = -fabs(V.Z);
                        /// V - массив, хранящий значения скорости по оси Ox;
+
if (P.Z < -Size / 4)
                        /// X - массив, хранящий координаты точки по оси Ox;
+
V.Z = fabs(V.Z);
                        /// Y - массив, хранящий значения скорости по оси Oy;
+
 
                        /// U - массив, хранящий координаты точки по оси Oy;
+
// Запоминание состояния изменения текущей СК
 +
glPushMatrix();
  
int main()
+
// Рисование стенок
{
+
glutWireCube(Size / 2);
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
// Задача перемещения мяча
    cin >> v >> a >> st >> m;          /// Считывание данных, введенных пользователей в переменные;
+
glTranslated(P.X, P.Y, P.Z);
    double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
// Цвет мяча
    int n=2*t/st;      /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
glColor3d(1, 0.5, 0);
    //int p=1/st;
+
// Рисование мяча
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
+
glutSolidSphere(0.5, 30, 30);
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
+
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
+
// Восстановление последнего запоминания состояния изменения текущей СК
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
+
glPopMatrix();
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
+
}
    X[0]=0;        /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
+
}; // end of 'ball_air_3' class
    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, тем самым завершая программу;
 
  
 +
#endif /*__SAMPLE_H_ */
  
}
+
// END OF 'SAMPLE.H' FILE
 +
</syntaxhighlight>
 +
</div>
 +
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
 +
<br>
  
// Третий случай
+
'''[[Рубинова Раиса]]'''
  
#include <iostream>
+
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
#include <math.h>
+
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 
 +
Скачать можно [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 <cstdlib>
 
#include <fstream>
 
#include <fstream>
  
/// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
+
/// Программа, анализирующая полет тела;
  
 
using namespace std;
 
using namespace std;
double v,a,st,m,x,y;    /// Создание переменных, необходимых для работы;
+
double a,s,H,p1,p2,X,f;    /// Создание переменных, необходимых для работы:
                        /// v - модуль скорости, который задает сам пользователь;
+
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
                                                                                /// H - координата тела по оси Oy;
                        /// m - масса тела, задается пользователем;
+
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
                        /// x - координата тела по оси Ox в мнимый момент времени t=-1;
+
                                                                                /// X - координата тела по оси Oy;
                        /// y - координата тела по оси Oy в мнимый момент времени t=-1;
+
                                                                                /// f - шаг по времени;
double *V,*X, *Y, *U;  /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
 
                        /// V - массив, хранящий значения скорости по оси Ox;
+
int main()
                        /// X - массив, хранящий координаты точки по оси Ox;
 
                        /// Y - массив, хранящий значения скорости по оси Oy;
 
                        /// U - массив, хранящий координаты точки по оси Oy;
 
 
 
int main()
 
 
{
 
{
     cout << "Enter speed and angle and step of time and weight" << endl;   /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
     cout << "Enter speed and angle and step of time" << endl;   /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователей в переменные;
+
     cin >> s >> a >> f;     /// Считывание данных, введенных пользователем, в переменные;
     double t=(v/9.8)*sin(3.14159*a/180.0);     /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
     double t=s*sin(a*3.14159/180.0)/9.8;       /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
     int n=2*t/st;  /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
     for (double i=f; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
    //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;
+
         p1=s*sin(a*3.14159/180)*i;     /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
         V[k]=(X[k+1]-X[k-1])/(2*st);       /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
+
         p2=4.9*i*i;         /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
         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;
+
         H=double(p1)-p2;   /// Вычисление координаты тела по оси Oy;
         U[k]=(Y[k+1]-Y[k-1])/(2*st);       /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
+
         X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
         //cerr <<i<<" "<<k<<" "<<
+
         cerr << X << " ";      /// Вывод на экран значения по оси Ox
         cerr << X[k+1] << " " << Y[k+1] << endl;   /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
+
         cerr << H << endl;     /// и по оси Oy;
        out << X[k+1] << " " << Y[k+1] << endl;     /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
+
    }
         k=k+1;     /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
+
    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();   /// Закрываем файл, с которым работали в течение программы;
+
     out.close();       /// Закрываем файл, с которым работали в течение программы;
     return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
+
     return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
}
  
// Четвертый случай
+
// Второй случай  
  
 
#include <iostream>
 
#include <iostream>
Строка 2061: Строка 2196:
 
#include <fstream>
 
#include <fstream>
  
/// Программа, анализирующая полет тела при помощи метода Верле;
+
/// Программа, позволяющая описать полет точки при помощи точного метода;
  
 
using namespace std;
 
using namespace std;
double v,a,st,m,x,y;       /// Создание переменных, необходимых для работы:
+
double v,a,st,m;   /// Создание переменных, необходимых для работы:
                            /// v - модуль скорости, который задает сам пользователь;
+
                        /// v - модуль скорости, который задает сам пользователь;
                            /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
                            /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
                            /// m - масса тела, задается пользователем;
+
                        /// m - масса тела, задается пользователем;
                            /// x - координата тела по оси Ox в мнимый момент времени t=-1;
+
double *V,*X, *Y, *U;   /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
                            /// y - координата тела по оси Oy в мнимый момент времени t=-1;
+
                        /// V - массив, хранящий значения скорости по оси Ox;
double *V,*X, *Y, *U;       /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
                        /// X - массив, хранящий координаты точки по оси Ox;
                            /// V - массив, хранящий значения скорости по оси Ox;
+
                        /// Y - массив, хранящий значения скорости по оси Oy;
                            /// X - массив, хранящий координаты точки по оси Ox;
+
                        /// U - массив, хранящий координаты точки по оси Oy;
                            /// Y - массив, хранящий значения скорости по оси Oy;
 
                            /// U - массив, хранящий координаты точки по оси Oy;
 
  
 
int main()
 
int main()
 
{
 
{
 
     cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
 
     cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователем, в переменные;
+
     cin >> v >> a >> st >> m;           /// Считывание данных, введенных пользователей в переменные;
     double t=(v/9.8)*sin(3.14159*a/180.0);     /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
     double t=(v/9.8)*sin(3.14159*a/180.0);         /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
     int n=2*t/st;           /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
     int n=2*t/st;       /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 
     //int p=1/st;
 
     //int p=1/st;
     V = new double [n+2];   /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
+
     V = new double [n+2];       /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
     X = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
+
     X = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
     Y = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
+
     Y = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
     U = new double [n+2];   /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
+
     U = new double [n+2];       /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 
     V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 
     V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
     X[0]=0;                 /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
+
     X[0]=0;         /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
    x=X[0]-V[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
+
     U[0]=v*sin(3.14159*a/180.0);       /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
    X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Ox в момент времени t=1;
+
     Y[0]=0;         /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
     U[0]=v*sin(3.14159*a/180.0);   /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
+
     ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
     Y[0]=0;                 /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
+
     for (int i=1; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
    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) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
                                     /// Цикл повторяется (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;
+
         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 по формуле, выведенной через дифференциальное уравнение точки для вертикальной оси и находящей координату как функцию от времени и координаты тела в предыдущей рассматриваемой нами точке;
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
+
         X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st));         /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
         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;
+
                                                                  /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
        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;
+
         cerr << X[i] << " " << Y[i] << endl;       /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
         out << X[k+1] << " " << Y[k+1] << endl;     /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
+
         out << X[i] << " " << Y[i] << endl;         /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 
 
                                                     /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
                                                     /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
     }
 
     }
     out.close();   /// Закрываем файл, с которым работали в течение программы;
+
     out.close();       /// Закрываем файл, с которым работали в течение программы;
     return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
+
     return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
}
 
  
</syntaxhighlight>
 
</div>
 
  
 +
}
  
'''[[Козловская Анна]]'''
+
// Третий случай
  
 +
#include <iostream>
 +
#include <math.h>
 +
#include <cstdlib>
 +
#include <fstream>
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
/// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/File:project2.rar тут].
+
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;
  
<br>'''[[Нарядчиков Александр]]'''<br>
+
int main()
'''Инструкция:''' Пользователю достаточно просто запустить программу.<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 )
 
 
{
 
{
// Получение единственного экземпляра класса анимации
+
    cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
sagl::anim &My = sagl::anim::Get();
+
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователей в переменные;
    
+
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
// Шар, летящий без сопротивлением воздуха
+
    int n=2*t/st;   /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
        for (int i = 0; i < 1; i++)
+
    //int p=1/st;
                My << new ball(Pi / 6, 10 + i);
+
    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;
for (int i = 0; i < 1; i++)
+
    V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
+
    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 в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
for (int i = 0; i < 1; i++)
+
    Y[0]=0;    /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
+
    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", находящемуся в папке с программой, и открываем файл для записи;
for (int i = 0; i < 1; i++)
+
    out << X[1] << " " << Y[1] << endl;    /// Записываем в файл полученные значения координат тела в момент времени t=1;
My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
+
    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, тем самым завершая программу;
 +
}
  
// Запуск главного цикла
+
// Четвертый случай
  My.Run();
 
} // End of 'main' function
 
  
// END OF 'T43ANIM.CPP' FILE
+
#include <iostream>
</syntaxhighlight>
+
#include <math.h>
"'''ANIM.CPP'''"
+
#include <cstdlib>
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
#include <fstream>
/* FILENAME: ANIM.CPP
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#include <stdio.h>
+
/// Программа, анализирующая полет тела при помощи метода Верле;
#include <stdlib.h>
 
#include <time.h>
 
  
#include "ANIM.H"
+
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()
sagl::anim sagl::anim::Instance;
 
 
 
/* Reshape function */
 
// Стандартная функция, вызываемая при изменении размеров окна
 
void sagl::anim::Reshape( int W, int H )
 
 
{
 
{
  // Установка области просмотра - все окно
+
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
glViewport(0, 0, W, H);
+
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователем, в переменные;
  Instance.WinW = W;
+
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
  Instance.WinH = H;
+
    int n=2*t/st;          /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
  double ratio_x = 1, ratio_y = 1;
+
    //int p=1/st;
   if (W > H)
+
    V = new double [n+2]/// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
     ratio_x = (double)W / H;
+
     X = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
   else
+
    Y = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
     ratio_y = (double)H / W;
+
     U = new double [n+2];  /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
  double Size = 1, Near = 1, Far = 500;
+
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
  // Установка системы координат "камеры"
+
    X[0]=0;                /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
glMatrixMode(GL_PROJECTION);
+
    x=X[0]-V[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
  glLoadIdentity();
+
    X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Ox в момент времени t=1;
  glFrustum(-Size * ratio_x, Size * ratio_x,
+
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
            -Size * ratio_y, Size * ratio_y,
+
    Y[0]=0;                /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
            Near, Far);
+
    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;
  glMatrixMode(GL_MODELVIEW);
+
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
} // End of 'Reshape' function
+
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 
+
    out << X[1] << " " << Y[1] << endl;        /// Записываем в файл полученные значения координат тела в момент времени t=1;
/* Timer function */
+
    int k=1;            /// Создаем целочисленную переменную k=1 для работы в цикле;
// Подсчет времени
+
    //cerr<<"N "<<n<<"\n";
void sagl::anim::Timer( void )
+
    for (int i=0; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
{
+
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
  long Time = clock();
+
    {
 
+
        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;
  if (IsPause)
+
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
    DeltaTime = 0, PauseTime += Time - OldTime;
+
        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;
  else
+
        U[k]=(Y[k+1]-Y[k-1])/(2*st);    /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
    DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;  
+
        //cerr <<i<<" "<<k<<" "<<
  OldTime = Time;
+
        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, тем самым завершая программу;
 +
}
  
  SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
+
</syntaxhighlight>
} /* End of 'Timer' function */
+
</div>
  
/* Display function */
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
// Стандартная функция, вызываемая при перерисовке окна
+
'''[[Савельева Ольга]]'''
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);
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
 
 +
<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;
  Instance.Render();
 
  
  glFinish();
+
double e = 0.0000001; //точность
// Копируем вторичный буфер в окно
+
double g = 9.8; //ускорение свободного падения
glutSwapBuffers();
+
double dt = 0.00001;   //шаг по времени
// Вызываем функцию обновления кадра
+
double windageLinearCoefficient = 0.1;
glutPostRedisplay();
+
double windageSquareCoefficient = 0.00001;
} // End of 'Display' function
 
  
/* Keyboard function */
+
struct Vector  //вектор
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 
void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
 
 
{
 
{
// Выход из программы
+
    double x, y;
if (Key == 27)
+
    Vector():x(0), y(0)
     exit(0);
+
     {}
// Открытие программы в полном экране
+
    Vector(double x, double y):x(x), y(y)
else if (Key == 'f')
+
    {}
     glutFullScreen();
+
    const Vector operator+(const Vector &v) const
  // Пауза
+
     {
else if (Key == 'p' || Key == 'P')
+
        return Vector(this -> x + v.x, this -> y + v.y);
     Instance.IsPause = !Instance.IsPause;
+
    }
} // End of 'Keyboard' function
+
    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);
 +
    }
 +
};
  
sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
+
const Vector operator*(const double a, const Vector &v)
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
 
 
{
 
{
// Инициализации OpenGL и GLUT
+
    return Vector(v.x * a, v.y * a);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+
}
 
 
// Задача размеров и позиции окна
 
glutInitWindowPosition(0, 0);
 
  glutInitWindowSize(700, 700);
 
// Создание окна
 
glutCreateWindow("T06BALL");
 
  
// Установка функций 'обратного вызова'
+
const Vector operator*(const int k, const Vector &v)
  glutDisplayFunc(Display);
+
{
  glutKeyboardFunc(Keyboard);
+
    return Vector(v.x * k, v.y * k);
  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);
 
 
}
 
}
  
// Деструктор
+
double abs(const Vector &v)
sagl::anim::~anim( void )
 
 
{
 
{
  // Чистка памяти
+
    return sqrt(v.x * v.x + v.y * v.y);
for (int i = 0; i < StockSize; i++)
 
    delete Stock[i];
 
 
}
 
}
  
/* Render function */
+
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
// Отрисовка объектов
 
void sagl::anim::Render( void )
 
 
{
 
{
for (int i = 0; i < StockSize; i++)
+
    fputs(description, output);
Stock[i]->Render(*this);
+
    fputs(": ", output);
} // End of 'Render' function
+
    fprintf(output, "%lf", v.x);
 +
    fputs(", ", output);
 +
    fprintf(output, "%lf\n", v.y);
 +
}
  
/* Run function */
+
Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
// Запуск главного цикла
 
void sagl::anim::Run( void )
 
 
{
 
{
// Запуск основного цикла построения
+
    double fallTime = 2 * velocity * sin(angle) / g;  //расчет времени падения
glutMainLoop();
+
    if((time < 0) or (time > fallTime))
} // End of 'Run' function
+
        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);
 +
}
  
// END OF 'ANIM.CPP' FILE
+
Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
</syntaxhighlight>
+
{
"'''ANIM.H'''"
+
    double nowTime = dt;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    Vector rsb(0, 0);
/* FILENAME: ANIM.H
+
    if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
  * LAST UPDATE: 17.01.2016
+
        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;
 +
}
  
#ifndef __ANIM_H_
+
Vector calculateForTime(Vector &v, double time)
#define __ANIM_H_
+
{
 +
    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;
 +
}
  
#include <stdio.h>
+
Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
#include <stdlib.h>
+
{
#include <time.h>
+
    if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
 
+
        return getCoordinatesWithoutWindage(velocity, angle, time);  //вычисляй будто это 0
#include <GL\glut.h>
+
    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;
 +
    }
 +
}
  
#include "VEC.H"
+
Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
 
+
{
// Константы
+
    double nowTime = dt;
#define Pi 3.14159265358979323846
+
    Vector rsb(0, 0);
#define E 2.71828182845904523536
+
    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;
 +
}
  
// Собственное пространство имен 'sagl'
+
void err(const char *s) //печатает сообщение об ошибке и завершает работу
namespace sagl
 
 
{
 
{
  // Объявления класса анимации наперед
+
    fputs(s, output);
class anim;
+
     exit(1);
 
+
}
// Функции получения случайных чисел
+
 
inline double r0( void )
+
int main(int argc, const char *argv[])
  {
+
{
     return rand() / (double)RAND_MAX;
+
     double velocity, angle;
  }
+
     bool needRead = true;
  inline double r1( void )
+
     if(argc==3) //если даны 2 аргумента
  {
 
     return 2.0 * rand() / RAND_MAX - 1;
 
  }
 
 
 
// Класс объектов
 
class object
 
  {
 
  public:
 
     // Вектора перемещения и скоростей
 
vec P, V, AbsV;
 
      
 
// Конструктор
 
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
 
 
     {
 
     {
 +
        velocity = atof(argv[1]);  //истолкование его как скорости и угла
 +
        angle = atof(argv[2]);
 +
        needRead = false;
 
     }
 
     }
+
    if(needRead)
// Отрисовка объектов
 
virtual void Render( anim &Ani )
 
 
     {
 
     {
     } // End of 'Render' function
+
        puts("Enter initial velocity (m/s)");
  }; // end of 'object' class
+
        scanf("%lf", &velocity);
 
+
     }
// Класс анимации
+
    if(velocity < 0)    //проверка, если скорость меньше 0
class anim
+
        err("Initial velocity must be above 0");
  {
+
    if(needRead)
  private:
+
    {
     // Функции 'обратного вызова'
+
        puts("Enter initial angle (0-180 degrees)");
static void Display( void );
+
        scanf("%lf", &angle);
     static void Keyboard( unsigned char Key, int X, int Y );
+
    }
     static void Reshape( int W, int H );
+
    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%" >
 +
 
  
    // Единственный экземпляр класса
+
'''[[Сенников Иван]]'''
static anim Instance;
 
   
 
    // Конструктор
 
anim( void );
 
  
// Максимальное количество объектов
+
'''Суть программы:'''Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.
    static const int Max = 100;
+
 
    // 'Контейнер' объектов
+
'''Идея:''' Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.
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;
 
  
// Переменные, хранящие время в секундах
+
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Throws_v2.0.zip здесь].
    double SyncTime, DeltaTime;
 
  
    // Переменная, отвечающая за паузу
+
</div>
bool IsPause;
 
  
    // Деструктор
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
~anim( void );
+
'''[[Степанянц Степан]]'''
   
+
 
// Запуск главного цикла
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
void Run( void );
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
   
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
    // Метод, возвращающий переменную - единственный экземпляр данного типа
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
static anim & Get( void )
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
    {
+
 
      return Instance;
+
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
    }
 
  }; // end of 'anim' class
 
} // end of 'sagl' namespace
 
  
#endif /*__ANIM_H_ */
+
<div class="mw-collapsible-content">
 +
[[File:graph239.png]]
  
// END OF 'ANIM.H' FILE
+
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
</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'
+
Файл "'''main.cpp'''"
namespace sagl
+
<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;
class vec
+
    y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t;  //Расчитываем координаты в каждой точке через шаг
  {
+
  F<<x<<" "<<y<<endl;
  public:
+
  t=t+dt;
    // Координаты вектора
+
double X, Y, Z;
+
}
   
+
// Конструктор
+
F.close();
vec( void ) : X(0), Y(0), Z(0)
+
                                        //Точное решение для линейной зависимости
    {
+
F.open("C:\\2.txt",ios::out);
    }
+
y=y0;
      
+
x=x0;
// Конструктор
+
t=0;                                                                            //Расчитываем координаты в каждой точке через шаг
vec( double A, double B, double C ) : X(A), Y(B), Z(C)
+
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
static double R0( void )
+
    ypr = y0 - u0*sin(a)*dt;
     {
+
yt=ypr;
      return rand() / (double)RAND_MAX;
+
     xpr = x0 - u0*cos(a)*dt;
     }
+
    x = x0;                                                                            //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
      
+
    y = y0;
static double R1( void )
+
    u = u0;
 +
    ux = u0 * cos(a);                            
 +
     uy = u0 * sin(a);
 +
F.open("C:\\4.txt",ios::out);
 +
 +
     while (y >= y0)
 
     {
 
     {
      return 2 * rand() / (double)RAND_MAX - 1;
+
        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();
// Функции получения случайных векторов
+
static vec Rnd( void )
+
    {
+
return 0;
      return vec(R0(), R0(), R0());
+
    }
+
   
+
}
static vec Rnd1( void )
+
 
    {
+
</syntaxhighlight>
      return vec(R1(), R1(), R1());
+
</div>
    }
+
 
+
 
vec operator+( vec V )
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
{
+
'''[[Александр Сюрис]]'''  
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_ */
+
'''Описание программы''':
 
+
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
// END OF 'VEC.H' FILE
+
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
</syntaxhighlight>
+
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении          воздуха от скорости
"'''SAMPLE.H'''"
+
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 +
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
Скачать можно  [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">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
/* FILENAME: SAMPLE.H
+
#include <iostream>
* LAST UPDATE: 17.01.2016
+
#include <fstream>
*/
+
#include <math.h>
 +
#include <cmath>
 +
using namespace std;
 +
int o;
 +
double v,a,m,k;
 +
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
  
#ifndef __SAMPLE_H_
 
#define __SAMPLE_H_
 
  
#include <math.h>
 
  
#include "ANIM.H"
+
int rez_1(double v, double a)
 
 
// Шар, летящий без сопротивлением воздуха
 
class ball : public sagl::object
 
 
{
 
{
private:
+
    fout<<"---------------Первый режим-------------------------"<<endl;
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
+
    fout<<" T=0 x=0 y=0";
public:
+
    fout<<endl;
  // Конструктор
+
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
ball( void ) : angle(Pi / 3), v(1)
+
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
  {
+
    V0y=v*sin(a/180*M_PI);
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    Ty=2*V0y/g;//время полета
V.X = 0;
+
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
V.Y = sin(angle) * v;
+
    {
V.Z = cos(angle) * v;
+
        x=x+V0x*t;              //ф-лы для рассчета x и y в данный момент времени
  }
+
        y=y+V0y*t-g*pow(t,2)/2;
+
 
// Конструктор
+
        if (y<0) //если y<0
ball( double angle1, double v1 ) : angle(angle1), v(v1)
+
            {
{
+
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
                x=x+V0x*t1;//используя это время находим координату по х
V.X = 0;
+
                fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
V.Y = sin(angle) * v;
+
                break;
V.Z = cos(angle) * v;
+
            }
}
+
            else
 
+
                {
// Отрисовка объекта
+
                    V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
void Render( sagl::anim &Ani )
+
                    fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
  {
+
                    T=T+t;//увел время на шаг
// Вектор ускорения свободного падения
+
                }
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)
+
int rez_2(double v, double a, double k, double m)
V.X = fabs(V.X);
+
{
 +
    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;
 +
    }
 +
 
 +
 
 +
}
  
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
 
  
// Шар, летящий с сопротивлением воздуха
+
int rez_3(double v, double a, double k, double m)
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 
class ball_air : public sagl::object
 
 
{
 
{
private:
+
  fout<<"---------------Третий режим работы-------------------------"<<endl;
double angle, v, m, n;
+
    fout<<" T=0 x=0 y=0";
public:
+
    fout<<endl;
// Конструктор
+
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    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 в момент времени Т
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
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);
 
  
// Изменение вектора скорости
+
    x3=2*x2-x1-k/m*Vxn*pow(t,2);  //координаты в момент времени T
V += a * Ani.DeltaTime;
+
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
// Изменение вектора перемещения
+
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
P += V * Ani.DeltaTime;
+
    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;
if (P.X > Size / 4)
+
        x1=x2;
V.X = -fabs(V.X);
+
        y1=y2;
if (P.X < -Size / 4)
+
        x2=x3;
V.X = fabs(V.X);
+
        y2=y3;
  
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
 
  
// Шар, летящий с сопротивлением воздуха
+
int rez_4(double v, double a, double k, double m)
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
 
class ball_air_2 : public sagl::object
 
 
{
 
{
private:
+
  fout<<"---------------Четвертый режим работы-------------------------"<<endl;
double angle, v, m, n;
+
    fout<<" T=0 x=0 y=0";
public:
+
    fout<<endl;
// Конструктор
+
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    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 в момент времени Т
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
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;
 
  
// Ограничения - стенки
+
    x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
if (P.X > Size / 4)
+
    y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
V.X = -fabs(V.X);
+
    Vxn=(x3-x1)/(2.0*t);
if (P.X < -Size / 4)
+
    Vyn=(y3-y1)/(2.0*t);
V.X = fabs(V.X);
+
    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;
 +
        }
  
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)
+
        T=T+t;
V.Z = -fabs(V.Z);
+
        x1=x2;
if (P.Z < -Size / 4)
+
        y1=y2;
V.Z = fabs(V.Z);
+
        x2=x3;
 +
        y2=y3;
  
// Запоминание состояния изменения текущей СК
+
    }
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
 
  
// Шар, летящий с сопротивлением воздуха
+
int main()
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 
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;
 
  
// Изменение вектора ускорения
+
setlocale(LC_ALL, "rus");
a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
+
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)
V += a * Ani.DeltaTime;
+
    {
// Изменение вектора перемещения
+
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
P += V * Ani.DeltaTime;
+
    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;
 +
 
 +
            }
 +
}
  
// Ограничения - стенки
 
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)
+
</syntaxhighlight>
V.Y = -fabs(V.Y);
+
</div>
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);
 
  
// Запоминание состояния изменения текущей СК
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
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_ */
+
Скачать можно  [http://tm.spbstu.ru/Файл:motion.zip тут.]
  
// END OF 'SAMPLE.H' FILE
+
<div class="mw-collapsible-content">
</syntaxhighlight>
 
</div>
 
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
 
<br>
 
  
 +
'''Визуализированный результат работы программы'''
 +
[[File:Grafics.png]]
  
'''[[Абрамов Игорь]]'''
+
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
  
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
+
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
 +
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
 +
#include <math.h>
 +
#include<stdlib.h>
 +
using namespace std;
  
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
+
int main()
 +
{
 +
    double a, step, Pi, g, Vo, m, r;
 +
    ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
  
</div>
+
    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
  
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
+
    cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
[[http://tm.spbstu.ru/File:phys.rar тут]]
+
    cin >> Vo; ///вывод значения скорости на экран
  
</div>
+
    ///для движения без учёта сопротивления
 +
    x0=0; ///обнуление переменных
 +
    y0=0;
 +
    x=0;
 +
    y=0;
  
 +
    ///для движения с учётом сопротивления
 +
    x_0=0; ///обнуление переменных
 +
    y_0=0;
  
 +
    ///для 1го варианта метода Верле
  
</div>
+
    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го варианта метода Верле
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
+
    x_2=0; ///обнуление переменных
 +
    y_2=0;
 +
    x_3=0;
 +
    y_3=0;
  
</div>
+
    Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
 +
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
  
</div>
+
    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();
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
+
    ofstream out1 ("For method with resistance.txt");
 +
    ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
  
</div>
+
    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
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
        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го варианта метода Верле
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
+
    {
 +
        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) шаге
  
<div class="mw-collapsible-content">
+
        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) шаге
  
[[:File:Throws.png]]
+
        out3 << x_3 << "  " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    }
 +
    out3.close();
  
#include <iostream>
+
    cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
#include <math.h>
+
    cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
#include <iomanip>
+
    return 0;
#include <fstream>
+
}
#include <conio.h>
+
</syntaxhighlight>
#include <stdio.h>
+
</div>
  
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Уманский Александр]]'''
  
using namespace std;
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
+
<div class="mw-collapsible-content">
  
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
+
[[File:Methods.rar|Скачать архив]]
{
 
    FILE *Coord;
 
  Coord = fopen ("Throws Without Resistance.txt", "w");
 
    double X = 0, Y = 0; // Координаты начала
 
  
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
+
[[File:1.png]]
    {
 
  
      X =  Vo*t*cos(alpha);
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
      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>
 
</syntaxhighlight>
 
</div>
 
</div>
 
'''[[Гильманов Илья]]'''
 
 
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 
#  Полет тела без сопротивления воздуха;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
 
Скачать можно [[http://mech.spbstu.ru/File:Qwertyui.rar тут]]
 
 
'''[[Киселёв Лев]]'''
 
 
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
 
#  Полет тела без сопротивления воздуха;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
 
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
 
 
'''[[Ляжков Сергей]]'''
 
'''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
 
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значение y не станет ОТРИЦАТЕЛЬНЫМИ...
 
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
 
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
 

Текущая версия на 00:28, 16 июня 2016

Абрамов Игорь

Алгоритм: в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.

Инструкция: при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.

Ссылка для скачивания: [1]


Андреева Полина

Краткое описание алгоритма: в классе находятся координаты по формулам и записываются в файл.

Инструкция : Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.

Скачать можно тут.



Визуализированный результат работы программы

File:graphAP.png

Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;

  1. "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. "MyFile.txt" using 3 : 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.


 1 #include <iostream>
 2 #include <fstream>
 3 #include "math.h"
 4 #include <iomanip>
 5 using namespace std;
 6 class func
 7 {
 8 
 9  private:
10     double speed0, angle0, step ;
11    double time;
12 
13    public:
14        double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
15        double t, amount;
16       int amountint;
17     func ( double _speed0, double _angle0, double _step ):speed0(_speed0), angle0(_angle0), step(_step)
18     {
19         angle0=(3.14159*angle0) / 180 ; ///перевод угла в радианы
20 
21         time = ( 2*speed0*sin(angle0) ) / g;///подсчет полного времени полета
22         amount = (time/step) + 1;///количество точек для траектории
23         amountint =  static_cast<int> (amount) ;
24 
25 
26     }
27 
28 
29 
30       void SaveFile(char filename[])
31     {
32         double x0=0, y0=0;
33         double xv1=0, x1=0, y1=0, Vx1=speed0*cos(angle0),Vy1=speed0*sin(angle0), V1=speed0, yv1=0;
34         double xm1=x0-speed0*cos(angle0)*step, ym1=y0-speed0*sin(angle0)*step;
35         double xv2=0, x2=0, y2=0, Vx2=speed0*cos(angle0),Vy2=speed0*sin(angle0), V2=speed0, yv2=0;
36         double xm2=x0-speed0*cos(angle0)*step, ym2=y0-speed0*sin(angle0)*step;
37         double x3,y3;
38         std::ofstream fout(filename);
39         for (int i=0; (y0+(speed0*sin(angle0)*i*step - (g*i*i*step*step*0.5)))>=0; i++)
40         {
41             ///Верле линейная зависимость
42             x2=2*xv2-xm2-(n/m)*step*step*Vx2;
43             y2=2*yv2-ym2-(g+(n/m)*Vy2)*step*step;
44             Vx2=(x2-xm2) / (2.0*step);
45             Vy2=(y2-ym2) / (2.0*step);
46             xm2=xv2;
47             xv2=x2;
48             ym2=yv2;
49             yv2=y2;
50 
51             ///точное решение
52             x3=x0+speed0*cos(angle0)*(m/n)*(1.0-exp(-(n/m)*i*step));
53             y3=y0+(m/n)*(speed0*sin(angle0) + g*(m/n))*(1.0-exp(-(n/m)*i*step))-g*(m/n)*i*step;
54 
55             ///метод Верле, квадратичная зависимость
56             x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
57             y1=2*yv1-ym1-(g+(n/m)*V1*Vy1)*step*step;
58             Vx1=(x1-xm1) / (2.0*step);
59             Vy1=(y1-ym1) / (2.0*step);
60             V1=sqrt(Vx1*Vx1+Vy1*Vy1);
61             xm1=xv1;
62             xv1=x1;///запоминание предыдущего шага
63             ym1=yv1;
64             yv1=y1;
65 
66 
67 
68 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";
69 
70         }
71         fout.close();
72     }
73 
74 };
75 
76 
77 int main()
78 {
79     double V0, angle, step;
80     cout << " enter V0 = ";///введите начальную скорость
81     cin >> V0;
82     cout << " enter an angle , 0 < angle <= 90, angle = " ;///введите угол в диапозоне от 0 до 90 градусов
83     cin >> angle;
84     cout << "\n enter step ";///введите шаг, с которым будут рассчитываться координаты
85     cin >> step; cout << endl;
86     func f1(V0,angle,step);///создание траектории
87      f1.SaveFile("Myfile.txt");///запись в файл
88 
89 
90     return 0;
91 }

Бальцер Анастасия

Описание программы : программа записывает в четыре файла результаты вычисления:

Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.

Посмотреть программу можно здесь

Белоусова Екатерина

Описание программы: пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки.

Программа записывает в один файл результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  4. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;

Скачать можно тут.

Формулы.png

Визуализированный результат работы программы Graph1.png

Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01;

  1. "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  3. "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
  4. "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.


  1 #include <iostream>
  2 #include <locale.h>
  3 #include <math.h>
  4 #include <fstream>
  5 #include<iomanip>
  6 #include <cmath>
  7 
  8 using namespace std;
  9 
 10 class fly ///создаем класс полета тела
 11 {
 12 
 13 private: ///объявляем тип переменных в привате
 14     double Vo, Agrad, Brad, time, step, amountdouble; ///Vo-начальная скорость тела; Agrad-угол, под которым летит тело, в градусах;
 15                                                       ///Brad-угол, под которым летит тело, в радианах; time-время полета тела; step-шаг;
 16                                                       ///amountdouble-количество точек (типа double)
 17 
 18 public: ///объявляем переменные в паблике
 19     int amount; ///amoun-количество точек (типа int)
 20 
 21 fly (double _step, double _Agrad, double _Vo):step(_step),Agrad(_Agrad),Vo(_Vo) ///создаем конструктор функции с объявлением переменных
 22 {
 23 
 24     double g=9.8; ///объявляем тип и значение переменной g(ускорение свободного падения)
 25     Brad=3.14159*Agrad/180.0; ///переводим значение угла из градусов в радианы
 26 
 27     time=2*Vo*sin(Brad)/g; ///рассчитываем время полета тела
 28     amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом
 29     amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
 30 
 31 }
 32 void zapis (char Zapis[]) ///создаем функцию записи
 33 {
 34     double g=9.8, m=1, n=0.05; ///объявляем тип и значения переменных g (ускорение свободного падения), m (масса тела), n(коэффициэнт сопротивления)
 35     double Xb, Yb; ///объявляем тип переменных для полёта тела без сопротивления ветра Xb(координата тела по Х), Yb(координата тела по У)
 36     double V=Vo, Vxv=Vo*cos(Brad), Vyv=Vo*sin(Brad), Xo=0, Yo=0, Xv=0, Yv=0, Y_1=Yo-Vo*sin(Brad)*step, X_1=Xo-Vo*cos(Brad)*step, Y=0, X=0;
 37            ///объявляем тип переменных для метода ВерлеI V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 38            ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 39            ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 40            ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 41            ///X (координата тела на n-ом шаге на оси Х);
 42     double Vxv2=Vo*cos(Brad), Vyv2=Vo*sin(Brad), Xo2=0, Yo2=0, Xv2=0, Yv2=0, Y_12=Yo2-Vo*sin(Brad)*step, X_12=Xo-Vo*cos(Brad)*step, Y2=0, X2=0;
 43            ///объявляем тип переменных для метода ВерлеII V (скорость тела по модулю), Vxv (составляющая скорости по Х),
 44            ///Vyv (составляющая скорости по У), Xo (начальное положение тела на оси Х), Yo (начальное положение тела на оси У),
 45            ///Xv (координата тела на оси Х), Yv (координата тела на оси У), Y_1 (координата тела на (n-1)ом шаге на оси У),
 46            ///X_1 (координата тела на (n-1)ом шаге на оси Х), Y (координата тела на n-ом шаге на оси У),
 47            ///X (координата тела на n-ом шаге на оси Х);
 48     double Yt=0, Xt=0, Yot=0, Xot=0, Voxt=Vo*cos(Brad), Voyt=Vo*sin(Brad);
 49 
 50     ofstream outfile("Zapis.txt"); ///запись элементов функции в фаил "Zapis.txt"
 51     outfile<<setw(20)<<"Xb"<<setw(20)<<"Yb"<<setw(20)<<"Xt"<<setw(20)<<"Yt"<<setw(20)<<"Xv"<<setw(20)<<"Yv"<<setw(20)<<"Xv2"<<setw(20)<<"Yv2"<<" \n"; ///вывод на экран по столбцам
 52                                                                                   ///X (координата тела на оси Х без ветра),
 53                                                                                   ///Y (координата тела на оси У без ветра),
 54                                                                                   ///Xv (координата тела на оси Х с ветром для метода Верле),
 55                                                                                   ///Yv (координата тела на оси У с ветром для метода Верле)
 56                                                                                   ///setw() размер столбиков
 57 
 58     for (int l=0; Yb>=0; ++l) ///создаем цикл от 0 до тех пор пока У больше нуля
 59     {
 60         outfile<<setw(20)<<Xb<<setw(20)<<Yb<<setw(20)<<Xt<<setw(20)<<Yt<<setw(20)<<Xv<<setw(20)<<Yv<<setw(20)<<Xv2<<setw(20)<<Yv2<<" \n";
 61             ///вывод на экран по столбцам Xv, Yv;
 62 
 63         ///полёт без ветра
 64         Xb=Vo*cos(Brad)*l*step;
 65         Yb=Vo*sin(Brad)*l*step-(9.8*l*step*l*step*0.5);
 66 
 67         ///точный метод
 68         Xt=Xot+(m/n)*Voxt*(1.0 - exp((-n*l*step)/m));
 69         Yt=Yot+(m/n)*(Voyt+g*(m/n))*(1.0 - exp((-n*l*step)/m))-g*l*step*(m/n);
 70 
 71         ///метод Верле I
 72         Xv=2*X-X_1-(n/m)*V*Vxv*step*step; ///расчитываем координату Х в момент времени t для метода Верле
 73         Yv=2*Y-Y_1-(g+(n/m)*V*Vyv)*step*step; ///расчитываем координату У в момент времени t для метода Верле
 74         Vxv=(Xv-X_1)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
 75         Vyv=(Yv-Y_1)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 76         V=sqrt(Vxv*Vxv+Vyv*Vyv); ///рассчитываем скорость тела по модулю
 77         X_1=X; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 78         X=Xv;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 79         Y_1=Y; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 80         Y=Yv;  ///присваиваем значению координаты У на n-ом шаге значение координаты У
 81 
 82         ///метод Верле II
 83         Xv2=2*X2-X_12-(n/m)*Vxv2*step*step; ///расчитываем координату Х в момент времени t для метода Верле
 84         Yv2=2*Y2-Y_12-(g+(n/m)*Vyv2)*step*step; ///расчитываем координату У в момент времени t для метода Верле
 85         Vxv2=(Xv2-X_12)/(2.0*step); ///расчитываем скорость тела по оси Х в момент времени t для метода Верле
 86         Vyv2=(Yv2-Y_12)/(2.0*step); ///расчитываем скорость тела по оси У в момент времени t для метода Верле
 87         X_12=X2; ///присваиваем значению координаты Х на (n-1)ом шаге значение координаты Х на n-ом шаге
 88         X2=Xv2;  ///присваиваем значению координаты Х на n-ом шаге значение координаты Х
 89         Y_12=Y2; ///присваиваем значению координаты У на (n-1)ом шаге значение координаты У на n-ом шаге
 90         Y2=Yv2;  ///присваиваем значению координаты У на n-ом шаге значение координаты У
 91 
 92     }
 93 
 94     outfile.close();
 95 
 96 }
 97 
 98 };
 99 
100 int main()
101 {
102 
103     setlocale(LC_ALL,"RUS"); ///функция, позволяющая с++ распознавать русский язык
104 
105     double Vo, Agrad, Brad, time, step; ///объявляем тип переменных Vo (начальная скорость тела), Agrad (угол, под которым летит тело, в градусах);
106                                         ///Brad (угол, под которым летит тело, в радианах); time (время полета тела); step (шаг)
107     cout<<"Задайте начальную скорость тела в м/с: Vo="; ///на экран выводится сообщение с просьюой задать начальную скорость тела
108     cin>>Vo; ///пользователь вводит начальную скорость тела
109     cout<<'\n'<<"Задайте в градусах угол, под которым брошено тело (угол должен принимать значения от 0 до 90): a=";
110                                                         ///на экран выводится сообщение с просьбой задать угол, под которым летит тело, в градусах
111     cin>>Agrad; ///пользователь вводит угол, под которым летит тело
112     cout<<'\n'<<"Задайте шаг (шаг должен быть очень маленьким): шаг="; ///на экран выводится сообщение с просьбой ввести шаг
113     cin>>step; ///пользователь вводит шаг
114 
115     fly X(step,Agrad,Vo); ///объявление коструктора, создание функции Х, зависящей от step,Agrad,Vo
116     X.zapis("координаты.txt"); ///запись элементов функции в файл
117 
118     return 0; ///конец программы
119 
120 }

Васильева Анастасия

Описание программы: пользователь вводит начальную скорость полета, угол падения и шаг, с которым будут рассчитаны точки.

Программа записывает в один файл результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные при численном интегрировании - метод Эйлера;
  3. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  4. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;

Скачать можно тут.



Визуализированный результат работы программы Graphick.png

Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;

  1. "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
  3. "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
  4. "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.


  1 #include <iostream>
  2 #include <fstream>
  3 #include <iomanip>
  4 #include <time.h>
  5 #include <conio.h>
  6 #include <stdlib.h>
  7 #include <math.h>
  8 #include <cstring>
  9 using namespace std;
 10 
 11 class pad ///создаем класс
 12 {
 13 private: ///в закрытом доступе
 14     double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
 15     double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
 16     int Size; ///размер массива- сколько точек считать в первом способе
 17     double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
 18 
 19     void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
 20     {
 21         g = 9.8;///коэфф свободного падения
 22         float t = 0; ///время
 23         X = new double [Size];///создаем массив для координат по х для простого падения
 24         E = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
 25         X[0] = 0; ///задаем значение по х в нуле
 26         E[0] = 0 ; ///задаем значение по х в нуле по эйлеру
 27         for (int i = 1; i < Size; i++) ///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
 28         {
 29             t += shag; ///каждый раз прибавляем по времени шаг
 30             X[i] = v * cos(a) * t; ///координаты по х для простого падения
 31             E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
 32         }
 33     }
 34 
 35     void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
 36     {
 37         g = 9.8; ///коэфф свободного падения
 38         double Vy; /// переменная для значение скорости по у для метода эйлера
 39         float t = 0; ///время
 40         Y = new double [Size];///создаем массив для координат по у для простого падения
 41         G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
 42         Vy = v * sin (a);/// значение скорости по у для метода эйлера
 43         Y[0] = 0;///задаем значение по у в нуле
 44         G[0] = 0;///задаем значение по у в нуле по эйлеру
 45         for (int i = 1; i < Size; i++)///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
 46         {
 47             t += shag; ///каждый раз прибавляем по времени шаг
 48             Y[i] = v * sin (a) *t - (g * t * t) * 0.5; ///координаты по у для простого падения
 49             Vy -= g * shag; ///значение скорости по у для метода эйлера
 50             G[i] = G[i-1] + Vy  * shag;///у из интегрирования по эйлеру
 51         }
 52     }
 53 
 54     void SetVerle() ///функция для метода верле
 55     {
 56         double k = 0.1, m = 0.5; ///коэфф сопротивления водуха, масса тела
 57         g = 9.8; /// коэфф свободного падения
 58         uint32_t Size1 = 1000000.0; ///размер массива
 59         S = new double [Size1]; ///создаем массив для значений по х для метода верле
 60         Z = new double [Size1]; ///создаем массив для значений по у для метода верле
 61         vx = v * cos(a); ///формулы для вычисления скорости по оси х
 62         vy = v * sin(a); ///формулы для вычисления скорости по оси у
 63         S[1] = 0; ///значение х метод верле
 64         S[0] = -vx * shag; ///значение в нуле
 65         Z[1] = 0; ///значение у метод верле
 66         Z[0] = -vy * shag; ///значение в нуле
 67         for (int i = 0; i < Size1-2; i++) ///задаем цикл
 68         {
 69             S[i+2] = 2.0 * S[i+1] - S[i] - (k / m) * v * vx * shag * shag;///значения по х для верле
 70             vx = 0.5 * ( 1.0 / shag )* ( S[i+2] - S[i]);///считаем значения скорости по оси х
 71             Z[i+2] = 2.0 * Z[i+1] - Z[i] - ( g + (k / m) * v * vy ) * shag * shag;///значения по х для верле
 72             vy = 0.5 * ( 1.0 / shag )* ( Z[i+2] - Z[i]);///считаем значения скорости по оси х
 73             v = sqrt (vx * vx + vy * vy); ///модуль общей скорости
 74         }
 75     }
 76     void SetVerleLast() ///функция для точного метода верле
 77     {
 78         double k = 0.1, m = 0.5;///коэфф сопротивления водуха, масса тела
 79         g = 9.8; /// коэфф свободного падения
 80         uint32_t Size2 = 1000000.0; ///размер массива
 81         float t = 0; ///время
 82         V = new double [Size2]; ///создаем массив для значений по х для точного метода верле
 83         U = new double [Size2]; ///создаем массив для значений по у для точного метода верле
 84         vx = v * cos(a); ///формулы для вычисления скорости по оси х
 85         vy = v * sin(a); ///формулы для вычисления скорости по оси у
 86         ///double e = 2.7 ;///значение экспоненты
 87         V[0] = 0; ///значение х точный метод верле
 88         U[0] = 0; ///значение у точный метод верле
 89         for (int i = 1; i < Size2; i++)
 90         {
 91             t += shag; ///увеличиваем время на шаг
 92             V[i] = vx * (m / k) * (1.0 - exp(((-k) / m) * t)); ///значения по х для точного верле
 93             U[i] = (m / k) * (vy +  g * (m / k)) * (1.0 -  (exp(((-k) / m) * t))) - g * t * (m / k);///значения по х для точного верле
 94         }
 95     }
 96 
 97 public: ///в открытом
 98     pad()
 99     {
100         X = 0; ///зануляем значения
101         Y = 0;
102         Size = 0;
103         v = 0;
104         shag = 0;
105         b = 0;
106     }
107     pad(double _v, double _shag, double _b) ///конструктор с параметрами
108     {
109         pi = M_PI; ///значение числа пи
110         g = 9.8; ///коэфф свободного падения
111         v = _v;/// присваиваем значения переменных значению параметров в конструкторе
112         shag = _shag;
113         b = _b;
114         a = (pi * b) / 180.0 ; ///вычисляем значение угла в радианах
115         double t = (2.0 * v * sin(a)) / g; /// считаем значение времени
116         Size = abs( t / shag )+1;///ищем значение размера массива
117         SetX(); ///вызываем функции зависящие от параметров конструктора
118         SetY();
119         SetVerle();
120         SetVerleLast();
121     }
122 
123     void FilePrint() ///функция записи в файл
124     {
125         ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
126         fout << "X:    " << "    Y:    " << "    E:   " << "   G:  " << "   S:  " << "   Z:  "<< "   V:   "<< "    U:    "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
127         for (int i = 0; i < Size; i++) ///цикл
128         fout << X[i] << "     " << Y[i] << "     " << E[i] << "    "  << G[i] << "   " << S[i] << "   " << Z[i] << "   " << V[i] <<"    "<< U[i] <<"\n"; ///забивает сами значения массивов
129         fout.close();///закрываем файл
130     };
131 };
132 
133 int main()/// основная функция
134 {
135     double shag, b, v; ///шаг, угол в градусах, скорость начальная
136     cout << "vvedite v "; ///просим пользователя ввести значение скорости начальной
137     cin >> v; ///считываем начальную скорость
138     cout << "vvedite ygol ";///просим пользователя ввести угол в градусах
139     cin >> b;/// считываем угол
140     cout << "vvedite shag ";///просим пользователя ввести шаг по времени
141     cin >> shag; ///считываем значение шага
142     pad F1(v, shag, b); ///объявление коструктора, создание функции F1 с переменными v, shag, b
143     F1.FilePrint(); ///вызываем функцию для записи файла
144 }

Гильманов Илья

Описание программы: программа состоит из четырех независимых друг от друга частей:

  1. Полет тела без сопротивления воздуха;
  2. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
  3. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  4. Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;

Скачать можно [тут]

Демченко Артём

Описание программы: программа записывает в четыре файла результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.

Инструкция : Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.



Визуализированный результат работы программы

File:Throws.png

  1 #include <iostream>
  2 #include <math.h>
  3 #include <iomanip>
  4 #include <fstream>
  5 #include <conio.h>
  6 #include <stdio.h>
  7 
  8 
  9 using namespace std;
 10 
 11 double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
 12 
 13 int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
 14 {
 15     FILE *Coord;
 16    Coord = fopen ("Throws Without Resistance.txt", "w");
 17      double X = 0, Y = 0; // Координаты начала
 18 
 19      while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
 20      {
 21 
 22       X =  Vo*t*cos(alpha);
 23       Y =  Vo*t*sin(alpha) - (g*t*t)*0.5;
 24       t+= dt;
 25     if (Y > Yo )
 26         fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 27     else
 28         fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
 29      }
 30 
 31 }
 32 
 33 int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
 34 {                                                                                          // для линейной зависимости
 35     FILE *Coord;
 36    Coord = fopen ("ExactForm.txt", "w");
 37     double X, Y = 0, Vx, Vy;
 38 
 39     while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
 40      {
 41 
 42       X = ((m*Vx)/R) * (1 - exp(((-1)*R*t)/m));
 43       Y = (m/R)*((Vy + (g*m)/R)*(1 - exp((-1)*R*t/m))) - (g*t*m)/R;
 44       Vx = Vo*cos(alpha);
 45       Vy = Vo*sin(alpha);
 46       t+= dt;
 47     if (Y > Yo )
 48         fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 49     else
 50         fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
 51       }
 52 }
 53 
 54 int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
 55 {                                                                                                    // для Квадратичной зависимости сопротивления от скорости
 56     FILE *Coord;
 57    Coord = fopen ("VerleSq.txt", "w");
 58 
 59     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
 60                                                                   // Xop, Yop - вспомогательные координаты для (-1)-го шага
 61 
 62     Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
 63     Xop = Xo - Vo*cos(alpha)*dt;
 64     X = Xo;
 65     Y = Yo;
 66     Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
 67     Vx = (1.0/(2.0*dt))*(Xnext - Xop);
 68     Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
 69     Vy =  (1.0/(2.0*dt))*(Ynext - Yop);
 70     V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
 71 
 72     fprintf(Coord, "%.3lf \t %.3lf\n", X, Y); // Записываем первую координату в файл
 73 
 74     Xprev = X; // Меняем координаты местами. Так (n-1)-ый шаг становится n-ым шагом, n-ый шаг становится (n+1)-ым шагом. Далее аналогично
 75     X = Xnext;
 76     Yprev = Y;
 77     Y = Ynext;
 78 
 79 
 80     while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
 81     {
 82     Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
 83     Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
 84     Ynext = 2.0*Y - Yprev - (g +(R/m)*V*Vy)*(dt*dt);
 85     Vy =  (1.0/(2.0*dt))*(Ynext - Yprev);
 86     V = sqrt((Vx*cos(alpha)*Vx*cos(alpha)) + (Vy*sin(alpha) - g*dt)*(Vy*sin(alpha) - g*dt));
 87     if (Ynext > Yo )
 88         fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
 89     else
 90 
 91        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
 92 
 93     Xprev = X;
 94     X = Xnext;
 95     Yprev = Y;
 96     Y = Ynext;
 97     }
 98 
 99 }
100 int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
101 {                                                                                                   // для линейной зависимости сопротивления от скорости
102     FILE *Coord;
103    Coord = fopen ("VerleL.txt", "w");
104 
105     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,Yop, Xop; // Комментарии аналогичны переменным и формулам в VtrleSq
106 
107     Yop = Yo - Vo*sin(alpha)*dt;
108     Xop = Xo - Vo*cos(alpha)*dt;
109     X = Xo;
110     Y = Yo;
111     Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
112     Vx = (1.0/(2.0*dt))*(Xnext - Xop);
113     Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
114     Vy =  (1.0/(2.0*dt))*(Ynext - Yop);
115     V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
116 
117     fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
118 
119     Xprev = X;
120     X = Xnext;
121     Yprev = Y;
122     Y = Ynext;
123 
124 
125     while (Y >= Yo)
126     {
127     Xnext = 2.0*X - Xprev - (R/m)*Vx*(dt*dt);
128     Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
129     Ynext = 2.0*Y - Yprev - (g +(R/m)*Vy)*(dt*dt);
130     Vy =  (1.0/(2.0*dt))*(Ynext - Yprev);
131    if (Ynext > Yo )
132         fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
133     else
134        fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, 0.000);
135 
136     Xprev = X;
137     X = Xnext;
138     Yprev = Y;
139     Y = Ynext;
140     }
141 
142 }
143 
144 int main()
145 {
146    double alpha, Vo, dt, R, m , t = 0, Yo = 0, Xo = 0; // Объявляем переменные: alpha - угол броска; Vo - начальная скорость; dt - шаг по времени; R- коэф. сопротивления; m- масса тела;
147                                                       // t = 0 - начало отсчета времени с 0; Yo = 0, Xo = 0 - координаты начала
148    int i = 0; // переменная для оператора switch
149 
150    cout << "Enter start speed:\n";
151    cin >> Vo; // Вводим с клавиатуры начальную скорость
152    cout << "Enter angle in grades ( from 0 to 180 ):\n";
153    cin >> alpha; // Вводим с клавиатуры угол броска в градусах
154    alpha = alpha*Pi / 180; // переводим угол броска из градусов в радианы
155    cout << "Enter mass:\n";
156    cin >> m; // Вводим с клавиатуры массу
157    cout << "Enter precision:\n";
158    cin >> dt; // Вводим с клавиатуры шаг по времени
159    cout << "Enter resistance:\n";
160    cin >> R; // Вводим сопротивление воздуха
161    cout << "Press 1 to draw graph without resistance\n\n"
162            "Press 2 to draw graph in Exact form\n\n"
163            "Press 3 to draw graph in VerleSq form\n\n"
164            "Press 4 to draw graph in VerleL form\n\n"
165            "Press 5 to draw all graphs at the same time\n\n"
166            "Press 0 to quit\n\n";
167    cin >> i;
168    cout << "\nPress any button\n";
169 
170 
171     FILE *Gnu;
172     Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
173 
174  switch ( i )
175  {
176  case 1:
177      {
178     WoutR(alpha,dt,t,Yo,Vo);
179     fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
180     break;
181      }
182  case 2:
183      {
184     ExactForm(alpha,dt,t,Yo,Vo,R,m);
185     fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
186     break;
187      }
188  case 3:
189      {
190     VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
191     fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
192     break;
193      }
194  case 4:
195      {
196     VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
197     fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
198     break;
199      }
200  case 5:
201      {
202    WoutR(alpha,dt,t,Yo,Vo);
203    ExactForm(alpha,dt,t,Yo,Vo,R,m);
204    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
205    VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
206    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 названия четырех файлов
207    break;
208      }                                                   // с координатами таким образом, чтобы программа gnuplot смогла их увидеть и прочесть
209  case 0:
210     break;
211  default:
212     break;
213  }
214     return 0;
215 }


Иванова Яна

Описание программы: в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде. Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.

Скачать программу можно здесь

Визуализированный результат работы программыGraph.png

File:graph.png
  1 #include <iostream>
  2 #include <math.h>
  3 #include <iomanip>
  4 #include <fstream>
  5 #include <conio.h>
  6 
  7 
  8 using namespace std;
  9 
 10 ofstream outfile;
 11 
 12 double perevod (double angle) //перевод из градусов в радианы
 13 {
 14     return (angle * M_PI / 180 );
 15 }
 16 
 17 
 18 int main()
 19 {
 20     //объявление переменных и задание начальных значений
 21     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
 22     m = 1 , dt = 0.1 , g = 9.8,t = 0,
 23     ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
 24 
 25     alpha = perevod (ugol);
 26 
 27     //точное решение для случая движения без сопротивления воздуха
 28     Y = Yo;
 29     X = Xo;
 30 
 31     outfile.open("1.txt");
 32 
 33     while (Y >= Yo)
 34     {
 35         X = Xo + Vo * cos(alpha) * t;
 36         Vx = Vo * cos(alpha);
 37         Y = Yo + Vo * sin(alpha) * t  - 0.5 * g * t * t;
 38         Vy = Vo * sin(alpha) - g * t;
 39         t += dt;
 40 
 41         outfile << X << ' ' << Y << endl;
 42     }
 43     outfile.close();
 44 
 45     //начальные условия для квадратичной зависимости (метод Верле)
 46     Yprev = Yo - Vo*sin(alpha)*dt;
 47     Xprev = Xo - Vo*cos(alpha)*dt;
 48     X = Xo;
 49     Y = Yo;
 50     V = Vo;
 51     Vx = Vo * cos(alpha);
 52     Vy = Vo * sin(alpha);
 53 
 54     outfile.open("2.txt");
 55 
 56     while (Y >= Yo)
 57     {
 58         Xnext = 2.0 * X - Xprev - (R / m) * V * Vx * (dt * dt);
 59         Vx = ( Xnext - Xprev )/ (2.0 * dt);
 60         Ynext = 2.0 * Y - Yprev - (g + (R / m) * V * Vy) * (dt * dt);
 61         Vy =  (Ynext - Yprev)/ (2.0 * dt);
 62         V = sqrt(Vy*Vy + Vx*Vx );
 63         outfile << X << ' ' << Y << endl;
 64 
 65         Xprev = X;
 66         X = Xnext;
 67         Yprev = Y;
 68         Y = Ynext;
 69     }
 70     outfile.close();
 71 
 72     //начальные условия для линейной зависимости (метод Верле)
 73     Yprev = Yo - Vo*sin(alpha)*dt;
 74     Xprev = Xo - Vo*cos(alpha)*dt;
 75     X = Xo;
 76     Y = Yo;
 77     V = Vo;
 78     Vx = Vo * cos(alpha);
 79     Vy = Vo * sin(alpha);
 80 
 81     outfile.open("3.txt");
 82 
 83     while (Y >= Yo)
 84     {
 85         Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
 86         Vx = ( Xnext - Xprev )/ (2.0 * dt);
 87         Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
 88         Vy =  (Ynext - Yprev)/ (2.0 * dt);
 89         V = sqrt(Vy*Vy + Vx*Vx );
 90         outfile << X << ' ' << Y << endl;
 91 
 92         Xprev = X;
 93         X = Xnext;
 94         Yprev = Y;
 95         Y = Ynext;
 96     }
 97     outfile.close();
 98 
 99     //точное решения для линейной зависимости
100     Y = Yo;
101     X = Xo;
102     t = 0;
103 
104     outfile.open("4.txt");
105 
106     while (Y >= Yo)
107     {
108         Vx = Vo * cos(alpha);
109         Vy = Vo * sin(alpha);
110         X = (m * Vx / R)* (1 - exp(-1 * R * t / m));
111         Y = (m/R)*((Vy + g * m / R)*(1 - exp(-1 * R * t / m)) - g * t);
112         t += dt;
113         outfile << X << ' ' << Y << endl;
114     }
115     outfile.close();
116 
117     return 0;
118 
119 }

Капитанюк Светлана

Описание программы : программа записывает в четыре файла результаты вычисления:

Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.

Скачивать тут

Киселёв Лев

Описание программы: программа рассчитывает координаты точки при следующих случаях

  1. Полет тела без сопротивления воздуха;
  2. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
  3. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  4. Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;

Скачать можно [тут]

Лебедев Станислав

Описание программы: программа записывает в четыре файла результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.

Скачать можно тут.

1.png


Визуализированный результат работы программы Graph.png

  1. o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.


Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;

Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.

Файл "main.cpp"

  1 #include <iostream>
  2 #include <math.h>
  3 #include "Vector.h"
  4 #include <cstring>
  5 #include <cmath>
  6 #include <malloc.h>
  7 #include <fstream>
  8 
  9 using namespace std;
 10 
 11 int n = 100;
 12 ofstream outfile;
 13 
 14 class Ball                                          //класс бросаемого тела
 15 {
 16     private:
 17         double angle,m,k;                           //угол броска,масса,коэффицент сопротивления воздуха
 18         Vector3D r,v,a;                             //радиус-вектор,вектор скорости,ускорения
 19     public:
 20 
 21         //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
 22         Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
 23         {
 24             angle = _angle;
 25             r     = _r;
 26             v     = _v;
 27             a     = _a;
 28         }
 29 
 30          //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
 31         Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
 32         {
 33             angle = _angle;
 34             r     = _r;
 35             v     = _v;
 36             a     = _a;
 37             m     = _m;
 38             k     = _k;
 39         }
 40 
 41         //точная формула зависимости координаты от времени
 42         Vector3D positionReal(double t)
 43         {
 44             double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
 45             return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
 46         }
 47 
 48         //вывод положения на экран
 49         void writePosToScreen()
 50         {
 51             cout << r.x << "   " << r.y << "   " << r.z << endl;
 52         }
 53 
 54         //вывод положения в файл
 55         void writePosToFile(char s[])
 56         {
 57             outfile.open(s,ios :: app);
 58             outfile << r.x << "           " << r.y << endl;
 59             outfile.close();
 60         }
 61 
 62         //вывод произвольного вектора на экран
 63         void WVTS(Vector3D v)
 64         {
 65             cout.width(15);
 66             cout << v.x;
 67             cout.width(15);
 68             cout << v.y;
 69             cout.width(15);
 70             cout << v.z << endl;
 71         }
 72 
 73         //вывод произвольного вектора в файл
 74         void WVTF(Vector3D v,char s[])
 75         {
 76             outfile.open(s,ios :: app);
 77             outfile << v.x << "           " << v.y << endl;
 78             outfile.close();
 79         }
 80 
 81         //"пересчет" координаты по Верле(Линейная зависмость)
 82         void changeR(Vector3D r1, double dt)
 83         {
 84             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 );
 85         }
 86 
 87         //"пересчет" координаты по Верле(Квадратичная зависимость)
 88         void changeRSQ(Vector3D r1, double dt)
 89         {
 90             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 );
 91         }
 92         //пересчет скорости по Верле
 93         void changeV(Vector3D r1,double dt)
 94         {
 95             v =VS((VmV(r,r1)),1/(2*dt));
 96         }
 97 
 98         //рассчет предыдущегт к 0ому элементу
 99         Vector3D MR1(double dt)
100         {
101             return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
102         }
103 
104         //возращает координату тела
105         Vector3D getR()
106         {
107             return r;
108         }
109 
110         //рассчет времени полета
111         double TimeOfFly()
112         {
113             return (2*Length(v)*sin(angle)/Length(a));
114         }
115 
116         //рассчет координаты по точной формуле. без сопротивления воздуха.
117         Vector3D position(double t)
118         {
119             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);
120         }
121 
122 };
123 
124 int main()
125 {
126     //задание начальных параметров
127     Vector3D g = {0,-9.8,0};
128     double a,dt = 0;
129     char s[20];
130 
131 //    cin >> dt;
132 
133     dt = 0.1;
134     a = (M_PI * 30)/180;
135     Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
136 
137     double tof = b1.TimeOfFly()+1;   //единичка прибавлена,чтобы график красивым был
138 
139     //Без сопротивления возлуха
140     strcpy(s,"");
141     strcat(s, "o1.txt");
142     outfile.open(s, ios :: trunc);
143     outfile.close();
144     for (double i = 0; i <= tof; i += dt)
145     {
146         b1.WVTS(b1.position(i));
147         b1.WVTF(b1.position(i), s);
148     }
149 
150 
151     //Верле(Линейная зависимость)
152     dt = 0.1;
153     a = (M_PI * 30)/180;
154     Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
155 
156     strcpy(s,"");
157     strcat(s, "o2.txt");
158     outfile.open(s,ios :: trunc);
159     outfile.close();
160     Vector3D r1 = b2.MR1(dt),rp;
161     for (double i = 0; i <= 20; i += dt)
162     {
163         rp = b2.getR();
164         b2.writePosToFile(s);
165         b2.writePosToScreen();
166         b2.changeR(r1,dt);
167         b2.changeV(r1,dt);
168         r1.x = rp.x;
169         r1.y = rp.y;
170     }
171 
172     //Точное решение (Линейная зависимость)
173     dt = 0.1;
174     a = (M_PI * 30)/180;
175     Ball b3(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
176 
177     strcpy(s,"");
178     strcat(s, "o3.txt");
179     outfile.open(s, ios :: trunc);
180     outfile.close();
181     for (double i = 0; i <= 20; i += dt)
182     {
183         b3.WVTS(b3.positionReal(i));
184         b3.WVTF(b3.positionReal(i), s);
185     }
186 
187 
188     //Верле (Квадратичная зависимость)
189     dt = 0.1;
190     a = (M_PI * 30)/180;
191     Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
192 
193     strcpy(s,"");
194     strcat(s, "o4.txt");
195     outfile.open(s, ios :: trunc);
196     outfile.close();
197     r1 = b4.MR1(dt);
198     for (double i = 0; i <= 20; i += dt)
199     {
200         rp = b4.getR();
201         b4.writePosToFile(s);
202         b4.writePosToScreen();
203         b4.changeRSQ(r1,dt);
204         b4.changeV(r1,dt);
205         r1.x = rp.x;
206         r1.y = rp.y;
207     }
208 
209     return 0;
210 }

Файл "Vector.h"

 1 #ifndef VECTOR_H_INCLUDED
 2 #define VECTOR_H_INCLUDED
 3 
 4 struct Vector3D
 5 {
 6    double x,y,z;
 7 };
 8 
 9 Vector3D VmV(Vector3D v1,Vector3D v2)               //векторное вычитание
10 {
11     Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
12     return v;
13 };
14 Vector3D VpV(Vector3D v1,Vector3D v2)               //векторное сложение
15 {
16     Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
17     return v;
18 }
19 
20 double VV(Vector3D v1,Vector3D v2)               //скалярное умножение
21 {
22   return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
23 }
24 
25 Vector3D VxV(Vector3D v1,Vector3D v2)               //векторное умножение
26 {
27   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};
28   return v;
29 }
30 
31 bool Kol(Vector3D v1,Vector3D v2)
32 {
33   return ((v1.x/v2.x == v1.y/v2.y)&&(v1.z/v2.z == v1.y/v2.y))? true:false;
34 }
35 
36 Vector3D VS(Vector3D v1, double s)
37 {
38     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
39     return v;
40 }
41 
42 double Length(Vector3D v1)
43 {
44     return sqrt(VV(v1,v1));
45 }
46 
47 Vector3D MakeVector(double x,double y,double z)
48 {
49     Vector3D v = {x,y,z};
50     return v;
51 }
52 
53 Vector3D MakeVector(double length,double angle)
54 {
55     Vector3D v = {length * cos(angle), length * sin(angle),0};
56     return v;
57 }
58 
59 double Proection(Vector3D base, Vector3D dir)
60 {
61     return (VV(base,dir)/Length(base));
62 }
63 #endif // VECTOR_H_INCLUDED


Лобанов Илья

Описание программы : программа записывает в четыре файла результаты вычисления:

Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.


Краткая инструкция:

В окне консоли пользователю предлагается вывести следующие значения: начальную скорость , угол и шаг. После этого полученные в результате работы программы данные выводятся в файл.

Скачивать [тут] [тут]

Лосева Татьяна

Описание: Пользователя попросят ввести начальную скорость,угол бросания,массу тела и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  4. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;

Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;

Загружено (1).pngFile:загружено (1).png

  1 #include<iostream>
  2 using namespace std;
  3 #define N 1
  4 #define PI 3.14159265
  5 #include <fstream>
  6 #include<cmath>
  7 double g=9.8;
  8 double step=0.01;
  9 #include<math.h>
 10 
 11 void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 12 
 13 {
 14 	double x,y;
 15 	
 16 	ofstream fout;//открытие файла
 17 		   fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
 18 	cout<<"method1"<<endl;
 19 
 20 	   for(double t=0.01;t<N;t=t+0.01)
 21 		{
 22 			y=v*t*sin(r*PI/ 180)-g*t*t/2;//координата y
 23 			x=v*t*cos(r*PI / 180);//координата х
 24 			  
 25 				fout<<x<<"   ";//запись в файл х
 26 				cout<<"X="<<x<<endl;//вывод на экран
 27 			    fout<<y<<"    ";//запись в файл 
 28 				cout<<"Y="<<y<<endl<<endl;//вывод на экран
 29 				fout<<endl;
 30 		   }
 31 }
 32 		   
 33 void Verle1( double n,double m ,double v0,double r)//Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 34 
 35 { 
 36 	double x,y,x0=0,y0=0,xn_1,yn_1;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
 37 
 38 	double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
 39    double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
 40 
 41    xn_1=x0-vx*step;//X(n-1) для первого случая n=0
 42    yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
 43    ofstream fout;//открытие файла
 44  fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
 45 	cout<<"Verle1"<<endl<<endl;
 46 	for(double t=0.02;t<N;t=t+step)
 47 	{
 48 		x=2*x0-xn_1-(n*vx*step*step)/m;//считаем Хn+1
 49 		vx=(x-xn_1)/(2*step);
 50         xn_1=x0;//для следущего шага Xn-1=Xn
 51         x0=x;//для следущего шага Xn=Xn+1
 52 		
 53 		y=2*y0-yn_1-(g+(n*vy)/m)*step*step;//Yn+1
 54 		vy=(y-yn_1)/(2*0.01);//скорость 
 55 		yn_1=y0;//для следущего шага Yn-1=Yn
 56 		y0=y;//для следущего шага Yn=Yn+1
 57      	cout<<"X="<<x<<endl;
 58 		cout<<"Y="<<y<<endl<<endl;
 59     	fout<<x<<" ";
 60 		fout<<y<<"  ";
 61 		fout<<endl; 
 62 		
 63 
 64 	}
 65 }
 66 
 67 	void Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 68 
 69 { 
 70 	double x,y,x0=0,y0=0,xn_1,yn_1,v;//x0,y0=Xn,Yn начальные значения;xn_1=X(n-1);yn_1=Y(n-1);
 71 
 72 	double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
 73    double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
 74 
 75    xn_1=x0-vx*step;//X(n-1) для первого случая n=0
 76    yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
 77    ofstream fout;//открытие файла
 78   fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
 79 		cout<<"Verle2"<<endl<<endl;
 80 	for(double t=0.02;t<N;t=t+step)
 81 	{
 82 
 83 	   v=sqrt(vx*vx+vy*vy);//скорость V
 84 
 85 		x=2*x0-xn_1-(n*v*vx*step*step)/m;//Xn+1
 86 		vx=(x-xn_1)/(2*step);//скорость Vx
 87         xn_1=x0;//для следущего шага Xn-1=Xn
 88 		x0=x;//для следущего шага Xn=Xn+1
 89 		
 90 		y=2*y0-yn_1-(g+(n*vy*v)/m)*step*step;//Yn+1
 91 		vy=(y-yn_1)/(2*0.01);//скорость Vy
 92 		yn_1=y0;//для следущего шага Yn-1=Yn
 93 		y0=y;//для следущего шага Yn=Yn+1
 94 		cout<<"X="<<x<<endl;
 95 		cout<<"Y="<<y<<endl<<endl;
 96 		fout<<x<<" ";
 97 		fout<<y<<"  ";
 98 		fout<<endl; 
 99 	}
100 	
101 }
102 
103 void method4(double n,double m ,double v0,double r)//Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
104 {
105 	double x,y,x0=0,y0=0;//x0,y0 начальные значения;
106 
107  double vx=v0*cos(r*PI / 180);//рассчитваем Vx 
108   double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vy
109   
110    ofstream fout;//открытие файла
111   fout.open("C:\\Users\\Light\\Desktop\\4.txt");
112 	cout<<"4"<<endl<<endl;
113 	for(double t=0.01;t<N;t=t+step)
114 	{
115 		x=x0+m*vx*(1-(exp((-1*n)*t/m)))/n;//координата х
116 		
117 		y = y0+(m/n)*((vy + g * m / n)*(1 - exp(-1 * n * t / m))) - g * t*m/n;//координата у
118 
119 		//вывод в файл  и на экран
120      	cout<<"X="<<x<<endl;
121 		cout<<"Y="<<y<<endl<<endl;
122 		fout<<x<<" ";
123 		fout<<y<<" ";
124 		fout<<endl; 
125 
126 	}
127 }
128 	   
129 int main(void)
130 {
131 
132 	double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
133 
134 	cout<<"Enter  start speed:"<<endl;
135 	cin>>v0;
136 	cout<<"Enter angle less than 90 deg:"<<endl;
137 	cin>>r;
138 	cout<<"Enter mass:"<<endl;
139 	cin>>m;
140 	cout<<"Coefficient of resistance:"<<endl;
141 	cin>>n;
142 	
143 	Func(v0,r);
144 	Verle1(n,m,v0,r);
145 	Verle2(n,m,v0,r);
146 	method4(n,m,v0,r);
147 
148 
149 
150 	int k;
151 	cin>>k;
152 		return 0;
153 }

Скачать можно тут.

Ляжков Сергей

Описание программы: Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится). Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ... Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться. Скачать можно [тут]


Нарядчиков Александр
Инструкция: Пользователю достаточно просто запустить программу.
Описание программы: В комнате скачут 4 мячика, первый двигается без сопротивления воздуха, второй двигается с квадратичной зависимостью сопротивления воздуха от скорости (Метод Верле), третий двигается с линейной зависимостью сопротивления воздуха от скорости (точное решение), четвертый двигается с линейной зависимостью сопротивления воздуха от скорости (Метод Верле).
Описание алгоритма: Программа реализована с помощью системы анимации(class anim), используя библиотеки OpenGl и GLUT. Изменения координат мячей проходят в режиме реального времени в векторной форме.

"T06BALL.CPP"

 1 /* FILENAME: T06BALL.CPP
 2  * LAST UPDATE: 17.01.2016
 3  */
 4 
 5 #include "ANIM.H"
 6 #include "SAMPLE.H"
 7 
 8 /* Main function */
 9 void main( void )
10 {
11 	// Получение единственного экземпляра класса анимации
12 	sagl::anim &My = sagl::anim::Get();
13   
14 	// Шар, летящий без сопротивлением воздуха
15         for (int i = 0; i < 1; i++)
16                 My << new ball(Pi / 6, 10 + i);
17 
18 	// Шар, летящий с сопротивлением воздуха
19 	// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
20 	for (int i = 0; i < 1; i++)
21 		My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
22 
23 	// Шар, летящий с сопротивлением воздуха
24 	// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
25 	for (int i = 0; i < 1; i++)
26 		My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
27 
28 	// Шар, летящий с сопротивлением воздуха
29 	// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
30 	for (int i = 0; i < 1; i++)
31 		My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
32 
33 	// Запуск главного цикла
34   My.Run();
35 } // End of 'main' function
36 
37 // END OF 'T43ANIM.CPP' FILE

"ANIM.CPP"

  1 /* FILENAME: ANIM.CPP
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <time.h>
  8 
  9 #include "ANIM.H"
 10 
 11 // Единственный экземпляр класса
 12 sagl::anim sagl::anim::Instance;
 13 
 14 /* Reshape function */
 15 // Стандартная функция, вызываемая при изменении размеров окна
 16 void sagl::anim::Reshape( int W, int H )
 17 {
 18   // Установка области просмотра - все окно
 19 	glViewport(0, 0, W, H);
 20   Instance.WinW = W;
 21   Instance.WinH = H;
 22   double ratio_x = 1, ratio_y = 1;
 23   if (W > H)
 24     ratio_x = (double)W / H;
 25   else
 26     ratio_y = (double)H / W;
 27   double Size = 1, Near = 1, Far = 500;
 28   // Установка системы координат "камеры"
 29 	glMatrixMode(GL_PROJECTION);
 30   glLoadIdentity();
 31   glFrustum(-Size * ratio_x, Size * ratio_x,
 32             -Size * ratio_y, Size * ratio_y,
 33             Near, Far);
 34 	// Установка "мировой" СК в состояние без преобразований
 35   glMatrixMode(GL_MODELVIEW);
 36 } // End of 'Reshape' function
 37 
 38 /* Timer function */
 39 // Подсчет времени
 40 void sagl::anim::Timer( void )
 41 {
 42   long Time = clock();
 43   
 44   if (IsPause)
 45     DeltaTime = 0, PauseTime += Time - OldTime;
 46   else
 47     DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC; 
 48   OldTime = Time;
 49 
 50   SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
 51 } /* End of 'Timer' function */
 52 
 53 /* Display function */
 54 // Стандартная функция, вызываемая при перерисовке окна
 55 void sagl::anim::Display( void )
 56 {
 57 	// Запуск времени
 58 	Instance.Timer();
 59 	// Очищаем цветовой буфер для создания нового изображения
 60   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 61 
 62   glLoadIdentity();
 63   // Позиционирование СК
 64 	gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
 65 
 66 	// Отрисовка объектов
 67   Instance.Render();
 68 
 69   glFinish();
 70 	// Копируем вторичный буфер в окно
 71 	glutSwapBuffers();
 72 	// Вызываем функцию обновления кадра
 73 	glutPostRedisplay();
 74 } // End of 'Display' function
 75 
 76 /* Keyboard function */
 77 // Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 78 void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
 79 {
 80 	// Выход из программы
 81 	if (Key == 27)
 82     exit(0);
 83 	// Открытие программы в полном экране
 84 	else if (Key == 'f')
 85     glutFullScreen();
 86   // Пауза
 87 	else if (Key == 'p' || Key == 'P')
 88     Instance.IsPause = !Instance.IsPause;
 89 } // End of 'Keyboard' function
 90 
 91 sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
 92   StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
 93 {
 94 	// Инициализации OpenGL и GLUT
 95 	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 96   
 97 	// Задача размеров и позиции окна
 98 	glutInitWindowPosition(0, 0);
 99   glutInitWindowSize(700, 700);
100 	// Создание окна
101 	glutCreateWindow("T06BALL");
102 
103 	// Установка функций 'обратного вызова'
104   glutDisplayFunc(Display);
105   glutKeyboardFunc(Keyboard);
106   glutReshapeFunc(Reshape);
107 
108 	// Установка цвета закраски фона
109   glClearColor(0.3, 0.5, 0.7, 1);
110   // Включение буфера глубины
111 	glEnable(GL_DEPTH_TEST);
112   // Включение режима вычисления цвета согласно освещенности от источников света
113 	glEnable(GL_LIGHTING);
114 	// Включение источника света
115   glEnable(GL_LIGHT0);
116 	// Включение упрощенного режима освещенности для простого способа описания свойств поверхности
117   glEnable(GL_COLOR_MATERIAL);
118 	// Приведение нормалей к единичной длине
119   glEnable(GL_NORMALIZE);
120 }
121 
122 // Деструктор
123 sagl::anim::~anim( void )
124 {
125   // Чистка памяти
126 	for (int i = 0; i < StockSize; i++)
127     delete Stock[i];
128 }
129 
130 /* Render function */
131 // Отрисовка объектов
132 void sagl::anim::Render( void )
133 {
134 	for (int i = 0; i < StockSize; i++)
135 		Stock[i]->Render(*this);
136 } // End of 'Render' function
137 
138 /* Run function */
139 // Запуск главного цикла
140 void sagl::anim::Run( void )
141 {
142 	// Запуск основного цикла построения
143 	glutMainLoop();
144 } // End of 'Run' function
145 
146 // END OF 'ANIM.CPP' FILE

"ANIM.H"

  1 /* FILENAME: ANIM.H
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #ifndef __ANIM_H_
  6 #define __ANIM_H_
  7 
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <time.h>
 11 
 12 #include <GL\glut.h>
 13 
 14 #include "VEC.H"
 15 
 16 // Константы
 17 #define Pi 3.14159265358979323846
 18 #define E 2.71828182845904523536 
 19 
 20 // Собственное пространство имен 'sagl'
 21 namespace sagl
 22 {
 23   // Объявления класса анимации наперед
 24 	class anim;
 25   
 26 	// Функции получения случайных чисел
 27 	inline double r0( void )
 28   {
 29     return rand() / (double)RAND_MAX;
 30   }
 31   inline double r1( void )
 32   {
 33     return 2.0 * rand() / RAND_MAX - 1;
 34   }
 35   
 36 	// Класс объектов
 37 	class object
 38   {
 39   public:
 40     // Вектора перемещения и скоростей
 41 		vec P, V, AbsV;
 42     
 43 		// Конструктор
 44 		object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
 45     {
 46     }
 47 		
 48 		// Отрисовка объектов
 49 		virtual void Render( anim &Ani )
 50     {
 51     } // End of 'Render' function
 52   }; // end of 'object' class
 53   
 54 	// Класс анимации
 55 	class anim
 56   {
 57   private:
 58     // Функции 'обратного вызова'
 59 		static void Display( void );
 60     static void Keyboard( unsigned char Key, int X, int Y );
 61     static void Reshape( int W, int H );
 62 
 63     // Единственный экземпляр класса
 64 		static anim Instance;
 65     
 66     // Конструктор
 67 		anim( void );
 68 
 69 		// Максимальное количество объектов
 70     static const int Max = 100;
 71     // 'Контейнер' объектов
 72 		object *Stock[Max];
 73     // Размер 'контейнера' объектов
 74 		int StockSize;
 75     
 76 		// Переменные, хранящие время в секундах
 77     long StartTime, OldTime, PauseTime;
 78     
 79 		// Отрисовка объектов
 80 		void Render( void );
 81 		
 82 		// Подсчет времени
 83 		void Timer( void );
 84   public:
 85     // Добавление объектов в 'контейнер'
 86 		anim & operator<<( object *Obj )
 87     {
 88       if (StockSize < Max )
 89         Stock[StockSize++] = Obj;
 90       else 
 91         delete Obj;
 92       
 93 			return *this;
 94     }
 95     
 96 		// Ширина и высота окна
 97     int WinW, WinH;
 98 
 99 		// Переменные, хранящие время в секундах
100     double SyncTime, DeltaTime;
101 
102     // Переменная, отвечающая за паузу
103 		bool IsPause;
104 
105     // Деструктор
106 		~anim( void );
107     
108 		// Запуск главного цикла
109 		void Run( void );
110     
111     // Метод, возвращающий переменную - единственный экземпляр данного типа
112 		static anim & Get( void )
113     {
114       return Instance;
115     }
116   }; // end of 'anim' class
117 } // end of 'sagl' namespace
118 
119 #endif /*__ANIM_H_ */
120 
121 // END OF 'ANIM.H' FILE

"VEC.H"

 1 /* FILENAME: VEC.H
 2  * LAST UPDATE: 17.01.2016
 3  */
 4 
 5 #ifndef __VEC_H_
 6 #define __VEC_H_
 7 
 8 #include <stdlib.h>
 9 #include <math.h>
10 
11 // Собственное пространство имен 'sagl'
12 namespace sagl
13 {
14   // Класс векторов
15 	class vec
16   {
17   public:
18     // Координаты вектора
19 		double X, Y, Z;
20     
21 		// Конструктор
22 		vec( void ) : X(0), Y(0), Z(0)
23     {
24     }
25     
26 		// Конструктор
27 		vec( double A, double B, double C ) : X(A), Y(B), Z(C)
28     {
29     }
30     
31 		// Функции получения случайных чисел
32 		static double R0( void )
33     {
34       return rand() / (double)RAND_MAX;
35     }
36     
37 		static double R1( void )
38     {
39       return 2 * rand() / (double)RAND_MAX - 1;
40     }
41     
42 		// Функции получения случайных векторов
43 		static vec Rnd( void )
44     {
45       return vec(R0(), R0(), R0());
46     }
47     
48 		static vec Rnd1( void )
49     {
50       return vec(R1(), R1(), R1());
51     }
52 		
53 		vec operator+( vec V )
54 		{
55 			return vec(X + V.X, Y + V.Y, Z + V.Z);
56 		}
57 		
58 		vec operator*( double t )
59     {
60       return vec(X * t, Y * t, Z * t);
61     }
62     
63 		vec & operator+=( const vec &V )
64     {
65       X += V.X;
66       Y += V.Y;
67       Z += V.Z;
68       
69 			return *this;
70     }
71 		
72 		// Длина вектора
73 		double operator!(void) const
74 		{
75 			return sqrt(X * X + Y * Y + Z * Z);
76 		} /* end of 'operator!' function */
77   }; // end of 'vec' class
78 } // end of 'sagl' namespace
79 
80 #endif /*__VEC_H_ */
81 
82 // END OF 'VEC.H' FILE

"SAMPLE.H"

  1 /* FILENAME: SAMPLE.H
  2  * LAST UPDATE: 17.01.2016
  3  */
  4 
  5 #ifndef __SAMPLE_H_
  6 #define __SAMPLE_H_
  7 
  8 #include <math.h>
  9 
 10 #include "ANIM.H"
 11 
 12 // Шар, летящий без сопротивлением воздуха
 13 class ball : public sagl::object
 14 {
 15 private:
 16   double angle, v; // угол вектора скорости к горизонту; модуль скорости
 17 public:
 18   // Конструктор
 19 	ball( void ) : angle(Pi / 3), v(1)
 20   {
 21 		P = sagl::vec(sagl::r0() + 5, 5, 0);
 22 		V.X = 0;
 23 		V.Y = sin(angle) * v;
 24 		V.Z = cos(angle) * v;
 25   }
 26 	
 27 	// Конструктор
 28 	ball( double angle1, double v1 ) : angle(angle1), v(v1)
 29 	{
 30 		P = sagl::vec(sagl::r0() + 5, 5, 0);
 31 		V.X = 0;
 32 		V.Y = sin(angle) * v;
 33 		V.Z = cos(angle) * v;
 34 	}
 35   
 36 	// Отрисовка объекта
 37 	void Render( sagl::anim &Ani )
 38   {
 39 		// Вектор ускорения свободного падения
 40 		sagl::vec g = sagl::vec(0, -9.8, 0);
 41 		// Размер комнаты
 42 		double Size = 120;
 43 
 44 		// Изменение вектора скорости
 45 		V += g * Ani.DeltaTime;
 46 		// Изменение вектора перемещения
 47 		P += V * Ani.DeltaTime;
 48 
 49 		// Ограничения - стенки
 50 		if (P.X > Size / 4)
 51 			V.X = -fabs(V.X);
 52 		if (P.X < -Size / 4)
 53 			V.X = fabs(V.X);
 54 
 55 		if (P.Y > Size / 4)
 56 			V.Y = -fabs(V.Y);
 57 		if (P.Y < -Size / 4)
 58       V.Y = fabs(V.Y);
 59 
 60 		if (P.Z > Size / 4)
 61 			V.Z = -fabs(V.Z);
 62 		if (P.Z < -Size / 4)
 63 			V.Z = fabs(V.Z);
 64 		
 65     // Запоминание состояния изменения текущей СК
 66 		glPushMatrix();
 67 		
 68 		// Рисование стенок
 69 		glutWireCube(Size / 2);
 70 		// Задача перемещения мяча
 71 		glTranslated(P.X, P.Y, P.Z);
 72     // Цвет мяча
 73 		glColor3d(0, 1, 0);
 74 		// Рисование мяча
 75 		glutSolidSphere(0.5, 30, 30);
 76     
 77 		// Восстановление последнего запоминания состояния изменения текущей СК
 78 		glPopMatrix();
 79   }
 80 }; // end of 'ball' class
 81 
 82 // Шар, летящий с сопротивлением воздуха
 83 // Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 84 class ball_air : public sagl::object
 85 {
 86 private:
 87 	double angle, v, m, n;
 88 public:
 89 	// Конструктор
 90 	ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 91 	{
 92 		P = sagl::vec(sagl::r0() + 5, 5, 0);
 93 		V.X = 0;
 94 		V.Y = sin(angle) * v;
 95 		V.Z = cos(angle) * v;
 96 	}
 97 	
 98 	// Конструктор
 99 	ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
100 	{
101 		P = sagl::vec(sagl::r0() + 5, 5, 0);
102 		V.X = 0;
103 		V.Y = sin(angle) * v;
104 		V.Z = cos(angle) * v;
105 	}
106 	
107 	// Отрисовка объекта
108 	void Render( sagl::anim &Ani )
109 	{
110 		// Вектор ускорения свободного падения и вектор полного ускорения
111 		sagl::vec g = sagl::vec(0, -9.8, 0), a;
112 		// Размер комнаты
113 		double Size = 120;
114 
115 		// Изменение вектора ускорения
116 		a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
117 
118 		// Изменение вектора скорости
119 		V += a * Ani.DeltaTime;
120 		// Изменение вектора перемещения
121 		P += V * Ani.DeltaTime;
122 
123 		// Ограничения - стенки
124 		if (P.X > Size / 4)
125 			V.X = -fabs(V.X);
126 		if (P.X < -Size / 4)
127 			V.X = fabs(V.X);
128 
129 		if (P.Y > Size / 4)
130 			V.Y = -fabs(V.Y);
131 		if (P.Y < -Size / 4)
132 			V.Y = fabs(V.Y);
133 
134 		if (P.Z > Size / 4)
135 			V.Z = -fabs(V.Z);
136 		if (P.Z < -Size / 4)
137 			V.Z = fabs(V.Z);
138 			
139 		// Запоминание состояния изменения текущей СК
140 		glPushMatrix();
141 		
142 		// Рисование стенок
143 		glutWireCube(Size / 2);
144 		// Задача перемещения мяча
145 		glTranslated(P.X, P.Y, P.Z);
146 		// Цвет мяча
147 		glColor3d(1, 0, 0);
148 		// Рисование мяча
149 		glutSolidSphere(0.5, 30, 30);
150 		
151 		// Восстановление последнего запоминания состояния изменения текущей СК
152 		glPopMatrix();
153 	}
154 }; // end of 'ball_air' class
155 
156 // Шар, летящий с сопротивлением воздуха
157 // Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
158 class ball_air_2 : public sagl::object
159 {
160 private:
161 	double angle, v, m, n;
162 public:
163 	// Конструктор
164 	ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
165 	{
166 		P = sagl::vec(sagl::r0() + 5, 5, 0);
167 		V.X = 0;
168 		V.Y = sin(angle) * v;
169 		V.Z = cos(angle) * v;
170 	}
171 	
172 	// Конструктор
173 	ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
174 	{
175 		P = sagl::vec(sagl::r0() + 5, 5, 0);
176 		V.X = 0;
177 		V.Y = sin(angle) * v;
178 		V.Z = cos(angle) * v;
179 	}
180 	
181 	// Отрисовка объекта
182 	void Render( sagl::anim &Ani )
183 	{
184 		// Вектор ускорения свободного падения и вектор полного ускорения
185 		sagl::vec g = sagl::vec(0, -9.8, 0), a;
186 		// Размер комнаты
187 		double Size = 120;
188 
189 		// Изменение вектора скорости
190 		V.Z = V.Z * exp(-n / m * Ani.DeltaTime);
191 		V.Y = (V.Y - g.Y * m / n) * exp(-n / m * Ani.DeltaTime) + g.Y * m / n;
192 		// Изменение вектора перемещения
193 		P += V * Ani.DeltaTime;
194 
195 		// Ограничения - стенки
196 		if (P.X > Size / 4)
197 			V.X = -fabs(V.X);
198 		if (P.X < -Size / 4)
199 			V.X = fabs(V.X);
200 
201 		if (P.Y > Size / 4)
202 			V.Y = -fabs(V.Y);
203 		if (P.Y < -Size / 4)
204 			V.Y = fabs(V.Y);
205 
206 		if (P.Z > Size / 4)
207 			V.Z = -fabs(V.Z);
208 		if (P.Z < -Size / 4)
209 			V.Z = fabs(V.Z);
210 
211 		// Запоминание состояния изменения текущей СК
212 		glPushMatrix();
213 
214 		// Рисование стенок
215 		glutWireCube(Size / 2);
216 		// Задача перемещения мяча
217 		glTranslated(P.X, P.Y, P.Z);
218 		// Цвет мяча
219 		glColor3d(0, 1, 1);
220 		// Рисование мяча
221 		glutSolidSphere(0.5, 30, 30);
222 		
223 		// Восстановление последнего запоминания состояния изменения текущей СК
224 		glPopMatrix();
225 	}
226 }; // end of 'ball_air_2' class
227 
228 // Шар, летящий с сопротивлением воздуха
229 // Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
230 class ball_air_3 : public sagl::object
231 {
232 private:
233 	double angle, v, m, n;
234 public:
235 	// Конструктор
236 	ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
237 	{
238 		P = sagl::vec(sagl::r0() + 5, 5, 0);
239 		V.X = 0;
240 		V.Y = sin(angle) * v;
241 		V.Z = cos(angle) * v;
242 	}
243 	
244 	// Конструктор
245 	ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
246 	{
247 		P = sagl::vec(sagl::r0() + 5, 5, 0);
248 		V.X = 0;
249 		V.Y = sin(angle) * v;
250 		V.Z = cos(angle) * v;
251 	}
252 	
253 	// Отрисовка объекта
254 	void Render( sagl::anim &Ani )
255 	{
256 		// Вектор ускорения свободного падения и вектор полного ускорения
257 		sagl::vec g = sagl::vec(0, -9.8, 0), a;
258 		// Размер комнаты
259 		double Size = 120;
260 
261 		// Изменение вектора ускорения
262 		a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
263 
264 		// Изменение вектора скорости
265 		V += a * Ani.DeltaTime;
266 		// Изменение вектора перемещения
267 		P += V * Ani.DeltaTime;
268 
269 		// Ограничения - стенки
270 		if (P.X > Size / 4)
271 			V.X = -fabs(V.X);
272 		if (P.X < -Size / 4)
273 			V.X = fabs(V.X);
274 
275 		if (P.Y > Size / 4)
276 			V.Y = -fabs(V.Y);
277 		if (P.Y < -Size / 4)
278 			V.Y = fabs(V.Y);
279 
280 		if (P.Z > Size / 4)
281 			V.Z = -fabs(V.Z);
282 		if (P.Z < -Size / 4)
283 			V.Z = fabs(V.Z);
284 
285 		// Запоминание состояния изменения текущей СК
286 		glPushMatrix();
287 
288 		// Рисование стенок
289 		glutWireCube(Size / 2);
290 		// Задача перемещения мяча
291 		glTranslated(P.X, P.Y, P.Z);
292 		// Цвет мяча
293 		glColor3d(1, 0.5, 0);
294 		// Рисование мяча
295 		glutSolidSphere(0.5, 30, 30);
296 		
297 		// Восстановление последнего запоминания состояния изменения текущей СК
298 		glPopMatrix();
299 	}
300 }; // end of 'ball_air_3' class
301 
302 #endif /*__SAMPLE_H_ */
303 
304 // END OF 'SAMPLE.H' FILE

Скачать архив

Рубинова Раиса

Описание программы: программа состоит из четырех независимых друг от друга частей:

  1. Полет тела без сопротивления воздуха;
  2. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
  3. Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  4. Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;

Скачать можно тут.

Обычный.png Точный.png Верле2.png Верле1.png

  1 // Первый случай
  2 
  3 #include <iostream>
  4 #include <math.h>
  5 #include <cstdlib>
  6 #include <fstream>
  7 
  8 /// Программа, анализирующая полет тела;
  9 
 10 using namespace std;
 11 double a,s,H,p1,p2,X,f;    /// Создание переменных, необходимых для работы:
 12                                                                                 /// a - угол к горизонту, под которым летит тело, вводится пользователем;
 13                                                                                 /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
 14                                                                                 /// H - координата тела по оси Oy;
 15                                                                                 /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
 16                                                                                 /// X - координата тела по оси Oy;
 17                                                                                 /// f - шаг по времени;
 18 
 19 int main()
 20 {
 21     cout << "Enter speed and angle and step of time" << endl;   /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
 22     cin >> s >> a >> f;     /// Считывание данных, введенных пользователем, в переменные;
 23     double t=s*sin(a*3.14159/180.0)/9.8;        /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
 24     for (double i=f; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
 25     {
 26         p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
 27         p2=4.9*i*i;         /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
 28         H=double(p1)-p2;    /// Вычисление координаты тела по оси Oy;
 29         X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
 30         cerr << X << " ";       /// Вывод на экран значения по оси Ox
 31         cerr << H << endl;      /// и по оси Oy;
 32     }
 33     ofstream out("zap.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 34     for (double i=0; i<(2*t+f); i+=f)        /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
 35     {
 36         p1=s*sin(a*3.14159/180)*i;       /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
 37         p2=4.9*i*i;             /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
 38         H=double(p1)-p2;        /// Вычисление координаты тела по оси Oy;
 39         X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
 40         out << X << " ";        /// Запись в файл значения по оси Ox
 41         out << H << endl;       /// и по оси Oy;
 42     }
 43     out.close();        /// Закрываем файл, с которым работали в течение программы;
 44     return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 45 }
 46 
 47 // Второй случай 
 48 
 49 #include <iostream>
 50 #include <math.h>
 51 #include <cstdlib>
 52 #include <fstream>
 53 
 54 /// Программа, позволяющая описать полет точки при помощи точного метода;
 55 
 56 using namespace std;
 57 double v,a,st,m;    /// Создание переменных, необходимых для работы:
 58                         /// v - модуль скорости, который задает сам пользователь;
 59                         /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
 60                         /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
 61                         /// m - масса тела, задается пользователем;
 62 double *V,*X, *Y, *U;   /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 63                         /// V - массив, хранящий значения скорости по оси Ox;
 64                         /// X - массив, хранящий координаты точки по оси Ox;
 65                         /// Y - массив, хранящий значения скорости по оси Oy;
 66                         /// U - массив, хранящий координаты точки по оси Oy;
 67 
 68 int main()
 69 {
 70     cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
 71     cin >> v >> a >> st >> m;           /// Считывание данных, введенных пользователей в переменные;
 72     double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
 73     int n=2*t/st;       /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 74     //int p=1/st;
 75     V = new double [n+2];       /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 76     X = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 77     Y = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 78     U = new double [n+2];       /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 79     V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 80     X[0]=0;         /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 81     U[0]=v*sin(3.14159*a/180.0);        /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 82     Y[0]=0;         /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 83     ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 84     for (int i=1; i<n; ++i)         /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 85                                     /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 86     {
 87         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 по формуле, выведенной через дифференциальное уравнение точки для вертикальной оси и находящей координату как функцию от времени и координаты тела в предыдущей рассматриваемой нами точке;
 88         X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st));          /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
 89                                                                   /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
 90                                                                   /// Движение по горизонтальной оси рассматривается как равномерное прямолинейное движение;
 91                                                                   /// Движение по вертикальной оси рассматривается как равноускоренное прямолинейное движение;
 92         cerr << X[i] << " " << Y[i] << endl;        /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 93         out << X[i] << " " << Y[i] << endl;         /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 94                                                     /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 95     }
 96     out.close();        /// Закрываем файл, с которым работали в течение программы;
 97     return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 98 
 99 
100 }
101 
102 // Третий случай
103 
104 #include <iostream>
105 #include <math.h>
106 #include <cstdlib>
107 #include <fstream>
108 
109 /// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
110 
111 using namespace std;
112 double v,a,st,m,x,y;    /// Создание переменных, необходимых для работы;
113                         /// v - модуль скорости, который задает сам пользователь;
114                         /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
115                         /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
116                         /// m - масса тела, задается пользователем;
117                         /// x - координата тела по оси Ox в мнимый момент времени t=-1;
118                         /// y - координата тела по оси Oy в мнимый момент времени t=-1;
119 double *V,*X, *Y, *U;   /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
120                         /// V - массив, хранящий значения скорости по оси Ox;
121                         /// X - массив, хранящий координаты точки по оси Ox;
122                         /// Y - массив, хранящий значения скорости по оси Oy;
123                         /// U - массив, хранящий координаты точки по оси Oy;
124 
125 int main()
126 {
127     cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
128     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователей в переменные;
129     double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
130     int n=2*t/st;   /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
131     //int p=1/st;
132     V = new double [n+2];       /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
133     X = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
134     Y = new double [n+2];       /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
135     U = new double [n+2];       /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
136     V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
137     X[0]=0;     /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
138     x=X[0]-V[0]*st;     /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
139     X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st;  /// Вычисление координаты тела по оси Ox в момент времени t=1;
140     U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
141     Y[0]=0;     /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
142     y=Y[0]-U[0]*st;     /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
143     Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st;      /// Вычисление координаты тела по оси Oу в момент времени t=1;
144     cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
145     ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
146     out << X[1] << " " << Y[1] << endl;     /// Записываем в файл полученные значения координат тела в момент времени t=1;
147     int k=1;        /// Создаем целочисленную переменную k=1 для работы в цикле;
148     //cerr<<"N "<<n<<"\n";
149     for (int i=0; i<n; ++i)     /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
150                                 /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
151     {
152         X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st;    /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
153         V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
154         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;
155         U[k]=(Y[k+1]-Y[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
156         //cerr <<i<<" "<<k<<" "<<
157         cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
158         out << X[k+1] << " " << Y[k+1] << endl;     /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
159         k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
160                     /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
161     }
162     out.close();    /// Закрываем файл, с которым работали в течение программы;
163     return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
164 }
165 
166 // Четвертый случай
167 
168 #include <iostream>
169 #include <math.h>
170 #include <cstdlib>
171 #include <fstream>
172 
173 /// Программа, анализирующая полет тела при помощи метода Верле;
174 
175 using namespace std;
176 double v,a,st,m,x,y;        /// Создание переменных, необходимых для работы:
177                             /// v - модуль скорости, который задает сам пользователь;
178                             /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
179                             /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
180                             /// m - масса тела, задается пользователем;
181                             /// x - координата тела по оси Ox в мнимый момент времени t=-1;
182                             /// y - координата тела по оси Oy в мнимый момент времени t=-1;
183 double *V,*X, *Y, *U;       /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
184                             /// V - массив, хранящий значения скорости по оси Ox;
185                             /// X - массив, хранящий координаты точки по оси Ox;
186                             /// Y - массив, хранящий значения скорости по оси Oy;
187                             /// U - массив, хранящий координаты точки по оси Oy;
188 
189 int main()
190 {
191     cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
192     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователем, в переменные;
193     double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
194     int n=2*t/st;           /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
195     //int p=1/st;
196     V = new double [n+2];   /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
197     X = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
198     Y = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
199     U = new double [n+2];   /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
200     V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
201     X[0]=0;                 /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
202     x=X[0]-V[0]*st;         /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
203     X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Ox в момент времени t=1;
204     U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
205     Y[0]=0;                 /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
206     y=Y[0]-U[0]*st;         /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
207     Y[1]=2*Y[0]-y-(0.01/m)*U[0]*U[0]/sin(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Oу в момент времени t=1;
208     cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
209     ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
210     out << X[1] << " " << Y[1] << endl;         /// Записываем в файл полученные значения координат тела в момент времени t=1;
211     int k=1;            /// Создаем целочисленную переменную k=1 для работы в цикле;
212     //cerr<<"N "<<n<<"\n";
213     for (int i=0; i<n; ++i)         /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
214                                     /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
215     {
216         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;
217         V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
218         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;
219         U[k]=(Y[k+1]-Y[k-1])/(2*st);    /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
220         //cerr <<i<<" "<<k<<" "<<
221         cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
222         out << X[k+1] << " " << Y[k+1] << endl;     /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
223         k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
224                                                     /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
225     }
226     out.close();    /// Закрываем файл, с которым работали в течение программы;
227     return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
228 }

Савельева Ольга

Описание: Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  4. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <cmath>
  4 
  5 using namespace std;
  6 
  7 FILE *output;
  8 
  9 double e = 0.0000001; //точность
 10 double g = 9.8; //ускорение свободного падения
 11 double dt = 0.00001;   //шаг по времени
 12 double windageLinearCoefficient = 0.1;
 13 double windageSquareCoefficient = 0.00001;
 14 
 15 struct Vector   //вектор
 16 {
 17     double x, y;
 18     Vector():x(0), y(0)
 19     {}
 20     Vector(double x, double y):x(x), y(y)
 21     {}
 22     const Vector operator+(const Vector &v) const
 23     {
 24         return Vector(this -> x + v.x, this -> y + v.y);
 25     }
 26     const Vector operator-(const Vector &v) const
 27     {
 28         return Vector(this -> x - v.x, this -> y - v.y);
 29     }
 30     const Vector operator*(const double k) const
 31     {
 32         return Vector(this -> x * k, this -> y * k);
 33     }
 34     const Vector operator*(const int k) const
 35     {
 36         return Vector(this -> x * k, this -> y * k);
 37     }
 38     const Vector operator/(const double k) const
 39     {
 40         return Vector(this -> x / k, this -> y / k);
 41     }
 42 };
 43 
 44 const Vector operator*(const double a, const Vector &v)
 45 {
 46     return Vector(v.x * a, v.y * a);
 47 }
 48 
 49 const Vector operator*(const int k, const Vector &v)
 50 {
 51     return Vector(v.x * k, v.y * k);
 52 }
 53 
 54 double abs(const Vector &v)
 55 {
 56     return sqrt(v.x * v.x + v.y * v.y);
 57 }
 58 
 59 void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
 60 {
 61     fputs(description, output);
 62     fputs(": ", output);
 63     fprintf(output, "%lf", v.x);
 64     fputs(", ", output);
 65     fprintf(output, "%lf\n", v.y);
 66 }
 67 
 68 Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
 69 {
 70     double fallTime = 2 * velocity * sin(angle) / g;  //расчет времени падения
 71     if((time < 0) or (time > fallTime))
 72         time = fallTime;
 73     double x = velocity * cos(angle) * time;    // x = vx*t;
 74     double y = velocity * sin(angle) * time - g * time * time / 2;  // y = vy*t-(g*t^2)/2;
 75     return Vector(x, y);
 76 }
 77 
 78 Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
 79 {
 80     double nowTime = dt;
 81     Vector rsb(0, 0);
 82     if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
 83         return rsb; //вернитесь в начальную точку
 84     Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
 85     Vector r = v * dt;    //вторая точка
 86     Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
 87     a.y -= g;
 88     v = v + a * dt; //скорость во второй точке
 89     a = -windageLinearCoefficient * v; //ускорение во второй точке
 90     a.y -= g;
 91     while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //пока точка выше 0 или не достигла заданного времени
 92     {
 93         Vector rn = 2 * r - rsb + a * dt * dt;  // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
 94         v = (rn - rsb) / (2 * dt);  // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
 95         rsb = r;    //обновление r(t-dt) and r(t)
 96         r = rn;
 97         a = -windageLinearCoefficient * v;  //обновление a(t)
 98         a.y -= g;
 99         nowTime += dt;  //обновленное время
100     }
101     return r;
102 }
103 
104 Vector calculateForTime(Vector &v, double time)
105 {
106     Vector r;
107     // x = vx/k*(1-e^(-k*t));
108     r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
109     // y = ((vy+g/k)*(1-e^(-k*t))-g*t)/k;
110     r.y = ((v.y + g / windageLinearCoefficient) * (1 - exp(-windageLinearCoefficient * time)) - g * time) / windageLinearCoefficient;
111     return r;
112 }
113 
114 Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
115 {
116     if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
117         return getCoordinatesWithoutWindage(velocity, angle, time);   //вычисляй будто это 0
118     Vector r;
119     Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
120     if(time >= 0)   //время данное
121     {
122         r = calculateForTime(v, time);
123         if(r.y >= 0)    //если объект в воздухе или только приземлился
124             return r;   //затем верните координаты объекта
125         else    //еще
126             return getCoordinatesAccurateLinear(velocity, angle);   //верните координаты приземления
127     }
128     else
129     {
130         double timer, timel, timem;
131         timer = v.y / g;
132         timel = 0;
133         while(calculateForTime(v, timer).y > 0) //смотрим на некоторые значения времени, которые больше времени посадки
134             timer *= 1.5;
135         timem = timel + (timer - timel) / 2;
136         r = calculateForTime(v, timem);
137         while(abs(r.y) > e)    //бинарный поиск времени посадки
138         {
139             if(r.y > 0)
140                 timel = timem;
141             else
142                 timer = timem;
143             timem = timel + (timer - timel) / 2;
144             r = calculateForTime(v, timem);
145         }
146         return r;
147     }
148 }
149 
150 Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
151 {
152     double nowTime = dt;
153     Vector rsb(0, 0);
154     if((dt / 2 - time > 0)and(time >= 0))   //если время слишком малое для рсчета
155         return rsb; //вернитесь в начальную точку
156     Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
157     Vector r = v * dt;  //вторая точка
158     Vector a = -abs(v) * v * windageSquareCoefficient;  //ускорение в начальной точке
159     a.y -= g;
160     v = v + a * dt; //скорость во второй точке
161     a = -abs(v) * v * windageSquareCoefficient; //ускорение во второй точке
162     a.y -= g;
163     while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //когда точка выше нулевой отметки и не достигает заданного времени
164     {
165         Vector rn = 2 * r - rsb + a * dt * dt;  // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
166         v = (rn - rsb) / (2 * dt);  // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
167         rsb = r;    //updating r(t-dt) and r(t)
168         r = rn;
169         a = -abs(v) * v * windageSquareCoefficient; //новое a(t)
170         a.y -= g;
171         nowTime += dt;  //новое a(t)
172     }
173     return r;
174 }
175 
176 void err(const char *s) //печатает сообщение об ошибке и завершает работу
177 {
178     fputs(s, output);
179     exit(1);
180 }
181 
182 int main(int argc, const char *argv[])
183 {
184     double velocity, angle;
185     bool needRead = true;
186     if(argc==3) //если даны 2 аргумента
187     {
188         velocity = atof(argv[1]);   //истолкование его как скорости и угла
189         angle = atof(argv[2]);
190         needRead = false;
191     }
192     if(needRead)
193     {
194         puts("Enter initial velocity (m/s)");
195         scanf("%lf", &velocity);
196     }
197     if(velocity < 0)    //проверка, если скорость меньше 0
198         err("Initial velocity must be above 0");
199     if(needRead)
200     {
201         puts("Enter initial angle (0-180 degrees)");
202         scanf("%lf", &angle);
203     }
204     if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
205         err("Initial angle must be from 0 to 180");
206     angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
207     output = fopen("Coordinates.txt", "w"); //открытие результативного файла
208     //вычисление и печать 4 значений
209     printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
210     printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
211     printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
212     printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
213     fclose(output); //закрытие файла
214     return 0;
215 }

Скачать можно здесь


Сенников Иван

Суть программы:Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.

Идея: Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.

Инструкция: Результаты программы будут записаны в соответствующий файл (подробности смотри в самой программе). Пользователю будет предоставлена возможность ввести начальную скорость и угол, под которым и бросают тело.

Ссылка для скачиваний: здесь.

Степанянц Степан

Описание программы: программа записывает в четыре файла результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.

Скачать можно тут.

Graph239.png

Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;


Файл "main.cpp"

  1 #include <iostream>
  2 #include <locale.h>
  3 #include <math.h>
  4 #include <fstream>
  5 #include<iomanip>
  6 #include <cmath>
  7 using namespace std;
  8 main ()
  9 {
 10     ofstream F;                                                                    //a1-угол в градусах,dt-шаг,r-сопротивление воздуха
 11 int u0=50;
 12 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 - проэкции скорости на оси х и у.
 13 a=a1*M_PI/180; //Градусы в радианы
 14 t=0;
 15  
 16                                          //Движение без сопротивления воздуха
 17  F.open("C:\\1.txt",ios::out);
 18 while(y>=0)
 19 {
 20     x=x0+u0*cos(M_PI/6)*t;
 21     y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t;  //Расчитываем координаты в каждой точке через шаг
 22    F<<x<<" "<<y<<endl;
 23    t=t+dt;
 24  
 25 }
 26  
 27 F.close();
 28                                          //Точное решение для линейной зависимости
 29  F.open("C:\\2.txt",ios::out);
 30  y=y0;
 31  x=x0;
 32  t=0;                                                                            //Расчитываем координаты в каждой точке через шаг
 33 while(y>=0)
 34 {
 35         ux = u0 * cos(a);
 36         uy = u0 * sin(a);
 37         x = x0+ (m * ux / r)* (1 - exp(-1 * r * t / m));                      //подстановка формул
 38         y = y0+(m/r)*((uy + g * m / r)*(1 - exp(-1 * r * t / m)) - g * t);
 39         t = t + dt;
 40  
 41        F << x << ' ' << y << endl;
 42  
 43  
 44  
 45 }
 46    F.close();
 47                                                         //метод Верле 1
 48  ypr = y0 - u0*sin(a)*dt;
 49  yt=ypr;
 50     xpr = x0 - u0*cos(a)*dt;
 51     x = x0;                          //Начальные условия
 52     y = y0;
 53     u = u0;
 54     ux = u0 * cos(a);
 55     uy = u0 * sin(a);                        
 56 F.open("C:\\3.txt",ios::out);
 57  
 58     while (y >= y0)
 59     {
 60         xsl = 2 * x - xpr - (r / m) * u * ux * (dt * dt);
 61         ux = ( xsl - xpr )/ (2 * dt);
 62         ysl = 2 * y - ypr - (g + (r / m) * u * uy) * (dt * dt);       //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
 63         uy =  (ysl - ypr)/ (2 * dt);
 64         u = sqrt(uy*uy + ux*ux );
 65         F << x << ' ' << y << endl;
 66  
 67         xpr = x;
 68         x = xsl;
 69         ypr = y;
 70         y = ysl;
 71     }
 72     F.close();
 73                                                        //Метод Верле 2
 74      ypr = y0 - u0*sin(a)*dt;
 75  yt=ypr;
 76     xpr = x0 - u0*cos(a)*dt;
 77     x = x0;                                                                            //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
 78     y = y0;
 79     u = u0;
 80     ux = u0 * cos(a);                             
 81     uy = u0 * sin(a);
 82 F.open("C:\\4.txt",ios::out);
 83  
 84     while (y >= y0)
 85     {
 86         xsl = 2 * x - xpr - (r / m) * ux * (dt * dt);
 87         ux = ( xsl - xpr )/ (2 * dt);
 88         ysl = 2 * y - ypr - (g + (r / m) * uy) * (dt * dt);
 89         uy =  (ysl - ypr)/ (2 * dt);
 90         u = sqrt(uy*uy + ux*ux );
 91         F << x << ' ' << y << endl;
 92  
 93         xpr = x;
 94         x = xsl;
 95         ypr = y;
 96         y = ysl;
 97     }
 98     F.close();
 99  
100  
101 return 0;
102  
103  
104 }


Александр Сюрис

Описание программы: Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
  2. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости
  3. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
  4. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
Скачать можно  тут.

Снимок.PNG Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2; Файл "main.cpp"

  1 #include <iostream>
  2 #include <fstream>
  3 #include <math.h>
  4 #include <cmath>
  5 using namespace std;
  6 int o;
  7 double v,a,m,k;
  8 ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
  9 
 10 
 11 
 12 int rez_1(double v, double a)
 13 {
 14     fout<<"---------------Первый режим-------------------------"<<endl;
 15     fout<<" T=0 x=0 y=0";
 16     fout<<endl;
 17     double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
 18     V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
 19     V0y=v*sin(a/180*M_PI);
 20     Ty=2*V0y/g;//время полета
 21     while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
 22     {
 23         x=x+V0x*t;               //ф-лы для рассчета x и y в данный момент времени
 24         y=y+V0y*t-g*pow(t,2)/2;
 25 
 26         if (y<0) //если y<0
 27             {
 28                 t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
 29                 x=x+V0x*t1;//используя это время находим координату по х
 30                 fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
 31                 break;
 32             }
 33             else
 34                 {
 35                     V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
 36                     fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
 37                     T=T+t;//увел время на шаг
 38                 }
 39     }
 40 
 41 
 42 }
 43 
 44 
 45 int rez_2(double v, double a, double k, double m)
 46 {
 47     fout<<"---------------Второй режим работы-------------------------"<<endl;
 48     fout<<" T=0 x=0 y=0";
 49     fout<<endl;
 50     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;
 51     x=(m*Vx/k)*(1-exp(-1*k*T/m));            //ф-лы для рассчета x и y в данный момент времени
 52     y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T);  //точное решение при лин завсисимости
 53     while (y>0)
 54     {
 55         x=(m*Vx/k)*(1-exp(-1*k*T/m));
 56         y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T);
 57         fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
 58         T=T+t;
 59     }
 60 
 61 
 62 }
 63 
 64 
 65 
 66 int rez_3(double v, double a, double k, double m)
 67 {
 68   fout<<"---------------Третий режим работы-------------------------"<<endl;
 69     fout<<" T=0 x=0 y=0";
 70     fout<<endl;
 71     double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
 72     x3=0,x2=0,x1=x2-Vxn*t,  y3=0,
 73     y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 74     //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
 75 
 76 
 77     x3=2*x2-x1-k/m*Vxn*pow(t,2);   //координаты в момент времени T
 78     y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
 79     Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
 80     Vyn=(y3-y1)/(2.0*t);
 81     x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
 82     y1=y2;
 83     x2=x3;//-//- к координате в n шаге значение в момент времени T
 84     y2=y3;
 85     while (y2>0)
 86     {
 87         x3=2*x2-x1-k/m*Vxn*pow(t,2);
 88         y3=2*y2-y1-(g+k/m*Vyn)*pow(t,2);
 89         Vxn=(x3-x1)/(2.0*t);
 90         Vyn=(y3-y1)/(2.0*t);
 91         fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
 92 
 93         if (y3<0)
 94         {
 95             t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
 96             x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
 97             fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 98         }
 99 
100         T=T+t;
101         x1=x2;
102         y1=y2;
103         x2=x3;
104         y2=y3;
105 
106     }
107 
108 }
109 
110 
111 int rez_4(double v, double a, double k, double m)
112 {
113   fout<<"---------------Четвертый режим работы-------------------------"<<endl;
114     fout<<" T=0 x=0 y=0";
115     fout<<endl;
116     double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
117     x3=0,x1=0, x2=x1+Vxn*t, y3=0, y1=0,
118     y2=y1+Vyn*t, g=9.8, t1, T=0.1, V=v;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
119     //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
120 
121 
122     x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
123     y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
124     Vxn=(x3-x1)/(2.0*t);
125     Vyn=(y3-y1)/(2.0*t);
126     V=sqrt(pow(Vxn,2)+pow(Vyn,2.0));
127     x1=x2;
128     y1=y2;
129     x2=x3;
130     y2=y3;
131     while (y2>0)
132     {
133         x3=2.0*x2-x1-(k/m)*Vxn*V*pow(t,2);
134         y3=2.0*y2-y1-(g+(k/m)*Vyn*V)*pow(t,2);
135         Vxn=(x3-x1)/(2.0*t);
136         Vyn=(y3-y1)/(2.0*t);
137         V=sqrt(pow(Vxn,2)+pow(Vyn,2));
138         fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
139 
140         if (y3<0)
141         {
142             t1=sqrt(abs((-y1+2.0*y2)/(g+(k/m)*Vyn*V)));
143             x3=2.0*x2-x1-(k/m)*Vxn*V*pow((t+t1),2);
144             fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
145         }
146 
147 
148         T=T+t;
149         x1=x2;
150         y1=y2;
151         x2=x3;
152         y2=y3;
153 
154     }
155 
156 }
157 
158 
159 int main()
160 {
161 
162  setlocale(LC_ALL, "rus");
163  cout<<"Введите скорость тела и угол"<<endl;
164  cin>>v>>a;
165 
166  while (1>0){
167  cout<<"Выберите режим работы программы:"<<endl;
168  cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
169  cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
170  cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
171  cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
172  cout<<"5 - Выйти";
173  cin>>o;
174 
175  if (o==1)
176     rez_1(v,a);
177  if (o==2)
178     {
179     cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
180     cin>>m>>k;
181     rez_2(v,a,k,m);
182     }
183 
184  if (o==3)
185     {
186     cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
187     cin>>m>>k;
188     rez_3(v,a,k,m);
189     }
190   if (o==4)
191     {
192     cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
193     cin>>m>>k;
194     rez_4(v,a,k,m);
195     }
196   if (o==5)
197         break;
198 
199             }
200 }


Тимошенко Валентина

Описание программы: при запуске пользователь вводит шаг функции, угол, под которым бросают тело, массу тела, сопротивление воздуха и скорость. Программа записывает в четыре файла результаты вычисления:

  1. Координаты, рассчитанные по формуле для движения без сопротивления воздуха;
  2. Координаты, рассчитанные по формуле для движения с учетом сопротивления воздуха;
  3. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивления воздуха от скорости.
  4. Координаты, полученные методом Верле при линейной зависимости силы сопротивления воздуха от скорости;

Скачать можно тут.

Визуализированный результат работы программы Grafics.png

Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.

  1 #include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
  2 #include <fstream> /// и для движений с учётом сопротивления и без его учёта
  3 #include <math.h>
  4 #include<stdlib.h>
  5 using namespace std;
  6 
  7 int main()
  8 {
  9     double a, step, Pi, g, Vo, m, r;
 10     ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
 11 
 12     double x, y, x_0, y_0, x0, y0, Vx, Vy;
 13     ///переменные для движения точки без учёта сопротивления и с его учётом
 14     ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
 15     ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
 16     ///Vx - скорость тела по оси Ох, Vу - скорость тела по оси Оу
 17     ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
 18 
 19     double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
 20     ///переменные для 1го варианта метода Верле
 21     ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
 22     ///у1 - координата тела по оси Оу на (n-1) шаге, у2 - координата тела по оси Оу на (n) шаге, у3 - координата тела по оси Оу на (n+1) шаге
 23     ///Vx0 - начальная скорость тела по оси Ох, Vy0 - начальная скорость тела по оси Оу
 24     ///Vxn - скорость тела в данный момент времени по оси Ох, Vyn - скорость тела в данный момент времени по оси Оу
 25 
 26     double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
 27     ///переменные для 2го варианта метода Верле
 28     ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
 29     ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
 30     ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
 31 
 32     g=10; ///значение ускорения свободного падения
 33     Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
 34 
 35     do ///цикл, запрашивающий ввод пользователем значения шага функции
 36     {
 37         cout << "Input the step, it must be less than 1" << endl; ///ввод с клавиатуры шага(то же самое, что дельта t), шаг должен быть маленьким (меньше 1)
 38         cin >> step;  ///вывод величины шага на экран
 39     }
 40     while (step>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
 41 
 42     cout << '\n' << "Input the corner in degrees,the corner is in the range from 0 to 90 degrees" << endl; ///ввод с клавиатуры угла в радианах (угол от 0 до 90 градусов)
 43     cin >> a; ///вывод значение угла на экран
 44     a=(Pi*a)/180.0;
 45     cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
 46     cin >> m; ///вывод величины массы на экран
 47 
 48     do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
 49     {
 50         cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
 51         cin >> r; ///вывод значения сопротивления на экран
 52     }
 53     while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
 54 
 55     cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
 56     cin >> Vo; ///вывод значения скорости на экран
 57 
 58     ///для движения без учёта сопротивления
 59     x0=0; ///обнуление переменных
 60     y0=0;
 61     x=0;
 62     y=0;
 63 
 64     ///для движения с учётом сопротивления
 65     x_0=0; ///обнуление переменных
 66     y_0=0;
 67 
 68     ///для 1го варианта метода Верле
 69 
 70     Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
 71     Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
 72 
 73     x2=0; ///обнуление переменных
 74     y2=0;
 75     x3=0;
 76     y3=0;
 77 
 78     y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
 79     x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
 80 
 81     ///для 2го варианта метода Верле
 82 
 83     x_2=0; ///обнуление переменных
 84     y_2=0;
 85     x_3=0;
 86     y_3=0;
 87 
 88     Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
 89     Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
 90 
 91     y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
 92     x_1=-Vo*cos(a)*step;    ///расчет начального значения координаты на (п-1) шаге по оси Ох
 93 
 94     ofstream out("For method without resistance.txt");
 95     ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
 96 
 97     for (int i=0; y>=0; ++i) ///цикл для подсчета координат при движении тела без учёта сопротивления
 98     {
 99         x=Vo*step*i*cos(a); ///расчет координаты тела по оси х
100         y=Vo*sin(a)*i*step-(g*i*step*i*step)*0.5; ///расчет координаты тела по оси y
101 
102         out << x << "    " << y <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
103     }
104     out.close();
105 
106     ofstream out1 ("For method with resistance.txt");
107     ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
108 
109     for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
110     {
111         Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
112         Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
113         x_0=x0+(m/r)*Vx*(1.0 - exp((-r*i*step)/m)); ///расчет координаты тела по оси х
114         y_0=y0+(m/r)*(Vy+g*(m/r))*(1.0 - exp((-r*i*step)/m))-g*i*step*(m/r); ///расчет координаты тела по оси y
115 
116         out1 << x_0 << "    " << y_0 <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
117     }
118     out1.close();
119 
120     ofstream out2 ("For method Verle 1.txt");
121     ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
122 
123     for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
124     {
125         x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
126         y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
127         Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
128         Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
129         Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
130 
131         x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
132         x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
133         y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
134         y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
135 
136         out2 << x3 << "   " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
137     }
138     out2.close();
139 
140     ofstream out3 ("For method Verle 2.txt");
141     ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
142 
143     for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
144     {
145         x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
146         y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
147         Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
148         Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
149 
150         x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
151         x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
152         y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
153         y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
154 
155         out3 << x_3 << "   " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
156 
157     }
158     out3.close();
159 
160     cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
161     cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
162     return 0;
163 }

Уманский Александр

Описание программы: программа записывает в четыре файла результаты вычисления:

  1. Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  2. Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  3. Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  4. Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.