Редактирование: Информатика: Движение тела в среде

Перейти к: навигация, поиск

Внимание! Вы не авторизовались на сайте. Ваш IP-адрес будет публично видимым, если вы будете вносить любые правки. Если вы войдёте или создадите учётную запись, правки вместо этого будут связаны с вашим именем пользователя, а также у вас появятся другие преимущества.

Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
<div>
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
'''[[Абрамов Игорь]]'''  
+
'''[[Лебедев Станислав]]'''  
  
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
+
Скачать можно  [http://tm.spbstu.ru/Файл:Шарик.rar тут].
  
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
+
<div class="mw-collapsible-content">
  
</div>
+
[[File:1.png]]
  
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
'''Визуализированный результат работы программы'''
'''[[Андреева Полина]]'''
+
[[File:graph.png]]
  
'''Краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл.
+
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
''' Инструкция ''':
 
Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут].
+
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
  
 +
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
  
<div class="mw-collapsible-content">
+
Файл "'''main.cpp'''"
 
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
+
#include <iostream>
'''Визуализированный результат работы программы'''
+
#include <math.h>
 
+
#include "Vector.h"
[[:File:graphAP.png]]
+
#include <cstring>
 +
#include <cmath>
 +
#include <malloc.h>
 +
#include <fstream>
  
Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;
+
using namespace std;
  
# "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
int n = 100;
# "MyFile.txt" using 3 : 4 -  Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
ofstream outfile;
# "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
 
  
 
+
class Ball                                          //класс бросаемого тела
 
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <fstream>
 
#include "math.h"
 
#include <iomanip>
 
using namespace std;
 
class func
 
 
{
 
{
 +
    private:
 +
        double angle,m,k;                          //угол броска,масса,коэффицент сопротивления воздуха
 +
        Vector3D r,v,a;                            //радиус-вектор,вектор скорости,ускорения
 +
    public:
  
private:
+
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
    double speed0, angle0, step ;
+
        Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
  double time;
+
        {
 +
            angle = _angle;
 +
            r    = _r;
 +
            v    = _v;
 +
            a    = _a;
 +
        }
  
  public:
+
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
      double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
+
        Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
      double t, amount;
+
        {
      int amountint;
+
            angle = _angle;
    func ( double _speed0, double _angle0, double _step ):speed0(_speed0), angle0(_angle0), step(_step)
+
            r    = _r;
     {
+
            v    = _v;
        angle0=(3.14159*angle0) / 180 ; ///перевод угла в радианы
+
            a    = _a;
 +
            m     = _m;
 +
            k    = _k;
 +
        }
  
         time = ( 2*speed0*sin(angle0) ) / g;///подсчет полного времени полета
+
         //точная формула зависимости координаты от времени
        amount = (time/step) + 1;///количество точек для траектории
+
        Vector3D positionReal(double t)
         amountint =  static_cast<int> (amount) ;
+
        {
 +
            double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
 +
            return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
 +
         }
  
 +
        //вывод положения на экран
 +
        void writePosToScreen()
 +
        {
 +
            cout << r.x << "  " << r.y << "  " << r.z << endl;
 +
        }
  
    }
+
        //вывод положения в файл
 +
        void writePosToFile(char s[])
 +
        {
 +
            outfile.open(s,ios :: app);
 +
            outfile << r.x << "          " << r.y << endl;
 +
            outfile.close();
 +
        }
  
 +
        //вывод произвольного вектора на экран
 +
        void WVTS(Vector3D v)
 +
        {
 +
            cout.width(15);
 +
            cout << v.x;
 +
            cout.width(15);
 +
            cout << v.y;
 +
            cout.width(15);
 +
            cout << v.z << endl;
 +
        }
  
 +
        //вывод произвольного вектора в файл
 +
        void WVTF(Vector3D v,char s[])
 +
        {
 +
            outfile.open(s,ios :: app);
 +
            outfile << v.x << "          " << v.y << endl;
 +
            outfile.close();
 +
        }
  
      void SaveFile(char filename[])
+
         //"пересчет" координаты по Верле(Линейная зависмость)
    {
+
         void changeR(Vector3D r1, double dt)
        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++)
 
 
         {
 
         {
             ///Верле линейная зависимость
+
             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 );
            x2=2*xv2-xm2-(n/m)*step*step*Vx2;
+
        }
            y2=2*yv2-ym2-(g+(n/m)*Vy2)*step*step;
 
            Vx2=(x2-xm2) / (2.0*step);
 
            Vy2=(y2-ym2) / (2.0*step);
 
            xm2=xv2;
 
            xv2=x2;
 
            ym2=yv2;
 
            yv2=y2;
 
  
            ///точное решение
+
        //"пересчет" координаты по Верле(Квадратичная зависимость)
             x3=x0+speed0*cos(angle0)*(m/n)*(1.0-exp(-(n/m)*i*step));
+
        void changeRSQ(Vector3D r1, double dt)
             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*Length(v)*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*Length(v)*v.y)*dt*dt, 0 );
 +
        }
 +
        //пересчет скорости по Верле
 +
        void changeV(Vector3D r1,double dt)
 +
        {
 +
             v =VS((VmV(r,r1)),1/(2*dt));
 +
        }
  
            ///метод Верле, квадратичная зависимость
+
        //рассчет предыдущегт к 0ому элементу
            x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
+
        Vector3D MR1(double dt)
            y1=2*yv1-ym1-(g+(n/m)*V1*Vy1)*step*step;
+
        {
             Vx1=(x1-xm1) / (2.0*step);
+
             return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
            Vy1=(y1-ym1) / (2.0*step);
+
        }
            V1=sqrt(Vx1*Vx1+Vy1*Vy1);
 
            xm1=xv1;
 
            xv1=x1;///запоминание предыдущего шага
 
            ym1=yv1;
 
            yv1=y1;
 
  
 +
        //возращает координату тела
 +
        Vector3D getR()
 +
        {
 +
            return r;
 +
        }
  
 +
        //рассчет времени полета
 +
        double TimeOfFly()
 +
        {
 +
            return (2*Length(v)*sin(angle)/Length(a));
 +
        }
  
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";
+
        //рассчет координаты по точной формуле. без сопротивления воздуха.
 
+
        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;
+
     //задание начальных параметров
    cout << " enter V0 = ";///введите начальную скорость
+
     Vector3D g = {0,-9.8,0};
     cin >> V0;
+
     double a,dt = 0;
    cout << " enter an angle , 0 < angle <= 90, angle = " ;///введите угол в диапозоне от 0 до 90 градусов
+
     char s[20];
    cin >> angle;
 
     cout << "\n enter step ";///введите шаг, с которым будут рассчитываться координаты
 
    cin >> step; cout << endl;
 
     func f1(V0,angle,step);///создание траектории
 
    f1.SaveFile("Myfile.txt");///запись в файл
 
  
 +
//    cin >> dt;
  
     return 0;
+
     dt = 0.1;
}
+
    a = (M_PI * 30)/180;
</syntaxhighlight>
+
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
</div>
 
  
<div>
+
    double tof = b1.TimeOfFly()+1;  //единичка прибавлена,чтобы график красивым был
  
'''[[Бальцер Анастасия]]'''
+
    //Без сопротивления возлуха
 +
    strcpy(s,"");
 +
    strcat(s, "o1.txt");
 +
    outfile.open(s, ios :: trunc);
 +
    outfile.close();
 +
    for (double i = 0; i <= tof; i += dt)
 +
    {
 +
        b1.WVTS(b1.position(i));
 +
        b1.WVTF(b1.position(i), s);
 +
    }
  
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
 
  
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
    //Верле(Линейная зависимость)
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
    dt = 0.1;
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
    a = (M_PI * 30)/180;
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
    Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
  
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
+
    strcpy(s,"");
 
+
    strcat(s, "o2.txt");
</div>
+
    outfile.open(s,ios :: trunc);
 
+
    outfile.close();
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    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);
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:задача_3.zip тут].
+
    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);
 +
    }
  
<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,"");
[[File:graph1.png]]
+
    strcat(s, "o4.txt");
 
+
    outfile.open(s, ios :: trunc);
Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01;
+
    outfile.close();
 
+
    r1 = b4.MR1(dt);
# "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
    for (double i = 0; i <= 20; i += dt)
# "Zapis.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
    {
# "Zapis.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
+
        rp = b4.getR();
# "Zapis.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
+
        b4.writePosToFile(s);
 +
        b4.writePosToScreen();
 +
        b4.changeRSQ(r1,dt);
 +
        b4.changeV(r1,dt);
 +
        r1.x = rp.x;
 +
        r1.y = rp.y;
 +
    }
  
 +
    return 0;
 +
}
 +
</syntaxhighlight>
  
 +
Файл "'''Vector.h'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
#include <iostream>
+
#ifndef VECTOR_H_INCLUDED
#include <locale.h>
+
#define VECTOR_H_INCLUDED
#include <math.h>
 
#include <fstream>
 
#include<iomanip>
 
#include <cmath>
 
  
using namespace std;
+
struct Vector3D
 
 
class fly ///создаем класс полета тела
 
 
{
 
{
 +
  double x,y,z;
 +
};
  
private: ///объявляем тип переменных в привате
+
Vector3D VmV(Vector3D v1,Vector3D v2)              //векторное вычитание
     double Vo, Agrad, Brad, time, step, amountdouble; ///Vo-начальная скорость тела; Agrad-угол, под которым летит тело, в градусах;
+
{
                                                      ///Brad-угол, под которым летит тело, в радианах; time-время полета тела; step-шаг;
+
     Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
                                                      ///amountdouble-количество точек (типа double)
+
    return v;
 +
};
 +
Vector3D VpV(Vector3D v1,Vector3D v2)              //векторное сложение
 +
{
 +
    Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
 +
    return v;
 +
}
  
public: ///объявляем переменные в паблике
+
double VV(Vector3D v1,Vector3D v2)              //скалярное умножение
    int amount; ///amoun-количество точек (типа int)
+
{
 +
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
 +
}
  
fly (double _step, double _Agrad, double _Vo):step(_step),Agrad(_Agrad),Vo(_Vo) ///создаем конструктор функции с объявлением переменных
+
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;
 +
}
  
    double g=9.8; ///объявляем тип и значение переменной g(ускорение свободного падения)
+
bool Kol(Vector3D v1,Vector3D v2)
    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;
 +
}
  
     time=2*Vo*sin(Brad)/g; ///рассчитываем время полета тела
+
Vector3D VS(Vector3D v1, double s)
     amountdouble=(round(time/step)+1); ///подсчитываем количество точек с заданым шагом
+
{
    amount=static_cast<int>(amountdouble); ///преобразуем количество из типа double к типу int
+
     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
 +
     return v;
 +
}
  
 +
double Length(Vector3D v1)
 +
{
 +
    return sqrt(VV(v1,v1));
 
}
 
}
void zapis (char Zapis[]) ///создаем функцию записи
+
 
 +
Vector3D MakeVector(double x,double y,double z)
 
{
 
{
     double g=9.8, m=1, n=0.05; ///объявляем тип и значения переменных g (ускорение свободного падения), m (масса тела), n(коэффициэнт сопротивления)
+
     Vector3D v = {x,y,z};
     double Xb, Yb; ///объявляем тип переменных для полёта тела без сопротивления ветра Xb(координата тела по Х), Yb(координата тела по У)
+
     return v;
    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"
+
Vector3D MakeVector(double length,double angle)
     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 (координата тела на оси Х без ветра),
+
     Vector3D v = {length * cos(angle), length * sin(angle),0};
                                                                                  ///Y (координата тела на оси У без ветра),
+
    return v;
                                                                                  ///Xv (координата тела на оси Х с ветром для метода Верле),
+
}
                                                                                  ///Yv (координата тела на оси У с ветром для метода Верле)
 
                                                                                  ///setw() размер столбиков
 
  
    for (int l=0; Yb>=0; ++l) ///создаем цикл от 0 до тех пор пока У больше нуля
+
double Proection(Vector3D base, Vector3D dir)
    {
+
{
        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";
+
    return (VV(base,dir)/Length(base));
            ///вывод на экран по столбцам 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 тут].
  
    outfile.close();
+
<div class="mw-collapsible-content">
  
}
+
[[File:формулы.png]]
  
};
+
'''Визуализированный результат работы программы'''
 +
[[File:graph1.png]]
  
int main()
+
Для тела с массой 1 кг,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.01;
{
 
  
    setlocale(LC_ALL,"RUS"); ///функция, позволяющая с++ распознавать русский язык
+
# "Zapis.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# "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; ///пользователь вводит шаг
 
  
    fly X(step,Agrad,Vo); ///объявление коструктора, создание функции Х, зависящей от step,Agrad,Vo
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    X.zapis("координаты.txt"); ///запись элементов функции в файл
+
#include <iostream>
 +
#include <locale.h>
 +
#include <math.h>
 +
#include <fstream>
 +
#include<iomanip>
 +
#include <cmath>
  
    return 0; ///конец программы
+
using namespace std;
  
}
+
class fly ///создаем класс полета тела
</syntaxhighlight>
+
{
</div>
 
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
private: ///объявляем тип переменных в привате
'''[[Васильева Анастасия]]'''
+
    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) ///создаем конструктор функции с объявлением переменных
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
{
# Координаты, полученные при численном интегрировании - метод Эйлера;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
+
    double g=9.8; ///объявляем тип и значение переменной g(ускорение свободного падения)
 +
    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 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
        ///точный метод
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
+
        Xt=Xot+(m/n)*Voxt*(1.0 - exp((-n*l*step)/m));
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
+
        Yt=Yot+(m/n)*(Voyt+g*(m/n))*(1.0 - exp((-n*l*step)/m))-g*l*step*(m/n);
# "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-ом шаге значение координаты У
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        ///метод Верле 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-ом шаге значение координаты У
  
#include <iostream>
+
    }
#include <fstream>
 
#include <iomanip>
 
#include <time.h>
 
#include <conio.h>
 
#include <stdlib.h>
 
#include <math.h>
 
#include <cstring>
 
using namespace std;
 
  
class pad ///создаем класс
+
    outfile.close();
 +
 
 +
}
 +
 
 +
};
 +
 
 +
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;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
 
  
     void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
+
     setlocale(LC_ALL,"RUS"); ///функция, позволяющая с++ распознавать русский язык
     {
+
 
        g = 9.8;///коэфф свободного падения
+
     double Vo, Agrad, Brad, time, step; ///объявляем тип переменных Vo (начальная скорость тела), Agrad (угол, под которым летит тело, в градусах);
        float t = 0; ///время
+
                                        ///Brad (угол, под которым летит тело, в радианах); time (время полета тела); step (шаг)
        X = new double [Size];///создаем массив для координат по х для простого падения
+
    cout<<"Задайте начальную скорость тела в м/с: Vo="; ///на экран выводится сообщение с просьюой задать начальную скорость тела
        E = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
+
    cin>>Vo; ///пользователь вводит начальную скорость тела
        X[0] = 0; ///задаем значение по х в нуле
+
    cout<<'\n'<<"Задайте в градусах угол, под которым брошено тело (угол должен принимать значения от 0 до 90): a=";
        E[0] = 0 ; ///задаем значение по х в нуле по эйлеру
+
                                                        ///на экран выводится сообщение с просьбой задать угол, под которым летит тело, в градусах
        for (int i = 1; i < Size; i++) ///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
+
    cin>>Agrad; ///пользователь вводит угол, под которым летит тело
        {
+
    cout<<'\n'<<"Задайте шаг (шаг должен быть очень маленьким): шаг="; ///на экран выводится сообщение с просьбой ввести шаг
            t += shag; ///каждый раз прибавляем по времени шаг
+
    cin>>step; ///пользователь вводит шаг
            X[i] = v * cos(a) * t; ///координаты по х для простого падения
+
 
            E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
+
    fly X(step,Agrad,Vo); ///объявление коструктора, создание функции Х, зависящей от step,Agrad,Vo
        }
+
    X.zapis("координаты.txt"); ///запись элементов функции в файл
     }
+
 
 +
     return 0; ///конец программы
 +
 
 +
}
 +
</syntaxhighlight>
 +
</div>
  
    void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
 
    {
 
        g = 9.8; ///коэфф свободного падения
 
        double Vy; /// переменная для значение скорости по у для метода эйлера
 
        float t = 0; ///время
 
        Y = new double [Size];///создаем массив для координат по у для простого падения
 
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
 
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
 
        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;///у из интегрирования по эйлеру
 
        }
 
    }
 
  
    void SetVerle() ///функция для метода верле
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    {
+
'''[[Васильева Анастасия]]'''
        double k = 0.1, m = 0.5; ///коэфф сопротивления водуха, масса тела
+
 
        g = 9.8; /// коэфф свободного падения
+
'''Описание программы''': пользователь вводит начальную скорость полета, угол бросания и шаг, с которым будут рассчитаны точки.  
        uint32_t Size1 = 1000000.0; ///размер массива
+
 
        S = new double [Size1]; ///создаем массив для значений по х для метода верле
+
Программа записывает в один файл результаты вычисления:
        Z = new double [Size1]; ///создаем массив для значений по у для метода верле
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
+
# Координаты, полученные при численном интегрировании - метод Эйлера;
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
        S[1] = 0; ///значение х метод верле
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
        S[0] = -vx * shag; ///значение в нуле
+
 
        Z[1] = 0; ///значение у метод верле
+
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
        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() ///функция записи в файл
+
<div class="mw-collapsible-content">
    {
+
 
        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();///закрываем файл
 
    };
 
};
 
  
int main()/// основная функция
+
'''Визуализированный результат работы программы'''
{
+
[[File:graphick.png]]
    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>
 
  
'''[[Гильманов Илья]]'''
+
Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;
  
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
+
# "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
#  Полет тела без сопротивления воздуха;  
+
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
# Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
+
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
# Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
+
# "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
  
Скачать можно [[http://mech.spbstu.ru/File:Движение_тела_в_среде.rar тут]]
 
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
'''[[Демченко Артём]]'''
 
 
 
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
 
 
''' Инструкция ''':
 
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
 
 
 
 
 
<div class="mw-collapsible-content">
 
 
 
 
 
 
 
'''Визуализированный результат работы программы'''
 
 
 
[[:File:Throws.png]]
 
 
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
  
 
#include <iostream>
 
#include <iostream>
#include <math.h>
+
#include <fstream>
 
#include <iomanip>
 
#include <iomanip>
#include <fstream>
+
#include <time.h>
 
#include <conio.h>
 
#include <conio.h>
#include <stdio.h>
+
#include <stdlib.h>
 
+
#include <math.h>
 
+
#include <cstring>
 
using namespace std;
 
using namespace std;
  
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
+
class pad ///создаем класс
 
 
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
 
 
{
 
{
     FILE *Coord;
+
private: ///в закрытом доступе
  Coord = fopen ("Throws Without Resistance.txt", "w");
+
     double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
    double X = 0, Y = 0; // Координаты начала
+
    double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
 +
    int Size; ///размер массива- сколько точек считать в первом способе
 +
    double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
  
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
+
    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; ///х из интегрирования по эйлеру
 +
        }
 +
    }
  
      X = Vo*t*cos(alpha);
+
    void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
      Y = Vo*t*sin(alpha) - (g*t*t)*0.5;
+
    {
      t+= dt;
+
        g = 9.8; ///коэфф свободного падения
    if (Y > Yo )
+
        double Vy; /// переменная для значение скорости по у для метода эйлера
         fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
+
        float t = 0; ///время
     else
+
        Y = new double [Size];///создаем массив для координат по у для простого падения
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
+
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
    }
+
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
 +
        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;///у из интегрирования по эйлеру
 +
         }
 +
     }
  
}
+
    void SetVerle() ///функция для метода верле
 
+
    {
int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
+
        double k = 0.1, m = 0.5; ///коэфф сопротивления водуха, масса тела
{                                                                                          // для линейной зависимости
+
        g = 9.8; /// коэфф свободного падения
    FILE *Coord;
+
        uint32_t Size1 = 1000000.0; ///размер массива
  Coord = fopen ("ExactForm.txt", "w");
+
        S = new double [Size1]; ///создаем массив для значений по х для метода верле
    double X, Y = 0, Vx, Vy;
+
        Z = new double [Size1]; ///создаем массив для значений по у для метода верле
 
+
        vx = v * cos(a); ///формулы для вычисления скорости по оси х
    while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
+
        vy = v * sin(a); ///формулы для вычисления скорости по оси у
    {
+
        S[1] = 0; ///значение х метод верле
 
+
        S[0] = -vx * shag; ///значение в нуле
      X = ((m*Vx)/R) * (1 - exp(((-1)*R*t)/m));
+
        Z[1] = 0; ///значение у метод верле
      Y = (m/R)*((Vy + (g*m)/R)*(1 - exp((-1)*R*t/m))) - (g*t*m)/R;
+
        Z[0] = -vy * shag; ///значение в нуле
      Vx = Vo*cos(alpha);
+
        for (int i = 0; i < Size1-2; i++) ///задаем цикл
      Vy = Vo*sin(alpha);
+
        {
      t+= dt;
+
            S[i+2] = 2.0 * S[i+1] - S[i] - (k / m) * v * vx * shag * shag;///значения по х для верле
    if (Y > Yo )
+
            vx = 0.5 * ( 1.0 / shag )* ( S[i+2] - S[i]);///считаем значения скорости по оси х
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
+
            Z[i+2] = 2.0 * Z[i+1] - Z[i] - ( g + (k / m) * v * vy ) * shag * shag;///значения по х для верле
    else
+
            vy = 0.5 * ( 1.0 / shag )* ( Z[i+2] - Z[i]);///считаем значения скорости по оси х
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
+
            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);///значения по х для точного верле
 +
        }
 +
    }
  
int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
+
public: ///в открытом
{                                                                                                    // для Квадратичной зависимости сопротивления от скорости
+
    pad()
    FILE *Coord;
+
    {
  Coord = fopen ("VerleSq.txt", "w");
+
        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();
 +
    }
  
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
+
     void FilePrint() ///функция записи в файл
                                                                  // Xop, Yop - вспомогательные координаты для (-1)-го шага
+
    {
 
+
        ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
     Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
+
        fout << "X:    " << "    Y:    " << "    E:  " << "  G:  " << "  S:  " << "  Z:  "<< "  V:  "<< "    U:    "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
     Xop = Xo - Vo*cos(alpha)*dt;
+
        for (int i = 0; i < Size; i++) ///цикл
     X = Xo;
+
        fout << X[i] << "    " << Y[i] << "    " << E[i] << "    "  << G[i] << "  " << S[i] << "  " << Z[i] << "  " << V[i] <<"    "<< U[i] <<"\n"; ///забивает сами значения массивов
     Y = Yo;
+
        fout.close();///закрываем файл
     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);
+
int main()/// основная функция
    V = sqrt((Vo*cos(alpha)*Vo*cos(alpha)) + (Vo*sin(alpha)*Vo*sin(alpha)));
+
{
 +
     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>
  
    fprintf(Coord, "%.3lf \t %.3lf\n", X, Y); // Записываем первую координату в файл
 
  
    Xprev = X; // Меняем координаты местами. Так (n-1)-ый шаг становится n-ым шагом, n-ый шаг становится (n+1)-ым шагом. Далее аналогично
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    X = Xnext;
+
'''[[Андреева Полина]]'''
    Yprev = Y;
 
    Y = Ynext;
 
  
 +
'''Краткое описание алгоритма''': в классе находятся координаты по формулам и записываются в файл.
  
    while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
+
''' Инструкция ''':
    {
+
Пользователь должен ввести начальную скорость, угол и шаг, с которым будут рассчитываться координаты. В файл координаты записываются в таком порядке: 1, 2 столбики - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха; 3, 4 - Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости; 5,6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости; 7,8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.  
    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);
+
Скачать можно  [http://tm.spbstu.ru/File:ТраекторияАнПол.rar тут].
  
    Xprev = X;
 
    X = Xnext;
 
    Yprev = Y;
 
    Y = Ynext;
 
    }
 
  
}
+
<div class="mw-collapsible-content">
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);
+
[[:File:graphAP.png]]
  
    Xprev = X;
+
Для тела с массой 1 кг,сопротивлением воздуха 0.001, угол бросания 60°, начальная скорость 50 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.00001;
    X = Xnext;
 
    Yprev = Y;
 
    Y = Ynext;
 
  
 +
# "MyFile.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# "MyFile.txt" using 3 : 4 -  Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# "MyFile.txt" using 5 : 6 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# "MyFile.txt" using 7 : 8 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости.
  
    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;
 
    }
 
  
}
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
+
#include <iostream>
int main()
+
#include <fstream>
 +
#include "math.h"
 +
#include <iomanip>
 +
using namespace std;
 +
class func
 
{
 
{
  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";
+
private:
   cin >> Vo; // Вводим с клавиатуры начальную скорость
+
    double speed0, angle0, step ;
   cout << "Enter angle in grades ( from 0 to 180 ):\n";
+
   double time;
  cin >> alpha; // Вводим с клавиатуры угол броска в градусах
+
 
  alpha = alpha*Pi / 180; // переводим угол броска из градусов в радианы
+
   public:
  cout << "Enter mass:\n";
+
      double const g=9.8, n=0.001, m=1;///постоянная g, n-коэфициент сопротивления воздухаб m-масса
  cin >> m; // Вводим с клавиатуры массу
+
      double t, amount;
  cout << "Enter precision:\n";
+
      int amountint;
  cin >> dt; // Вводим с клавиатуры шаг по времени
+
    func ( double _speed0, double _angle0, double _step ):speed0(_speed0), angle0(_angle0), step(_step)
  cout << "Enter resistance:\n";
+
    {
  cin >> R; // Вводим сопротивление воздуха
+
        angle0=(3.14159*angle0) / 180 ; ///перевод угла в радианы
  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";
 
  
 +
        time = ( 2*speed0*sin(angle0) ) / g;///подсчет полного времени полета
 +
        amount = (time/step) + 1;///количество точек для траектории
 +
        amountint =  static_cast<int> (amount) ;
  
    FILE *Gnu;
 
    Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
 
  
switch ( i )
+
    }
{
+
 
case 1:
+
 
    {
+
 
    WoutR(alpha,dt,t,Yo,Vo);
+
      void SaveFile(char filename[])
     fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
+
     {
    break;
+
        double x0=0, y0=0;
    }
+
        double xv1=0, x1=0, y1=0, Vx1=speed0*cos(angle0),Vy1=speed0*sin(angle0), V1=speed0, yv1=0;
case 2:
+
        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;
    ExactForm(alpha,dt,t,Yo,Vo,R,m);
+
        double xm2=x0-speed0*cos(angle0)*step, ym2=y0-speed0*sin(angle0)*step;
    fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
+
        double x3,y3;
    break;
+
        std::ofstream fout(filename);
    }
+
        for (int i=0; (y0+(speed0*sin(angle0)*i*step - (g*i*i*step*step*0.5)))>=0; i++)
case 3:
+
        {
    {
+
            ///Верле линейная зависимость
    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
+
            x2=2*xv2-xm2-(n/m)*step*step*Vx2;
    fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
+
            y2=2*yv2-ym2-(g+(n/m)*Vy2)*step*step;
    break;
+
            Vx2=(x2-xm2) / (2.0*step);
    }
+
            Vy2=(y2-ym2) / (2.0*step);
case 4:
+
            xm2=xv2;
    {
+
            xv2=x2;
    VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
+
            ym2=yv2;
    fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
+
            yv2=y2;
    break;
 
    }
 
case 5:
 
    {
 
  WoutR(alpha,dt,t,Yo,Vo);
 
  ExactForm(alpha,dt,t,Yo,Vo,R,m);
 
  VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 
  VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
 
  fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l, \"ExactForm.txt\" using 1:2 w l, \"VerleSq.txt\" using 1:2 w l, \"VerleL.txt\" using 1:2 w l"); // записываем в Throws.gp названия четырех файлов
 
  break;
 
    }                                                  // с координатами таким образом, чтобы программа gnuplot смогла их увидеть и прочесть
 
case 0:
 
    break;
 
default:
 
    break;
 
}
 
    return 0;
 
}
 
  
</syntaxhighlight>
+
            ///точное решение
</div>
+
            x3=x0+speed0*cos(angle0)*(m/n)*(1.0-exp(-(n/m)*i*step));
 +
            y3=y0+(m/n)*(speed0*sin(angle0) + g*(m/n))*(1.0-exp(-(n/m)*i*step))-g*(m/n)*i*step;
  
 +
            ///метод Верле, квадратичная зависимость
 +
            x1=2*xv1-xm1-(n/m)*step*step* Vx1 * V1;
 +
            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;
  
'''[[Иванова Яна]]'''
 
 
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
 
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
 
  
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
 
  
<div class="mw-collapsible-content">
+
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";
'''Визуализированный результат работы программы'''[[File:graph.png]]
 
  
[[:File:graph.png]]
+
        }
 +
        fout.close();
 +
    }
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
};
#include <iostream>
 
#include <math.h>
 
#include <iomanip>
 
#include <fstream>
 
#include <conio.h>
 
 
 
 
 
using namespace std;
 
 
 
ofstream outfile;
 
 
 
double perevod (double angle) //перевод из градусов в радианы
 
{
 
    return (angle * M_PI / 180 );
 
}
 
  
  
 
int main()
 
int main()
 
{
 
{
     //объявление переменных и задание начальных значений
+
     double V0, angle, step;
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
+
    cout << " enter V0 = ";///введите начальную скорость
     m = 1 , dt = 0.1 , g = 9.8,t = 0,
+
     cin >> V0;
     ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
+
     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");///запись в файл
 +
 
  
     alpha = perevod (ugol);
+
     return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
  
    //точное решение для случая движения без сопротивления воздуха
 
    Y = Yo;
 
    X = Xo;
 
  
    outfile.open("1.txt");
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Иванова Яна]]'''
  
    while (Y >= Yo)
+
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
    {
+
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
        X = Xo + Vo * cos(alpha) * t;
 
        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;
+
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
    }
 
    outfile.close();
 
  
    //начальные условия для квадратичной зависимости (метод Верле)
+
<div class="mw-collapsible-content">
    Yprev = Yo - Vo*sin(alpha)*dt;
+
'''Визуализированный результат работы программы'''[[File:graph.png]]
    Xprev = Xo - Vo*cos(alpha)*dt;
+
 
    X = Xo;
+
[[:File:graph.png]]
    Y = Yo;
+
 
    V = Vo;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    Vx = Vo * cos(alpha);
+
#include <iostream>
    Vy = Vo * sin(alpha);
+
#include <math.h>
 +
#include <iomanip>
 +
#include <fstream>
 +
#include <conio.h>
  
    outfile.open("2.txt");
 
  
    while (Y >= Yo)
+
using namespace std;
    {
 
        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;
+
ofstream outfile;
        X = Xnext;
 
        Yprev = Y;
 
        Y = Ynext;
 
    }
 
    outfile.close();
 
  
    //начальные условия для линейной зависимости (метод Верле)
+
double perevod (double angle) //перевод из градусов в радианы
    Yprev = Yo - Vo*sin(alpha)*dt;
+
{
     Xprev = Xo - Vo*cos(alpha)*dt;
+
     return (angle * M_PI / 180 );
    X = Xo;
+
}
    Y = Yo;
 
    V = Vo;
 
    Vx = Vo * cos(alpha);
 
    Vy = Vo * sin(alpha);
 
  
    outfile.open("3.txt");
 
  
    while (Y >= Yo)
+
int main()
     {
+
{
        Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
+
     //объявление переменных и задание начальных значений
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
+
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
+
    m = 1 , dt = 0.1 , g = 9.8,t = 0,
        Vy = (Ynext - Yprev)/ (2.0 * dt);
+
    ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
        V = sqrt(Vy*Vy + Vx*Vx );
 
        outfile << X << ' ' << Y << endl;
 
  
        Xprev = X;
+
    alpha = perevod (ugol);
        X = Xnext;
 
        Yprev = Y;
 
        Y = Ynext;
 
    }
 
    outfile.close();
 
  
     //точное решения для линейной зависимости
+
     //точное решение для случая движения без сопротивления воздуха
 
     Y = Yo;
 
     Y = Yo;
 
     X = Xo;
 
     X = Xo;
    t = 0;
 
  
     outfile.open("4.txt");
+
     outfile.open("1.txt");
  
 
     while (Y >= Yo)
 
     while (Y >= Yo)
 
     {
 
     {
 +
        X = Xo + Vo * cos(alpha) * t;
 
         Vx = Vo * cos(alpha);
 
         Vx = Vo * cos(alpha);
         Vy = Vo * sin(alpha);
+
         Y = Yo + Vo * sin(alpha) * t  - 0.5 * g * t * t;
        X = (m * Vx / R)* (1 - exp(-1 * R * t / m));
+
         Vy = Vo * sin(alpha) - g * t;
         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;
 +
    V = Vo;
 +
    Vx = Vo * cos(alpha);
 +
    Vy = Vo * sin(alpha);
  
}
+
    outfile.open("2.txt");
  
</syntaxhighlight>
+
    while (Y >= Yo)
</div>
+
    {
 +
        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>
+
        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");
  
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
    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;
  
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
+
        Xprev = X;
 +
        X = Xnext;
 +
        Yprev = Y;
 +
        Y = Ynext;
 +
    }
 +
    outfile.close();
  
</div>
+
    //точное решения для линейной зависимости
 +
    Y = Yo;
 +
    X = Xo;
 +
    t = 0;
  
<div>
+
    outfile.open("4.txt");
'''[[Киселёв Лев]]'''
 
  
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
+
    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;
 +
 
 +
}
  
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
+
</syntaxhighlight>
 
</div>
 
</div>
 +
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
'''[[Лебедев Станислав]]'''  
+
'''[[Уманский Александр]]'''  
  
 
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
Строка 902: Строка 912:
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
Скачать можно  [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>
[[File:graph.png]]
+
</div>
  
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Лосева Татьяна ]]'''
  
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
+
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
 
 +
<div class="mw-collapsible-content">
 +
 
 +
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
  
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
+
[[File:загружено (1).png]][[:File:загружено (1).png]]
  
Файл "'''main.cpp'''"
 
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
#include <iostream>
+
#include<iostream>
#include <math.h>
+
using namespace std;
#include "Vector.h"
+
#define N 1
#include <cstring>
+
#define PI 3.14159265
#include <cmath>
 
#include <malloc.h>
 
 
#include <fstream>
 
#include <fstream>
 +
#include<cmath>
 +
double g=9.8;
 +
double step=0.01;
 +
#include<math.h>
  
using namespace std;
+
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  
int n = 100;
 
ofstream outfile;
 
 
class Ball                                          //класс бросаемого тела
 
 
{
 
{
    private:
+
double x,y;
        double angle,m,k;                           //угол броска,масса,коэффицент сопротивления воздуха
+
        Vector3D r,v,a;                            //радиус-вектор,вектор скорости,ускорения
+
ofstream fout;//открытие файла
    public:
+
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
 +
cout<<"method1"<<endl;
 +
 
 +
  for(double t=0.01;t<N;t=t+0.01)
 +
{
 +
y=v*t*sin(r*PI/ 180)-g*t*t/2;//координата y
 +
x=v*t*cos(r*PI / 180);//координата х
 +
 
 +
fout<<x<<"  ";//запись в файл х
 +
cout<<"X="<<x<<endl;//вывод на экран
 +
    fout<<y<<"    ";//запись в файл
 +
cout<<"Y="<<y<<endl<<endl;//вывод на экран
 +
fout<<endl;
 +
  }
 +
}
 +
 
 +
void Verle1( double n,double m ,double v0,double r)//Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
+
{
        Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
+
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);
        {
 
            angle = _angle;
 
            r    = _r;
 
            v    = _v;
 
            a    = _a;
 
        }
 
  
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
+
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
        Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
+
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
        {
 
            angle = _angle;
 
            r     = _r;
 
            v    = _v;
 
            a    = _a;
 
            m    = _m;
 
            k    = _k;
 
        }
 
  
        //точная формула зависимости координаты от времени
+
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
        Vector3D positionReal(double t)
+
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
        {
+
  ofstream fout;//открытие файла
            double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
+
fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
            return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
+
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 writePosToScreen()
+
}
        {
 
            cout << r.x << "  " << r.y << "  " << r.z << endl;
 
        }
 
  
        //вывод положения в файл
+
void Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
        void writePosToFile(char s[])
 
        {
 
            outfile.open(s,ios :: app);
 
            outfile << r.x << "          " << r.y << endl;
 
            outfile.close();
 
        }
 
  
        //вывод произвольного вектора на экран
+
{
        void WVTS(Vector3D v)
+
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);
        {
 
            cout.width(15);
 
            cout << v.x;
 
            cout.width(15);
 
            cout << v.y;
 
            cout.width(15);
 
            cout << v.z << endl;
 
        }
 
  
        //вывод произвольного вектора в файл
+
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
        void WVTF(Vector3D v,char s[])
+
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
        {
 
            outfile.open(s,ios :: app);
 
            outfile << v.x << "          " << v.y << endl;
 
            outfile.close();
 
        }
 
  
        //"пересчет" координаты по Верле(Линейная зависмость)
+
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
        void changeR(Vector3D r1, double dt)
+
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
        {
+
  ofstream fout;//открытие файла
            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 );
+
  fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
        }
+
cout<<"Verle2"<<endl<<endl;
 +
for(double t=0.02;t<N;t=t+step)
 +
{
  
        //"пересчет" координаты по Верле(Квадратичная зависимость)
+
  v=sqrt(vx*vx+vy*vy);//скорость V
        void changeRSQ(Vector3D r1, double dt)
 
        {
 
            r = MakeVector(2 * r.x -  r1.x - k/m*Length(v)*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*Length(v)*v.y)*dt*dt, 0 );
 
        }
 
        //пересчет скорости по Верле
 
        void changeV(Vector3D r1,double dt)
 
        {
 
            v =VS((VmV(r,r1)),1/(2*dt));
 
        }
 
  
        //рассчет предыдущегт к 0ому элементу
+
x=2*x0-xn_1-(n*v*vx*step*step)/m;//Xn+1
        Vector3D MR1(double dt)
+
vx=(x-xn_1)/(2*step);//скорость Vx
         {
+
         xn_1=x0;//для следущего шага Xn-1=Xn
            return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
+
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
        Vector3D getR()
+
yn_1=y0;//для следущего шага Yn-1=Yn
        {
+
y0=y;//для следущего шага Yn=Yn+1
            return r;
+
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)//Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
        double TimeOfFly()
 
        {
 
            return (2*Length(v)*sin(angle)/Length(a));
 
        }
 
 
 
        //рассчет координаты по точной формуле. без сопротивления воздуха.
 
        Vector3D position(double t)
 
        {
 
            return MakeVector(r.x + v.x*t + a.x*t*t/2,r.y + v.y*t + a.y*t*t/2,r.z + v.z*t + a.z*t*t/2);
 
        }
 
 
 
};
 
 
 
int main()
 
 
{
 
{
    //задание начальных параметров
+
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
 +
  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;//координата у
  
    dt = 0.1;
+
//вывод в файл  и на экран
    a = (M_PI * 30)/180;
+
    cout<<"X="<<x<<endl;
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
+
cout<<"Y="<<y<<endl<<endl;
 +
fout<<x<<" ";
 +
fout<<y<<" ";
 +
fout<<endl;  
  
    double tof = b1.TimeOfFly()+1;  //единичка прибавлена,чтобы график красивым был
+
}
 +
}
 +
 
 +
int main(void)
 +
{
  
    //Без сопротивления возлуха
+
double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
    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);
 
    }
 
  
 +
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);
  
    //Верле(Линейная зависимость)
 
    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,"");
+
int k;
    strcat(s, "o3.txt");
+
cin>>k;
    outfile.open(s, ios :: trunc);
+
return 0;
    outfile.close();
+
}
    for (double i = 0; i <= 20; i += dt)
 
    {
 
        b3.WVTS(b3.positionReal(i));
 
        b3.WVTF(b3.positionReal(i), s);
 
    }
 
  
 +
</syntaxhighlight>
 +
</div>
  
    //Верле (Квадратичная зависимость)
+
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
    dt = 0.1;
 
    a = (M_PI * 30)/180;
 
    Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
 
  
    strcpy(s,"");
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    strcat(s, "o4.txt");
+
'''[[Степанянц Степан]]'''
    outfile.open(s, ios :: trunc);
 
    outfile.close();
 
    r1 = b4.MR1(dt);
 
    for (double i = 0; i <= 20; i += dt)
 
    {
 
        rp = b4.getR();
 
        b4.writePosToFile(s);
 
        b4.writePosToScreen();
 
        b4.changeRSQ(r1,dt);
 
        b4.changeV(r1,dt);
 
        r1.x = rp.x;
 
        r1.y = rp.y;
 
    }
 
  
    return 0;
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
}
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
</syntaxhighlight>
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
Файл "'''Vector.h'''"
+
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#ifndef VECTOR_H_INCLUDED
 
#define VECTOR_H_INCLUDED
 
  
struct Vector3D
+
<div class="mw-collapsible-content">
{
+
[[File:graph239.png]]
  double x,y,z;
 
};
 
  
Vector3D VmV(Vector3D v1,Vector3D v2)              //векторное вычитание
+
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
{
 
    Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
 
    return v;
 
};
 
Vector3D VpV(Vector3D v1,Vector3D v2)              //векторное сложение
 
{
 
    Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
 
    return v;
 
}
 
  
double VV(Vector3D v1,Vector3D v2)              //скалярное умножение
 
{
 
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
 
}
 
  
Vector3D VxV(Vector3D v1,Vector3D v2)              //векторное умножение
 
{
 
  Vector3D v = {v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z,v1.x*v2.y - v1.y*v2.x};
 
  return v;
 
}
 
  
bool Kol(Vector3D v1,Vector3D v2)
+
Файл "'''main.cpp'''"
{
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  return ((v1.x/v2.x == v1.y/v2.y)&&(v1.z/v2.z == v1.y/v2.y))? true:false;
+
#include <iostream>
}
+
#include <locale.h>
 
+
#include <math.h>
Vector3D VS(Vector3D v1, double s)
+
#include <fstream>
 +
#include<iomanip>
 +
#include <cmath>
 +
using namespace std;
 +
main ()
 
{
 
{
     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
+
     ofstream F;
    return v;
+
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;
 +
a=a1*M_PI/180; //Градусы в радианы
 +
t=0;
  
double Length(Vector3D v1)
+
//Движение без сопротивления воздуха
 +
F.open("C:\\1.txt",ios::out);
 +
while(y>=0)
 
{
 
{
     return sqrt(VV(v1,v1));
+
     x=x0+u0*cos(M_PI/6)*t;
}
+
    y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t;
 +
  F<<x<<" "<<y<<endl;
 +
  t=t+dt;
  
Vector3D MakeVector(double x,double y,double z)
 
{
 
    Vector3D v = {x,y,z};
 
    return v;
 
 
}
 
}
  
Vector3D MakeVector(double length,double angle)
+
F.close();
 +
//Точное решение для линейной зависимости
 +
F.open("C:\\2.txt",ios::out);
 +
y=y0;
 +
x=x0;
 +
t=0;
 +
while(y>=0)
 
{
 
{
    Vector3D v = {length * cos(angle), length * sin(angle),0};
+
        ux = u0 * cos(a);
    return v;
+
        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;
  
double Proection(Vector3D base, Vector3D dir)
+
      F << x << ' ' << y << endl;
{
 
    return (VV(base,dir)/Length(base));
 
}
 
#endif // VECTOR_H_INCLUDED
 
</syntaxhighlight>
 
</div>
 
  
  
<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;
После этого полученные в результате работы программы данные выводятся в файл.
+
        x = xsl;
 +
        ypr = y;
 +
        y = ysl;
 +
    }
 +
    F.close();
  
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
 
[[http://tm.spbstu.ru/File:phys.rar тут]]
 
  
</div>
+
return 0;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''[[Лосева Татьяна ]]'''
 
  
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела  и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
+
}
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
<div class="mw-collapsible-content">
+
</syntaxhighlight>
 +
</div>
  
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
 
  
[[File:загружено (1).png]][[:File:загружено (1).png]]
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Александр Сюрис]]'''
  
 +
'''Описание программы''':
 +
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
 +
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
 +
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении          воздуха от скорости
 +
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 +
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
Скачать можно  [http://mech.spbstu.ru/File:%D0%9F%D0%BE%D0%BB%D0%B5%D1%82_%D1%82%D0%B5%D0%BB%D0%B0(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip тут].
 +
<div class="mw-collapsible-content">
 +
[[File:Снимок.PNG]]
 +
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 +
Файл "'''main.cpp'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
#include<iostream>
+
#include <iostream>
 +
#include <fstream>
 +
#include <math.h>
 +
#include <cmath>
 
using namespace std;
 
using namespace std;
#define N 1
+
int o;
#define PI 3.14159265
+
double v,a,m,k;
#include <fstream>
+
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
#include<cmath>
+
 
double g=9.8;
 
double step=0.01;
 
#include<math.h>
 
  
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
  
 +
int rez_1(double v, double a)
 
{
 
{
double x,y;
+
    fout<<"---------------Первый режим-------------------------"<<endl;
+
    fout<<" T=0 x=0 y=0";
ofstream fout;//открытие файла
+
    fout<<endl;
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
+
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
cout<<"method1"<<endl;
+
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
 +
    V0y=v*sin(a/180*M_PI);
 +
    Ty=2*V0y/g;//время полета
 +
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
 +
    {
 +
        x=x+V0x*t;              //ф-лы для рассчета x и y в данный момент времени
 +
        y=y+V0y*t-g*pow(t,2)/2;
 +
 
 +
        if (y<0) //если y<0
 +
            {
 +
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
 +
                x=x+V0x*t1;//используя это время находим координату по х
 +
                fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
 +
                break;
 +
            }
 +
            else
 +
                {
 +
                    V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
 +
                    fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
 +
                    T=T+t;//увел время на шаг
 +
                }
 +
    }
 +
 
  
  for(double t=0.01;t<N;t=t+0.01)
 
{
 
y=v*t*sin(r*PI/ 180)-g*t*t/2;//координата y
 
x=v*t*cos(r*PI / 180);//координата х
 
 
 
fout<<x<<"  ";//запись в файл х
 
cout<<"X="<<x<<endl;//вывод на экран
 
    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);
 
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
+
int rez_2(double v, double a, double k, double m)
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
+
{
 +
    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;
 +
    }
 +
 
  
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
+
}
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
 
  ofstream fout;//открытие файла
 
fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
 
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 Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
{  
+
int rez_3(double v, double a, double k, double m)
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<<"---------------Третий режим работы-------------------------"<<endl;
 +
    fout<<" T=0 x=0 y=0";
 +
    fout<<endl;
 +
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
 +
    x3=0,x2=0,x1=x2-Vxn*t, y3=0,
 +
    y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 +
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
  
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
+
    x3=2*x2-x1-k/m*Vxn*pow(t,2);   //координаты в момент времени T
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
+
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
  ofstream fout;//открытие файла
+
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
  fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
+
    Vyn=(y3-y1)/(2.0*t);
cout<<"Verle2"<<endl<<endl;
+
    x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
for(double t=0.02;t<N;t=t+step)
+
    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;
  
  v=sqrt(vx*vx+vy*vy);//скорость V
+
        if (y3<0)
 +
        {
 +
            t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
 +
            x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
 +
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 +
        }
 +
 
 +
        T=T+t;
 +
        x1=x2;
 +
        y1=y2;
 +
        x2=x3;
 +
        y2=y3;
 +
 
 +
    }
  
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_4(double v, double a, double k, double m)
 
{
 
{
double x,y,x0=0,y0=0;//x0,y0 начальные значения;
+
  fout<<"---------------Четвертый режим работы-------------------------"<<endl;
 +
    fout<<" T=0 x=0 y=0";
 +
    fout<<endl;
 +
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
 +
    x3=0,x1=0, x2=x1+Vxn*t, y3=0, y1=0,
 +
    y2=y1+Vyn*t, g=9.8, t1, T=0.1, V=v;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 +
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
  
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.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
    cout<<"X="<<x<<endl;
+
    y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
cout<<"Y="<<y<<endl<<endl;
+
    Vxn=(x3-x1)/(2.0*t);
fout<<x<<" ";
+
    Vyn=(y3-y1)/(2.0*t);
fout<<y<<" ";
+
    V=sqrt(pow(Vxn,2)+pow(Vyn,2.0));
fout<<endl;  
+
    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)));
int main(void)
+
            x3=2.0*x2-x1-(k/m)*Vxn*V*pow((t+t1),2);
{
+
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 +
        }
  
double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
 
 
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);
 
  
 +
        T=T+t;
 +
        x1=x2;
 +
        y1=y2;
 +
        x2=x3;
 +
        y2=y3;
  
 +
    }
  
int k;
 
cin>>k;
 
return 0;
 
 
}
 
}
  
</syntaxhighlight>
 
</div>
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
+
int main()
 +
{
  
<div>
+
setlocale(LC_ALL, "rus");
 +
cout<<"Введите скорость тела и угол"<<endl;
 +
cin>>v>>a;
  
'''[[Ляжков Сергей]]'''
+
while (1>0){
 
+
cout<<"Выберите режим работы программы:"<<endl;
'''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
+
cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
+
cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
+
cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
+
cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
</div>
+
cout<<"5 - Выйти";
 +
cin>>o;
  
<br>'''[[Нарядчиков Александр]]'''<br>
+
if (o==1)
'''Инструкция:''' Пользователю достаточно просто запустить программу.<br>
+
    rez_1(v,a);
'''Описание программы:''' В комнате скачут 4 мячика, первый двигается без сопротивления воздуха, второй двигается с квадратичной зависимостью сопротивления воздуха от скорости (Метод Верле), третий двигается с линейной зависимостью сопротивления воздуха от скорости (точное решение), четвертый двигается с линейной зависимостью сопротивления воздуха от скорости (Метод Верле).<br>
+
if (o==2)
'''Описание алгоритма:''' Программа реализована с помощью системы анимации(class anim), используя библиотеки OpenGl и GLUT. Изменения координат мячей проходят в режиме реального времени в векторной форме.<br>
+
    {
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
"'''T06BALL.CPP'''"
+
    cin>>m>>k;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    rez_2(v,a,k,m);
/* FILENAME: T06BALL.CPP
+
    }
* LAST UPDATE: 17.01.2016
 
*/
 
  
#include "ANIM.H"
+
if (o==3)
#include "SAMPLE.H"
+
    {
 
+
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
/* Main function */
+
    cin>>m>>k;
void main( void )
+
    rez_3(v,a,k,m);
{
+
    }
// Получение единственного экземпляра класса анимации
+
  if (o==4)
sagl::anim &My = sagl::anim::Get();
+
    {
    
+
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
// Шар, летящий без сопротивлением воздуха
+
    cin>>m>>k;
        for (int i = 0; i < 1; i++)
+
    rez_4(v,a,k,m);
                My << new ball(Pi / 6, 10 + i);
+
    }
 +
   if (o==5)
 +
        break;
  
// Шар, летящий с сопротивлением воздуха
+
            }
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
+
}
for (int i = 0; i < 1; i++)
 
My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
 
  
// Шар, летящий с сопротивлением воздуха
 
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
 
for (int i = 0; i < 1; i++)
 
My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
 
  
// Шар, летящий с сопротивлением воздуха
+
</syntaxhighlight>
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
+
</div>
for (int i = 0; i < 1; i++)
 
My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
 
  
// Запуск главного цикла
 
  My.Run();
 
} // End of 'main' function
 
  
// END OF 'T43ANIM.CPP' FILE
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
</syntaxhighlight>
+
'''[[Тимошенко Валентина]]'''  
"'''ANIM.CPP'''"
+
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
'''Описание программы''': при запуске пользователь вводит шаг функции, угол, под которым бросают тело, массу тела, сопротивление воздуха и скорость.
/* FILENAME: ANIM.CPP
+
Программа записывает в четыре файла результаты вычисления:
* LAST UPDATE: 17.01.2016
+
#Координаты, рассчитанные по формуле для движения без сопротивления воздуха;
*/
+
#Координаты, рассчитанные по формуле для движения с учетом сопротивления воздуха;
 +
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивления воздуха от скорости.
 +
#Координаты, полученные методом Верле при линейной зависимости силы сопротивления воздуха от скорости;
 +
 
 +
Скачать можно  [http://tm.spbstu.ru/Файл:motion.zip тут.]
 +
 
 +
<div class="mw-collapsible-content">
 +
 
 +
'''Визуализированный результат работы программы'''
 +
[[File:Grafics.png]]
  
#include <stdio.h>
+
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
#include <stdlib.h>
 
#include <time.h>
 
  
#include "ANIM.H"
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
// Единственный экземпляр класса
+
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
sagl::anim sagl::anim::Instance;
+
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
 +
#include <math.h>
 +
#include<stdlib.h>
 +
using namespace std;
  
/* Reshape function */
+
int main()
// Стандартная функция, вызываемая при изменении размеров окна
 
void sagl::anim::Reshape( int W, int H )
 
 
{
 
{
  // Установка области просмотра - все окно
+
    double a, step, Pi, g, Vo, m, r;
glViewport(0, 0, W, H);
+
     ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
  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 */
+
    double x, y, x_0, y_0, x0, y0, Vx, Vy;
// Подсчет времени
+
    ///переменные для движения точки без учёта сопротивления и с его учётом
void sagl::anim::Timer( void )
+
    ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
{
+
    ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
  long Time = clock();
+
     ///Vx - скорость тела по оси Ох, - скорость тела по оси Оу
 
+
     ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
  if (IsPause)
 
     DeltaTime = 0, PauseTime += Time - OldTime;
 
  else
 
     DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;
 
  OldTime = Time;
 
  
  SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
+
    double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
} /* End of 'Timer' function */
+
    ///переменные для 1го варианта метода Верле
 +
    ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
 +
    ///у1 - координата тела по оси Оу на (n-1) шаге, у2 - координата тела по оси Оу на (n) шаге, у3 - координата тела по оси Оу на (n+1) шаге
 +
    ///Vx0 - начальная скорость тела по оси Ох, Vy0 - начальная скорость тела по оси Оу
 +
    ///Vxn - скорость тела в данный момент времени по оси Ох, Vyn - скорость тела в данный момент времени по оси Оу
  
/* Display function */
+
    double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
// Стандартная функция, вызываемая при перерисовке окна
+
    ///переменные для 2го варианта метода Верле
void sagl::anim::Display( void )
+
    ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
{
+
    ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
// Запуск времени
+
    ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
Instance.Timer();
 
// Очищаем цветовой буфер для создания нового изображения
 
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
  
  glLoadIdentity();
+
    g=10; ///значение ускорения свободного падения
  // Позиционирование СК
+
    Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
 
  
// Отрисовка объектов
+
    do ///цикл, запрашивающий ввод пользователем значения шага функции
  Instance.Render();
+
    {
 +
        cout << "Input the step, it must be less than 1" << endl; ///ввод с клавиатуры шага(то же самое, что дельта t), шаг должен быть маленьким (меньше 1)
 +
        cin >> step;  ///вывод величины шага на экран
 +
    }
 +
    while (step>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
  
  glFinish();
+
    cout << '\n' << "Input the corner in degrees,the corner is in the range from 0 to 90 degrees" << endl; ///ввод с клавиатуры угла в радианах (угол от 0 до 90 градусов)
// Копируем вторичный буфер в окно
+
    cin >> a; ///вывод значение угла на экран
glutSwapBuffers();
+
    a=(Pi*a)/180.0;
// Вызываем функцию обновления кадра
+
    cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
glutPostRedisplay();
+
    cin >> m; ///вывод величины массы на экран
} // End of 'Display' function
+
 
 +
    do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
 +
    {
 +
        cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
 +
        cin >> r; ///вывод значения сопротивления на экран
 +
    }
 +
    while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
  
/* Keyboard function */
+
     cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
+
     cin >> Vo; ///вывод значения скорости на экран
void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
 
{
 
// Выход из программы
 
if (Key == 27)
 
     exit(0);
 
// Открытие программы в полном экране
 
else if (Key == 'f')
 
    glutFullScreen();
 
  // Пауза
 
else if (Key == 'p' || Key == 'P')
 
     Instance.IsPause = !Instance.IsPause;
 
} // End of 'Keyboard' function
 
  
sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
+
    ///для движения без учёта сопротивления
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
+
    x0=0; ///обнуление переменных
{
+
    y0=0;
// Инициализации OpenGL и GLUT
+
    x=0;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+
    y=0;
 
+
 
// Задача размеров и позиции окна
+
    ///для движения с учётом сопротивления
glutInitWindowPosition(0, 0);
+
    x_0=0; ///обнуление переменных
  glutInitWindowSize(700, 700);
+
    y_0=0;
// Создание окна
 
glutCreateWindow("T06BALL");
 
  
// Установка функций 'обратного вызова'
+
    ///для 1го варианта метода Верле
  glutDisplayFunc(Display);
 
  glutKeyboardFunc(Keyboard);
 
  glutReshapeFunc(Reshape);
 
  
// Установка цвета закраски фона
+
    Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
  glClearColor(0.3, 0.5, 0.7, 1);
+
    Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
  // Включение буфера глубины
 
glEnable(GL_DEPTH_TEST);
 
  // Включение режима вычисления цвета согласно освещенности от источников света
 
glEnable(GL_LIGHTING);
 
// Включение источника света
 
  glEnable(GL_LIGHT0);
 
// Включение упрощенного режима освещенности для простого способа описания свойств поверхности
 
  glEnable(GL_COLOR_MATERIAL);
 
// Приведение нормалей к единичной длине
 
  glEnable(GL_NORMALIZE);
 
}
 
  
// Деструктор
+
    x2=0; ///обнуление переменных
sagl::anim::~anim( void )
+
    y2=0;
{
+
    x3=0;
  // Чистка памяти
+
     y3=0;
for (int i = 0; i < StockSize; i++)
 
     delete Stock[i];
 
}
 
  
/* Render function */
+
    y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
// Отрисовка объектов
+
    x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
void sagl::anim::Render( void )
 
{
 
for (int i = 0; i < StockSize; i++)
 
Stock[i]->Render(*this);
 
} // End of 'Render' function
 
  
/* Run function */
+
    ///для 2го варианта метода Верле
// Запуск главного цикла
 
void sagl::anim::Run( void )
 
{
 
// Запуск основного цикла построения
 
glutMainLoop();
 
} // End of 'Run' function
 
  
// END OF 'ANIM.CPP' FILE
+
    x_2=0; ///обнуление переменных
</syntaxhighlight>
+
    y_2=0;
"'''ANIM.H'''"
+
    x_3=0;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    y_3=0;
/* FILENAME: ANIM.H
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#ifndef __ANIM_H_
+
    Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
#define __ANIM_H_
+
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
 +
 
 +
    y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
 +
    x_1=-Vo*cos(a)*step;    ///расчет начального значения координаты на (п-1) шаге по оси Ох
  
#include <stdio.h>
+
    ofstream out("For method without resistance.txt");
#include <stdlib.h>
+
    ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
#include <time.h>
 
  
#include <GL\glut.h>
+
    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
  
#include "VEC.H"
+
        out << x << "   " << y <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
 +
    }
 +
    out.close();
  
// Константы
+
    ofstream out1 ("For method with resistance.txt");
#define Pi 3.14159265358979323846
+
    ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
#define E 2.71828182845904523536
 
  
// Собственное пространство имен 'sagl'
+
    for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
namespace sagl
+
    {
{
+
        Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
  // Объявления класса анимации наперед
+
        Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
class anim;
+
        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
// Функции получения случайных чисел
+
 
inline double r0( void )
+
        out1 << x_0 << "    " << y_0 <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
  {
 
    return rand() / (double)RAND_MAX;
 
  }
 
  inline double r1( void )
 
  {
 
    return 2.0 * rand() / RAND_MAX - 1;
 
  }
 
 
 
// Класс объектов
 
class object
 
  {
 
  public:
 
    // Вектора перемещения и скоростей
 
vec P, V, AbsV;
 
   
 
// Конструктор
 
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
 
    {
 
 
     }
 
     }
+
    out1.close();
// Отрисовка объектов
+
 
virtual void Render( anim &Ani )
+
    ofstream out2 ("For method Verle 1.txt");
 +
    ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
 +
 
 +
    for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
 
     {
 
     {
    } // End of 'Render' function
+
        x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
  }; // end of 'object' class
+
        y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
 
+
        Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
// Класс анимации
+
        Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
class anim
+
        Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
  {
+
 
  private:
+
        x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
    // Функции 'обратного вызова'
+
        x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
static void Display( void );
+
        y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
    static void Keyboard( unsigned char Key, int X, int Y );
+
        y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
     static void Reshape( int W, int H );
+
 
 +
        out2 << x3 << "  " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
 +
    }
 +
     out2.close();
  
     // Единственный экземпляр класса
+
     ofstream out3 ("For method Verle 2.txt");
static anim Instance;
+
     ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
      
 
    // Конструктор
 
anim( void );
 
  
// Максимальное количество объектов
+
     for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
     static const int Max = 100;
+
     {
    // 'Контейнер' объектов
+
        x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
object *Stock[Max];
+
        y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
    // Размер 'контейнера' объектов
+
        Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
int StockSize;
+
        Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
      
 
// Переменные, хранящие время в секундах
 
    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;
 
  
// Переменные, хранящие время в секундах
+
        x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
    double SyncTime, DeltaTime;
+
        x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
 +
        y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
 +
        y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
  
    // Переменная, отвечающая за паузу
+
        out3 << x_3 << "  " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
bool IsPause;
 
  
     // Деструктор
+
     }
~anim( void );
+
     out3.close();
   
 
// Запуск главного цикла
 
void Run( void );
 
   
 
     // Метод, возвращающий переменную - единственный экземпляр данного типа
 
static anim & Get( void )
 
    {
 
      return Instance;
 
    }
 
  }; // end of 'anim' class
 
} // end of 'sagl' namespace
 
  
#endif /*__ANIM_H_ */
+
    cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
 
+
    cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
// END OF 'ANIM.H' FILE
+
    return 0;
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
"'''VEC.H'''"
+
</div>
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: VEC.H
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#ifndef __VEC_H_
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
#define __VEC_H_
+
'''[[Савельева Ольга]]'''
  
#include <stdlib.h>
+
'''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
#include <math.h>
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
  
// Собственное пространство имен 'sagl'
+
<div class="mw-collapsible-content">
namespace sagl
+
 
 +
<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;
class vec
+
     Vector():x(0), y(0)
  {
+
    {}
  public:
+
    Vector(double x, double y):x(x), y(y)
     // Координаты вектора
+
    {}
double X, Y, Z;
+
    const Vector operator+(const Vector &v) const
      
 
// Конструктор
 
vec( void ) : X(0), Y(0), Z(0)
 
 
     {
 
     {
 +
        return Vector(this -> x + v.x, this -> y + v.y);
 
     }
 
     }
      
+
     const Vector operator-(const Vector &v) const
// Конструктор
+
    {
vec( double A, double B, double C ) : X(A), Y(B), Z(C)
+
        return Vector(this -> x - v.x, this -> y - v.y);
    {
 
 
     }
 
     }
      
+
     const Vector operator*(const double k) const
// Функции получения случайных чисел
 
static double R0( void )
 
 
     {
 
     {
      return rand() / (double)RAND_MAX;
+
        return Vector(this -> x * k, this -> y * k);
 
     }
 
     }
      
+
     const Vector operator*(const int k) const
static double R1( void )
 
 
     {
 
     {
      return 2 * rand() / (double)RAND_MAX - 1;
+
        return Vector(this -> x * k, this -> y * k);
 
     }
 
     }
      
+
     const Vector operator/(const double k) const
// Функции получения случайных векторов
 
static vec Rnd( void )
 
 
     {
 
     {
      return vec(R0(), R0(), R0());
+
        return Vector(this -> x / k, this -> y / k);
 
     }
 
     }
   
+
};
static vec Rnd1( void )
+
 
    {
+
const Vector operator*(const double a, const Vector &v)
      return vec(R1(), R1(), R1());
+
{
    }
+
    return Vector(v.x * a, v.y * a);
+
}
vec operator+( vec V )
+
 
{
+
const Vector operator*(const int k, const Vector &v)
return vec(X + V.X, Y + V.Y, Z + V.Z);
+
{
}
+
     return Vector(v.x * k, v.y * k);
+
}
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_ */
+
double abs(const Vector &v)
 +
{
 +
    return sqrt(v.x * v.x + v.y * v.y);
 +
}
  
// END OF 'VEC.H' FILE
+
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
</syntaxhighlight>
+
{
"'''SAMPLE.H'''"
+
    fputs(description, output);
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    fputs(": ", output);
/* FILENAME: SAMPLE.H
+
    fprintf(output, "%lf", v.x);
* LAST UPDATE: 17.01.2016
+
    fputs(", ", output);
*/
+
    fprintf(output, "%lf\n", v.y);
 +
}
  
#ifndef __SAMPLE_H_
+
Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
#define __SAMPLE_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);
 +
}
  
#include <math.h>
+
Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
 
 
#include "ANIM.H"
 
 
 
// Шар, летящий без сопротивлением воздуха
 
class ball : public sagl::object
 
 
{
 
{
private:
+
    double nowTime = dt;
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
+
    Vector rsb(0, 0);
public:
+
    if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
  // Конструктор
+
        return rsb; //вернитесь в начальную точку
ball( void ) : angle(Pi / 3), v(1)
+
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
  {
+
    Vector r = v * dt;    //вторая точка
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
V.X = 0;
+
    a.y -= g;
V.Y = sin(angle) * v;
+
    v = v + a * dt; //скорость во второй точке
V.Z = cos(angle) * v;
+
    a = -windageLinearCoefficient * v; //ускорение во второй точке
  }
+
    a.y -= g;
+
    while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //пока точка выше 0 или не достигла заданного времени
// Конструктор
+
    {
ball( double angle1, double v1 ) : angle(angle1), v(v1)
+
        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);
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
        rsb = r;    //обновление r(t-dt) and r(t)
V.X = 0;
+
        r = rn;
V.Y = sin(angle) * v;
+
        a = -windageLinearCoefficient * v;  //обновление a(t)
V.Z = cos(angle) * v;
+
        a.y -= g;
}
+
        nowTime += dt;  //обновленное время
 
+
    }
// Отрисовка объекта
+
    return r;
void Render( sagl::anim &Ani )
+
}
  {
+
 
// Вектор ускорения свободного падения
+
Vector calculateForTime(Vector &v, double time)
sagl::vec g = sagl::vec(0, -9.8, 0);
+
{
// Размер комнаты
+
    Vector r;
double Size = 120;
+
    // x = vx/k*(1-e^(-k*t));
 +
    r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
 +
    // y = ((vy+g/k)*(1-e^(-k*t))-g*t)/k;
 +
    r.y = ((v.y + g / windageLinearCoefficient) * (1 - exp(-windageLinearCoefficient * time)) - g * time) / windageLinearCoefficient;
 +
    return r;
 +
}
  
// Изменение вектора скорости
+
Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
V += g * Ani.DeltaTime;
+
{
// Изменение вектора перемещения
+
    if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
P += V * Ani.DeltaTime;
+
        return getCoordinatesWithoutWindage(velocity, angle, time);   //вычисляй будто это 0
 
+
    Vector r;
// Ограничения - стенки
+
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
if (P.X > Size / 4)
+
    if(time >= 0)  //время данное
V.X = -fabs(V.X);
+
    {
if (P.X < -Size / 4)
+
        r = calculateForTime(v, time);
V.X = fabs(V.X);
+
        if(r.y >= 0)    //если объект в воздухе или только приземлился
 
+
            return r;  //затем верните координаты объекта
if (P.Y > Size / 4)
+
        else    //еще
V.Y = -fabs(V.Y);
+
            return getCoordinatesAccurateLinear(velocity, angle);  //верните координаты приземления
if (P.Y < -Size / 4)
+
    }
      V.Y = fabs(V.Y);
+
    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;
 +
    }
 +
}
  
if (P.Z > Size / 4)
+
Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
V.Z = -fabs(V.Z);
+
{
if (P.Z < -Size / 4)
+
    double nowTime = dt;
V.Z = fabs(V.Z);
+
    Vector rsb(0, 0);
+
    if((dt / 2 - time > 0)and(time >= 0))  //если время слишком малое для рсчета
     // Запоминание состояния изменения текущей СК
+
        return rsb; //вернитесь в начальную точку
glPushMatrix();
+
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
+
    Vector r = v * dt;  //вторая точка
// Рисование стенок
+
    Vector a = -abs(v) * v * windageSquareCoefficient; //ускорение в начальной точке
glutWireCube(Size / 2);
+
    a.y -= g;
// Задача перемещения мяча
+
     v = v + a * dt; //скорость во второй точке
glTranslated(P.X, P.Y, P.Z);
+
    a = -abs(v) * v * windageSquareCoefficient; //ускорение во второй точке
    // Цвет мяча
+
    a.y -= g;
glColor3d(0, 1, 0);
+
    while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //когда точка выше нулевой отметки и не достигает заданного времени
// Рисование мяча
+
    {
glutSolidSphere(0.5, 30, 30);
+
        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)
glPopMatrix();
+
        r = rn;
  }
+
        a = -abs(v) * v * windageSquareCoefficient; //новое a(t)
}; // end of 'ball' class
+
        a.y -= g;
 +
        nowTime += dt;  //новое a(t)
 +
    }
 +
    return r;
 +
}
  
// Шар, летящий с сопротивлением воздуха
+
void err(const char *s) //печатает сообщение об ошибке и завершает работу
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 
class ball_air : public sagl::object
 
 
{
 
{
private:
+
    fputs(s, output);
double angle, v, m, n;
+
    exit(1);
public:
+
}
// Конструктор
 
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 
{
 
P = sagl::vec(sagl::r0() + 5, 5, 0);
 
V.X = 0;
 
V.Y = sin(angle) * v;
 
V.Z = cos(angle) * v;
 
}
 
 
// Конструктор
 
ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 
{
 
P = sagl::vec(sagl::r0() + 5, 5, 0);
 
V.X = 0;
 
V.Y = sin(angle) * v;
 
V.Z = cos(angle) * v;
 
}
 
 
// Отрисовка объекта
 
void Render( sagl::anim &Ani )
 
{
 
// Вектор ускорения свободного падения и вектор полного ускорения
 
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 
// Размер комнаты
 
double Size = 120;
 
  
// Изменение вектора ускорения
+
int main(int argc, const char *argv[])
a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
+
{
 +
    double velocity, angle;
 +
    bool needRead = true;
 +
    if(argc==3) //если даны 2 аргумента
 +
    {
 +
        velocity = atof(argv[1]);  //истолкование его как скорости и угла
 +
        angle = atof(argv[2]);
 +
        needRead = false;
 +
    }
 +
    if(needRead)
 +
    {
 +
        puts("Enter initial velocity (m/s)");
 +
        scanf("%lf", &velocity);
 +
    }
 +
    if(velocity < 0)    //проверка, если скорость меньше 0
 +
        err("Initial velocity must be above 0");
 +
    if(needRead)
 +
    {
 +
        puts("Enter initial angle (0-180 degrees)");
 +
        scanf("%lf", &angle);
 +
    }
 +
    if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
 +
        err("Initial angle must be from 0 to 180");
 +
    angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
 +
    output = fopen("Coordinates.txt", "w"); //открытие результативного файла
 +
    //вычисление и печать 4 значений
 +
    printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
 +
    printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
 +
    printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
 +
    printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
 +
    fclose(output); //закрытие файла
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
 +
Скачать можно [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9A%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D1%8B.zip здесь]
  
// Изменение вектора скорости
 
V += a * Ani.DeltaTime;
 
// Изменение вектора перемещения
 
P += V * Ani.DeltaTime;
 
  
// Ограничения - стенки
 
if (P.X > Size / 4)
 
V.X = -fabs(V.X);
 
if (P.X < -Size / 4)
 
V.X = fabs(V.X);
 
  
if (P.Y > Size / 4)
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
V.Y = -fabs(V.Y);
+
'''[[Рубинова Раиса]]'''
if (P.Y < -Size / 4)
+
 
V.Y = fabs(V.Y);
+
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 +
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 
 +
Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут].
 +
 
 +
<div class="mw-collapsible-content">
  
if (P.Z > Size / 4)
+
[[File:Обычный.png]]
V.Z = -fabs(V.Z);
+
[[File:Точный.png]]
if (P.Z < -Size / 4)
+
[[File:Верле2.png]]
V.Z = fabs(V.Z);
+
[[File:Верле1.png]]
+
 
// Запоминание состояния изменения текущей СК
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
glPushMatrix();
+
// Первый случай
+
 
// Рисование стенок
+
#include <iostream>
glutWireCube(Size / 2);
+
#include <math.h>
// Задача перемещения мяча
+
#include <cstdlib>
glTranslated(P.X, P.Y, P.Z);
+
#include <fstream>
// Цвет мяча
+
 
glColor3d(1, 0, 0);
+
/// Программа, анализирующая полет тела;
// Рисование мяча
+
 
glutSolidSphere(0.5, 30, 30);
+
using namespace std;
+
double a,s,H,p1,p2,X,f;    /// Создание переменных, необходимых для работы:
// Восстановление последнего запоминания состояния изменения текущей СК
+
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
glPopMatrix();
+
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
}
+
                                                                                /// H - координата тела по оси Oy;
}; // end of 'ball_air' class
+
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
 +
                                                                                /// X - координата тела по оси Oy;
 +
                                                                                /// f - шаг по времени;
  
// Шар, летящий с сопротивлением воздуха
+
int main()
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
 
class ball_air_2 : public sagl::object
 
 
{
 
{
private:
+
    cout << "Enter speed and angle and step of time" << endl;  /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
double angle, v, m, n;
+
    cin >> s >> a >> f;    /// Считывание данных, введенных пользователем, в переменные;
public:
+
    double t=s*sin(a*3.14159/180.0)/9.8;        /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
// Конструктор
+
    for (double i=f; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    {
{
+
        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;
+
        cerr << X << " ";      /// Вывод на экран значения по оси Ox
}
+
        cerr << H << endl;      /// и по оси Oy;
+
    }
// Конструктор
+
    ofstream out("zap.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
+
    for (double i=0; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
{
+
    {
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
        p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
V.X = 0;
+
        p2=4.9*i*i;            /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
V.Y = sin(angle) * v;
+
        H=double(p1)-p2;        /// Вычисление координаты тела по оси Oy;
V.Z = cos(angle) * v;
+
        X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
}
+
        out << X << " ";        /// Запись в файл значения по оси Ox
+
        out << H << endl;      /// и по оси Oy;
// Отрисовка объекта
+
    }
void Render( sagl::anim &Ani )
+
    out.close();        /// Закрываем файл, с которым работали в течение программы;
{
+
    return 0;          /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
// Вектор ускорения свободного падения и вектор полного ускорения
+
}
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;
 
  
// Ограничения - стенки
+
#include <iostream>
if (P.X > Size / 4)
+
#include <math.h>
V.X = -fabs(V.X);
+
#include <cstdlib>
if (P.X < -Size / 4)
+
#include <fstream>
V.X = fabs(V.X);
 
  
if (P.Y > Size / 4)
+
/// Программа, позволяющая описать полет точки при помощи точного метода;
V.Y = -fabs(V.Y);
 
if (P.Y < -Size / 4)
 
V.Y = fabs(V.Y);
 
  
if (P.Z > Size / 4)
+
using namespace std;
V.Z = -fabs(V.Z);
+
double v,a,st,m;    /// Создание переменных, необходимых для работы:
if (P.Z < -Size / 4)
+
                        /// v - модуль скорости, который задает сам пользователь;
V.Z = fabs(V.Z);
+
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
 +
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
 +
                        /// m - масса тела, задается пользователем;
 +
double *V,*X, *Y, *U;  /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 +
                        /// V - массив, хранящий значения скорости по оси Ox;
 +
                        /// X - массив, хранящий координаты точки по оси Ox;
 +
                        /// Y - массив, хранящий значения скорости по оси Oy;
 +
                        /// U - массив, хранящий координаты точки по оси Oy;
  
// Запоминание состояния изменения текущей СК
+
int main()
glPushMatrix();
 
 
 
// Рисование стенок
 
glutWireCube(Size / 2);
 
// Задача перемещения мяча
 
glTranslated(P.X, P.Y, P.Z);
 
// Цвет мяча
 
glColor3d(0, 1, 1);
 
// Рисование мяча
 
glutSolidSphere(0.5, 30, 30);
 
 
// Восстановление последнего запоминания состояния изменения текущей СК
 
glPopMatrix();
 
}
 
}; // end of 'ball_air_2' class
 
 
 
// Шар, летящий с сопротивлением воздуха
 
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 
class ball_air_3 : public sagl::object
 
 
{
 
{
private:
+
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
double angle, v, m, n;
+
    cin >> v >> a >> st >> m;          /// Считывание данных, введенных пользователей в переменные;
public:
+
    double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
// Конструктор
+
    int n=2*t/st;      /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    //int p=1/st;
{
+
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
V.X = 0;
+
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
V.Y = sin(angle) * v;
+
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
V.Z = cos(angle) * v;
+
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
}
+
    X[0]=0;        /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
+
    U[0]=v*sin(3.14159*a/180.0);        /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
// Конструктор
+
    Y[0]=0;        /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
+
    ofstream out("Res.txt");       /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
{
+
    for (int i=1; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
V.X = 0;
+
    {
V.Y = sin(angle) * v;
+
        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.Z = cos(angle) * v;
+
        X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st));         /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
}
+
                                                                  /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
+
                                                                  /// Движение по горизонтальной оси рассматривается как равномерное прямолинейное движение;
// Отрисовка объекта
+
                                                                  /// Движение по вертикальной оси рассматривается как равноускоренное прямолинейное движение;
void Render( sagl::anim &Ani )
+
        cerr << X[i] << " " << Y[i] << endl;        /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
{
+
        out << X[i] << " " << Y[i] << endl;        /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
// Вектор ускорения свободного падения и вектор полного ускорения
+
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
sagl::vec g = sagl::vec(0, -9.8, 0), a;
+
    }
// Размер комнаты
+
    out.close();        /// Закрываем файл, с которым работали в течение программы;
double Size = 120;
+
    return 0;          /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
  
// Изменение вектора ускорения
 
a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
 
  
// Изменение вектора скорости
+
}
V += a * Ani.DeltaTime;
 
// Изменение вектора перемещения
 
P += V * Ani.DeltaTime;
 
  
// Ограничения - стенки
+
// Третий случай
if (P.X > Size / 4)
 
V.X = -fabs(V.X);
 
if (P.X < -Size / 4)
 
V.X = fabs(V.X);
 
  
if (P.Y > Size / 4)
+
#include <iostream>
V.Y = -fabs(V.Y);
+
#include <math.h>
if (P.Y < -Size / 4)
+
#include <cstdlib>
V.Y = fabs(V.Y);
+
#include <fstream>
  
if (P.Z > Size / 4)
+
/// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
V.Z = -fabs(V.Z);
 
if (P.Z < -Size / 4)
 
V.Z = fabs(V.Z);
 
  
// Запоминание состояния изменения текущей СК
+
using namespace std;
glPushMatrix();
+
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()
glutWireCube(Size / 2);
+
{
// Задача перемещения мяча
+
    cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
glTranslated(P.X, P.Y, P.Z);
+
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователей в переменные;
// Цвет мяча
+
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
glColor3d(1, 0.5, 0);
+
    int n=2*t/st;  /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
// Рисование мяча
+
    //int p=1/st;
glutSolidSphere(0.5, 30, 30);
+
    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;
glPopMatrix();
+
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
}
+
    V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
}; // end of 'ball_air_3' class
+
    X[0]=0;    /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 +
    x=X[0]-V[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 +
    X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st;  /// Вычисление координаты тела по оси Ox в момент времени t=1;
 +
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 +
    Y[0]=0;    /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 +
    y=Y[0]-U[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
 +
    Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st;      /// Вычисление координаты тела по оси Oу в момент времени t=1;
 +
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
 +
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 +
    out << X[1] << " " << Y[1] << endl;    /// Записываем в файл полученные значения координат тела в момент времени t=1;
 +
    int k=1;        /// Создаем целочисленную переменную k=1 для работы в цикле;
 +
    //cerr<<"N "<<n<<"\n";
 +
    for (int i=0; i<n; ++i)     /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 +
                                /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 +
    {
 +
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st;    /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k])*st*st;      /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        U[k]=(Y[k+1]-Y[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        //cerr <<i<<" "<<k<<" "<<
 +
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 +
                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 +
    }
 +
    out.close();    /// Закрываем файл, с которым работали в течение программы;
 +
    return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 +
}
  
#endif /*__SAMPLE_H_ */
+
// Четвертый случай
 
 
// END OF 'SAMPLE.H' FILE
 
</syntaxhighlight>
 
</div>
 
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
 
<br>
 
 
 
'''[[Рубинова Раиса]]'''
 
 
 
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 
#  Полет тела без сопротивления воздуха;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
 
 
Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут].
 
 
 
<div class="mw-collapsible-content">
 
 
 
[[File:Обычный.png]]
 
[[File:Точный.png]]
 
[[File:Верле2.png]]
 
[[File:Верле1.png]]
 
 
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
// Первый случай
 
  
 
#include <iostream>
 
#include <iostream>
Строка 2150: Строка 2061:
 
#include <fstream>
 
#include <fstream>
  
/// Программа, анализирующая полет тела;
+
/// Программа, анализирующая полет тела при помощи метода Верле;
  
 
using namespace std;
 
using namespace std;
double a,s,H,p1,p2,X,f;   /// Создание переменных, необходимых для работы:
+
double v,a,st,m,x,y;       /// Создание переменных, необходимых для работы:
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
+
                            /// v - модуль скорости, который задает сам пользователь;
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
+
                            /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
                                                                                /// H - координата тела по оси Oy;
+
                            /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
+
                            /// m - масса тела, задается пользователем;
                                                                                /// X - координата тела по оси Oy;
+
                            /// x - координата тела по оси Ox в мнимый момент времени t=-1;
                                                                                /// f - шаг по времени;
+
                            /// y - координата тела по оси Oy в мнимый момент времени t=-1;
 +
double *V,*X, *Y, *U;      /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 +
                            /// V - массив, хранящий значения скорости по оси Ox;
 +
                            /// X - массив, хранящий координаты точки по оси Ox;
 +
                            /// Y - массив, хранящий значения скорости по оси Oy;
 +
                            /// U - массив, хранящий координаты точки по оси Oy;
  
 
int main()
 
int main()
 
{
 
{
     cout << "Enter speed and angle and step of time" << endl;   /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
+
     cout << "Enter speed and angle and step of time and weight" << endl;       /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
     cin >> s >> a >> f;     /// Считывание данных, введенных пользователем, в переменные;
+
     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователем, в переменные;
     double t=s*sin(a*3.14159/180.0)/9.8;       /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
+
     double t=(v/9.8)*sin(3.14159*a/180.0);     /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
     for (double i=f; i<(2*t+f); i+=f)      /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
     int n=2*t/st;           /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
     {
+
    //int p=1/st;
        p1=s*sin(a*3.14159/180)*i;     /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
    V = new double [n+2];  /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
         p2=4.9*i*i;         /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
    X = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
        H=double(p1)-p2;   /// Вычисление координаты тела по оси Oy;
+
    Y = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
        X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
     U = new double [n+2];  /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
        cerr << X << " ";      /// Вывод на экран значения по оси Ox
+
    V[0]=v*cos(3.14159*a/180.0);       /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
        cerr << H << endl;     /// и по оси Oy;
+
    X[0]=0;                /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
    }
+
    x=X[0]-V[0]*st;         /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
     ofstream out("zap.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
+
    X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;   /// Вычисление координаты тела по оси Ox в момент времени t=1;
     for (double i=0; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 +
    Y[0]=0;                /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 +
    y=Y[0]-U[0]*st;         /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси ;
 +
    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) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
     {
 
     {
         p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
         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;
         p2=4.9*i*i;             /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
         V[k]=(X[k+1]-X[k-1])/(2*st);       /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
         H=double(p1)-p2;       /// Вычисление координаты тела по оси Oy;
+
         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;
         X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
         U[k]=(Y[k+1]-Y[k-1])/(2*st);   /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
         out << X << " ";       /// Запись в файл значения по оси Ox
+
         //cerr <<i<<" "<<k<<" "<<
         out << H << endl;       /// и по оси Oy;
+
        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();       /// Закрываем файл, с которым работали в течение программы;
+
     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 тут].
 +
 
 +
<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
 +
*/
  
using namespace std;
+
#include "ANIM.H"
double v,a,st,m;    /// Создание переменных, необходимых для работы:
+
#include "SAMPLE.H"
                        /// v - модуль скорости, который задает сам пользователь;
 
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
 
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
 
                        /// m - масса тела, задается пользователем;
 
double *V,*X, *Y, *U;  /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 
                        /// V - массив, хранящий значения скорости по оси Ox;
 
                        /// X - массив, хранящий координаты точки по оси Ox;
 
                        /// Y - массив, хранящий значения скорости по оси Oy;
 
                        /// U - массив, хранящий координаты точки по оси Oy;
 
  
int main()
+
/* Main function */
 +
void main( void )
 
{
 
{
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
// Получение единственного экземпляра класса анимации
    cin >> v >> a >> st >> m;          /// Считывание данных, введенных пользователей в переменные;
+
sagl::anim &My = sagl::anim::Get();
    double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
 
    int n=2*t/st;      /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
// Шар, летящий без сопротивлением воздуха
    //int p=1/st;
+
         for (int i = 0; i < 1; i++)
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
+
                My << new ball(Pi / 6, 10 + i);
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 
    X[0]=0;         /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 
    U[0]=v*sin(3.14159*a/180.0);        /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 
    Y[0]=0;        /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 
    for (int i=1; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
    {
 
        Y[i]=(m/0.001)*(U[0]+9.8*(m/0.001))*(1-exp(((0-0.001)/m)*i*st))-9.8*(m/0.001)*i*st;        /// Вычисление координаты тела в момент времени (i*st) по оси Oy по формуле, выведенной через дифференциальное уравнение точки для вертикальной оси и находящей координату как функцию от времени и координаты тела в предыдущей рассматриваемой нами точке;
 
        X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st));          /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
 
                                                                  /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
 
                                                                  /// Движение по горизонтальной оси рассматривается как равномерное прямолинейное движение;
 
                                                                  /// Движение по вертикальной оси рассматривается как равноускоренное прямолинейное движение;
 
        cerr << X[i] << " " << Y[i] << endl;        /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        out << X[i] << " " << Y[i] << endl;        /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
    }
 
    out.close();        /// Закрываем файл, с которым работали в течение программы;
 
    return 0;          /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
  
 +
// Шар, летящий с сопротивлением воздуха
 +
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
for (int i = 0; i < 1; i++)
 +
My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
 +
 +
// Шар, летящий с сопротивлением воздуха
 +
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
 +
for (int i = 0; i < 1; i++)
 +
My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
  
}
+
// Шар, летящий с сопротивлением воздуха
 
+
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
// Третий случай
+
for (int i = 0; i < 1; i++)
 +
My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
  
#include <iostream>
+
// Запуск главного цикла
#include <math.h>
+
  My.Run();
#include <cstdlib>
+
} // End of 'main' function
#include <fstream>
 
  
/// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
+
// END OF 'T43ANIM.CPP' FILE
 +
</syntaxhighlight>
 +
"'''ANIM.CPP'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: ANIM.CPP
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
using namespace std;
+
#include <stdio.h>
double v,a,st,m,x,y;    /// Создание переменных, необходимых для работы;
+
#include <stdlib.h>
                        /// v - модуль скорости, который задает сам пользователь;
+
#include <time.h>
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
 
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
#include "ANIM.H"
                        /// m - масса тела, задается пользователем;
+
 
                        /// x - координата тела по оси Ox в мнимый момент времени t=-1;
+
// Единственный экземпляр класса
                        /// y - координата тела по оси Oy в мнимый момент времени t=-1;
+
sagl::anim sagl::anim::Instance;
double *V,*X, *Y, *U;  /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 
                        /// V - массив, хранящий значения скорости по оси Ox;
 
                        /// X - массив, хранящий координаты точки по оси Ox;
 
                        /// Y - массив, хранящий значения скорости по оси Oy;
 
                        /// U - массив, хранящий координаты точки по оси Oy;
 
  
int main()
+
/* Reshape function */
 +
// Стандартная функция, вызываемая при изменении размеров окна
 +
void sagl::anim::Reshape( int W, int H )
 
{
 
{
    cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
  // Установка области просмотра - все окно
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователей в переменные;
+
glViewport(0, 0, W, H);
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
   Instance.WinW = W;
    int n=2*t/st;   /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
  Instance.WinH = H;
    //int p=1/st;
+
  double ratio_x = 1, ratio_y = 1;
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
+
  if (W > H)
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
+
     ratio_x = (double)W / H;
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
+
  else
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
+
     ratio_y = (double)H / W;
    V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
+
  double Size = 1, Near = 1, Far = 500;
    X[0]=0;    /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
+
  // Установка системы координат "камеры"
    x=X[0]-V[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
+
glMatrixMode(GL_PROJECTION);
    X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st;  /// Вычисление координаты тела по оси Ox в момент времени t=1;
+
  glLoadIdentity();
     U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
+
  glFrustum(-Size * ratio_x, Size * ratio_x,
    Y[0]=0;    /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
+
            -Size * ratio_y, Size * ratio_y,
    y=Y[0]-U[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
+
            Near, Far);
     Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st;      /// Вычисление координаты тела по оси Oу в момент времени t=1;
+
// Установка "мировой" СК в состояние без преобразований
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
+
  glMatrixMode(GL_MODELVIEW);
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
+
} // End of 'Reshape' function
    out << X[1] << " " << Y[1] << endl;    /// Записываем в файл полученные значения координат тела в момент времени t=1;
 
    int k=1;        /// Создаем целочисленную переменную k=1 для работы в цикле;
 
    //cerr<<"N "<<n<<"\n";
 
    for (int i=0; i<n; ++i)    /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 
                                /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
    {
 
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st;    /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k])*st*st;      /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        U[k]=(Y[k+1]-Y[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        //cerr <<i<<" "<<k<<" "<<
 
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 
                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
    }
 
    out.close();    /// Закрываем файл, с которым работали в течение программы;
 
    return 0;      /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
  
// Четвертый случай
+
/* Timer function */
 +
// Подсчет времени
 +
void sagl::anim::Timer( void )
 +
{
 +
  long Time = clock();
 +
 
 +
  if (IsPause)
 +
    DeltaTime = 0, PauseTime += Time - OldTime;
 +
  else
 +
    DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;
 +
  OldTime = Time;
 +
 
 +
  SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
 +
} /* End of 'Timer' function */
  
#include <iostream>
+
/* Display function */
#include <math.h>
+
// Стандартная функция, вызываемая при перерисовке окна
#include <cstdlib>
+
void sagl::anim::Display( void )
#include <fstream>
+
{
 +
// Запуск времени
 +
Instance.Timer();
 +
// Очищаем цветовой буфер для создания нового изображения
 +
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
/// Программа, анализирующая полет тела при помощи метода Верле;
+
  glLoadIdentity();
 +
  // Позиционирование СК
 +
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
  
using namespace std;
+
// Отрисовка объектов
double v,a,st,m,x,y;        /// Создание переменных, необходимых для работы:
+
  Instance.Render();
                            /// v - модуль скорости, который задает сам пользователь;
+
 
                            /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
  glFinish();
                            /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
// Копируем вторичный буфер в окно
                            /// m - масса тела, задается пользователем;
+
glutSwapBuffers();
                            /// x - координата тела по оси Ox в мнимый момент времени t=-1;
+
// Вызываем функцию обновления кадра
                            /// y - координата тела по оси Oy в мнимый момент времени t=-1;
+
glutPostRedisplay();
double *V,*X, *Y, *U;      /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
} // End of 'Display' function
                            /// V - массив, хранящий значения скорости по оси Ox;
 
                            /// X - массив, хранящий координаты точки по оси Ox;
 
                            /// Y - массив, хранящий значения скорости по оси Oy;
 
                            /// U - массив, хранящий координаты точки по оси Oy;
 
  
int main()
+
/* Keyboard function */
 +
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 +
void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
 
{
 
{
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
// Выход из программы
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователем, в переменные;
+
if (Key == 27)
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
     exit(0);
    int n=2*t/st;          /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
// Открытие программы в полном экране
    //int p=1/st;
+
else if (Key == 'f')
    V = new double [n+2];  /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
+
     glutFullScreen();
    X = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
+
  // Пауза
    Y = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
+
else if (Key == 'p' || Key == 'P')
    U = new double [n+2];  /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
+
     Instance.IsPause = !Instance.IsPause;
     V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
+
} // End of 'Keyboard' function
    X[0]=0;                /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 
    x=X[0]-V[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 
    X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Ox в момент времени t=1;
 
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 
    Y[0]=0;                /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 
    y=Y[0]-U[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
 
     Y[1]=2*Y[0]-y-(0.01/m)*U[0]*U[0]/sin(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Oу в момент времени t=1;
 
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
 
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 
    out << X[1] << " " << Y[1] << endl;        /// Записываем в файл полученные значения координат тела в момент времени t=1;
 
    int k=1;            /// Создаем целочисленную переменную k=1 для работы в цикле;
 
    //cerr<<"N "<<n<<"\n";
 
    for (int i=0; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
     {
 
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*V[k]*st*st;      /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k]*U[k])*st*st;    /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        U[k]=(Y[k+1]-Y[k-1])/(2*st);    /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        //cerr <<i<<" "<<k<<" "<<
 
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
    }
 
    out.close();    /// Закрываем файл, с которым работали в течение программы;
 
    return 0;      /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
  
</syntaxhighlight>
+
sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
</div>
+
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
 
+
{
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
// Инициализации OpenGL и GLUT
'''[[Савельева Ольга]]'''
+
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 +
 
 +
// Задача размеров и позиции окна
 +
glutInitWindowPosition(0, 0);
 +
  glutInitWindowSize(700, 700);
 +
// Создание окна
 +
glutCreateWindow("T06BALL");
  
'''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
+
// Установка функций 'обратного вызова'
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
  glutDisplayFunc(Display);
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
  glutKeyboardFunc(Keyboard);
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
  glutReshapeFunc(Reshape);
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
<div class="mw-collapsible-content">
+
// Установка цвета закраски фона
 +
  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);
 +
}
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
// Деструктор
#include <stdio.h>
+
sagl::anim::~anim( void )
#include <stdlib.h>
+
{
#include <cmath>
+
  // Чистка памяти
 +
for (int i = 0; i < StockSize; i++)
 +
    delete Stock[i];
 +
}
  
using namespace std;
+
/* Render function */
 +
// Отрисовка объектов
 +
void sagl::anim::Render( void )
 +
{
 +
for (int i = 0; i < StockSize; i++)
 +
Stock[i]->Render(*this);
 +
} // End of 'Render' function
  
FILE *output;
+
/* Run function */
 +
// Запуск главного цикла
 +
void sagl::anim::Run( void )
 +
{
 +
// Запуск основного цикла построения
 +
glutMainLoop();
 +
} // End of 'Run' function
  
double e = 0.0000001; //точность
+
// END OF 'ANIM.CPP' FILE
double g = 9.8; //ускорение свободного падения
+
</syntaxhighlight>
double dt = 0.00001;  //шаг по времени
+
"'''ANIM.H'''"
double windageLinearCoefficient = 0.1;
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
double windageSquareCoefficient = 0.00001;
+
/* FILENAME: ANIM.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
struct Vector  //вектор
+
#ifndef __ANIM_H_
{
+
#define __ANIM_H_
    double x, y;
+
 
    Vector():x(0), y(0)
+
#include <stdio.h>
    {}
+
#include <stdlib.h>
    Vector(double x, double y):x(x), y(y)
+
#include <time.h>
    {}
 
    const Vector operator+(const Vector &v) const
 
    {
 
        return Vector(this -> x + v.x, this -> y + v.y);
 
    }
 
    const Vector operator-(const Vector &v) const
 
    {
 
        return Vector(this -> x - v.x, this -> y - v.y);
 
    }
 
    const Vector operator*(const double k) const
 
    {
 
        return Vector(this -> x * k, this -> y * k);
 
    }
 
    const Vector operator*(const int k) const
 
    {
 
        return Vector(this -> x * k, this -> y * k);
 
    }
 
    const Vector operator/(const double k) const
 
    {
 
        return Vector(this -> x / k, this -> y / k);
 
    }
 
};
 
  
const Vector operator*(const double a, const Vector &v)
+
#include <GL\glut.h>
{
 
    return Vector(v.x * a, v.y * a);
 
}
 
  
const Vector operator*(const int k, const Vector &v)
+
#include "VEC.H"
{
 
    return Vector(v.x * k, v.y * k);
 
}
 
  
double abs(const Vector &v)
+
// Константы
{
+
#define Pi 3.14159265358979323846
    return sqrt(v.x * v.x + v.y * v.y);
+
#define E 2.71828182845904523536
}
 
  
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
+
// Собственное пространство имен 'sagl'
 +
namespace sagl
 
{
 
{
    fputs(description, output);
+
  // Объявления класса анимации наперед
    fputs(": ", output);
+
class anim;
    fprintf(output, "%lf", v.x);
+
 
     fputs(", ", output);
+
// Функции получения случайных чисел
    fprintf(output, "%lf\n", v.y);
+
inline double r0( void )
}
+
  {
 
+
     return rand() / (double)RAND_MAX;
Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
+
  }
{
+
  inline double r1( void )
     double fallTime = 2 * velocity * sin(angle) / g;  //расчет времени падения
+
  {
    if((time < 0) or (time > fallTime))
+
     return 2.0 * rand() / RAND_MAX - 1;
        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);
+
class object
}
+
  {
 
+
  public:
Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
+
     // Вектора перемещения и скоростей
{
+
vec P, V, AbsV;
    double nowTime = dt;
+
      
    Vector rsb(0, 0);
+
// Конструктор
    if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
+
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
        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;
+
}
+
// Отрисовка объектов
 +
virtual void Render( anim &Ani )
 +
    {
 +
     } // End of 'Render' function
 +
  }; // end of 'object' class
 +
 
 +
// Класс анимации
 +
class anim
 +
  {
 +
  private:
 +
    // Функции 'обратного вызова'
 +
static void Display( void );
 +
    static void Keyboard( unsigned char Key, int X, int Y );
 +
    static void Reshape( int W, int H );
  
Vector calculateForTime(Vector &v, double time)
+
     // Единственный экземпляр класса
{
+
static anim Instance;
    Vector r;
+
      
     // x = vx/k*(1-e^(-k*t));
+
     // Конструктор
     r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
+
anim( void );
     // 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)
+
// Максимальное количество объектов
{
+
    static const int Max = 100;
     if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
+
    // 'Контейнер' объектов
        return getCoordinatesWithoutWindage(velocity, angle, time);   //вычисляй будто это 0
+
object *Stock[Max];
     Vector r;
+
     // Размер 'контейнера' объектов
     Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
+
int StockSize;
    if(time >= 0)  //время данное
+
   
 +
// Переменные, хранящие время в секундах
 +
     long StartTime, OldTime, PauseTime;
 +
      
 +
// Отрисовка объектов
 +
void Render( void );
 +
 +
// Подсчет времени
 +
void Timer( void );
 +
   public:
 +
    // Добавление объектов в 'контейнер'
 +
anim & operator<<( object *Obj )
 
     {
 
     {
        r = calculateForTime(v, time);
+
      if (StockSize < Max )
         if(r.y >= 0)    //если объект в воздухе или только приземлился
+
         Stock[StockSize++] = Obj;
            return r;   //затем верните координаты объекта
+
      else
        else    //еще
+
        delete Obj;
            return getCoordinatesAccurateLinear(velocity, angle);   //верните координаты приземления
+
     
 +
return *this;
 
     }
 
     }
     else
+
      
     {
+
// Ширина и высота окна
        double timer, timel, timem;
+
     int WinW, WinH;
        timer = v.y / g;
+
 
        timel = 0;
+
// Переменные, хранящие время в секундах
        while(calculateForTime(v, timer).y > 0) //смотрим на некоторые значения времени, которые больше времени посадки
+
    double SyncTime, DeltaTime;
            timer *= 1.5;
+
 
        timem = timel + (timer - timel) / 2;
+
    // Переменная, отвечающая за паузу
        r = calculateForTime(v, timem);
+
bool IsPause;
        while(abs(r.y) > e)    //бинарный поиск времени посадки
+
 
        {
+
    // Деструктор
            if(r.y > 0)
+
~anim( void );
                timel = timem;
+
   
            else
+
// Запуск главного цикла
                timer = timem;
+
void Run( void );
            timem = timel + (timer - timel) / 2;
+
   
            r = calculateForTime(v, timem);
+
    // Метод, возвращающий переменную - единственный экземпляр данного типа
        }
+
static anim & Get( void )
        return r;
+
    {
 +
      return Instance;
 
     }
 
     }
}
+
  }; // end of 'anim' class
 +
} // end of 'sagl' namespace
  
Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
+
#endif /*__ANIM_H_ */
{
 
    double nowTime = dt;
 
    Vector rsb(0, 0);
 
    if((dt / 2 - time > 0)and(time >= 0))  //если время слишком малое для рсчета
 
        return rsb; //вернитесь в начальную точку
 
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
 
    Vector r = v * dt;  //вторая точка
 
    Vector a = -abs(v) * v * windageSquareCoefficient;  //ускорение в начальной точке
 
    a.y -= g;
 
    v = v + a * dt; //скорость во второй точке
 
    a = -abs(v) * v * windageSquareCoefficient; //ускорение во второй точке
 
    a.y -= g;
 
    while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //когда точка выше нулевой отметки и не достигает заданного времени
 
    {
 
        Vector rn = 2 * r - rsb + a * dt * dt;  // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
 
        v = (rn - rsb) / (2 * dt);  // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
 
        rsb = r;    //updating r(t-dt) and r(t)
 
        r = rn;
 
        a = -abs(v) * v * windageSquareCoefficient; //новое a(t)
 
        a.y -= g;
 
        nowTime += dt;  //новое a(t)
 
    }
 
    return r;
 
}
 
  
void err(const char *s) //печатает сообщение об ошибке и завершает работу
+
// END OF 'ANIM.H' FILE
{
+
</syntaxhighlight>
    fputs(s, output);
+
"'''VEC.H'''"
    exit(1);
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
}
+
/* FILENAME: VEC.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
int main(int argc, const char *argv[])
+
#ifndef __VEC_H_
 +
#define __VEC_H_
 +
 
 +
#include <stdlib.h>
 +
#include <math.h>
 +
 
 +
// Собственное пространство имен 'sagl'
 +
namespace sagl
 
{
 
{
     double velocity, angle;
+
  // Класс векторов
     bool needRead = true;
+
class vec
    if(argc==3) //если даны 2 аргумента
+
  {
 +
  public:
 +
     // Координаты вектора
 +
double X, Y, Z;
 +
      
 +
// Конструктор
 +
vec( void ) : X(0), Y(0), Z(0)
 
     {
 
     {
        velocity = atof(argv[1]);  //истолкование его как скорости и угла
 
        angle = atof(argv[2]);
 
        needRead = false;
 
 
     }
 
     }
     if(needRead)
+
      
 +
// Конструктор
 +
vec( double A, double B, double C ) : X(A), Y(B), Z(C)
 
     {
 
     {
        puts("Enter initial velocity (m/s)");
 
        scanf("%lf", &velocity);
 
 
     }
 
     }
     if(velocity < 0)    //проверка, если скорость меньше 0
+
      
        err("Initial velocity must be above 0");
+
// Функции получения случайных чисел
    if(needRead)
+
static double R0( void )
 
     {
 
     {
        puts("Enter initial angle (0-180 degrees)");
+
      return rand() / (double)RAND_MAX;
        scanf("%lf", &angle);
+
    }
 +
   
 +
static double R1( void )
 +
    {
 +
      return 2 * rand() / (double)RAND_MAX - 1;
 +
    }
 +
   
 +
// Функции получения случайных векторов
 +
static vec Rnd( void )
 +
    {
 +
      return vec(R0(), R0(), R0());
 +
    }
 +
   
 +
static vec Rnd1( void )
 +
    {
 +
      return vec(R1(), R1(), R1());
 
     }
 
     }
    if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
+
        err("Initial angle must be from 0 to 180");
+
vec operator+( vec V )
    angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
+
{
    output = fopen("Coordinates.txt", "w"); //открытие результативного файла
+
return vec(X + V.X, Y + V.Y, Z + V.Z);
    //вычисление и печать 4 значений
+
}
    printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
+
     printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
+
vec operator*( double t )
     printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
+
     {
    printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
+
      return vec(X * t, Y * t, Z * t);
     fclose(output); //закрытие файла
+
     }
    return 0;
+
   
}
+
vec & operator+=( const vec &V )
</syntaxhighlight>
+
    {
</div>
+
      X += V.X;
Скачать можно [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 здесь]
+
      Y += V.Y;
 
+
      Z += V.Z;
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
     
 
+
return *this;
 +
     }
 +
 +
// Длина вектора
 +
double operator!(void) const
 +
{
 +
return sqrt(X * X + Y * Y + Z * Z);
 +
} /* end of 'operator!' function */
 +
  }; // end of 'vec' class
 +
} // end of 'sagl' namespace
  
'''[[Сенников Иван]]'''
+
#endif /*__VEC_H_ */
  
'''Суть программы:'''Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.
+
// END OF 'VEC.H' FILE
 +
</syntaxhighlight>
 +
"'''SAMPLE.H'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: SAMPLE.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
'''Идея:''' Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.
+
#ifndef __SAMPLE_H_
 +
#define __SAMPLE_H_
  
'''Инструкция:''' Результаты программы будут записаны в соответствующий файл (подробности смотри в самой программе). Пользователю будет предоставлена возможность ввести начальную скорость и угол, под которым и бросают тело.
+
#include <math.h>
  
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Throws_v2.0.zip здесь].
+
#include "ANIM.H"
  
</div>
+
// Шар, летящий без сопротивлением воздуха
 +
class ball : public sagl::object
 +
{
 +
private:
 +
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
 +
public:
 +
  // Конструктор
 +
ball( void ) : angle(Pi / 3), v(1)
 +
  {
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
  }
 +
 +
// Конструктор
 +
ball( double angle1, double v1 ) : angle(angle1), v(v1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 
 +
// Отрисовка объекта
 +
void Render( sagl::anim &Ani )
 +
  {
 +
// Вектор ускорения свободного падения
 +
sagl::vec g = sagl::vec(0, -9.8, 0);
 +
// Размер комнаты
 +
double Size = 120;
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
// Изменение вектора скорости
'''[[Степанянц Степан]]'''
+
V += g * Ani.DeltaTime;
 
+
// Изменение вектора перемещения
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
P += V * Ani.DeltaTime;
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
+
// Ограничения - стенки
 +
if (P.X > Size / 4)
 +
V.X = -fabs(V.X);
 +
if (P.X < -Size / 4)
 +
V.X = fabs(V.X);
  
<div class="mw-collapsible-content">
+
if (P.Y > Size / 4)
[[File:graph239.png]]
+
V.Y = -fabs(V.Y);
 +
if (P.Y < -Size / 4)
 +
      V.Y = fabs(V.Y);
  
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
+
if (P.Z > Size / 4)
 
+
V.Z = -fabs(V.Z);
 
+
if (P.Z < -Size / 4)
 
+
V.Z = fabs(V.Z);
Файл "'''main.cpp'''"
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    // Запоминание состояния изменения текущей СК
#include <iostream>
+
glPushMatrix();
#include <locale.h>
+
#include <math.h>
+
// Рисование стенок
#include <fstream>
+
glutWireCube(Size / 2);
#include<iomanip>
+
// Задача перемещения мяча
#include <cmath>
+
glTranslated(P.X, P.Y, P.Z);
using namespace std;
+
    // Цвет мяча
main ()
+
glColor3d(0, 1, 0);
 +
// Рисование мяча
 +
glutSolidSphere(0.5, 30, 30);
 +
   
 +
// Восстановление последнего запоминания состояния изменения текущей СК
 +
glPopMatrix();
 +
  }
 +
}; // end of 'ball' class
 +
 
 +
// Шар, летящий с сопротивлением воздуха
 +
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
class ball_air : public sagl::object
 
{
 
{
    ofstream F;                                                                    //a1-угол в градусах,dt-шаг,r-сопротивление воздуха
+
private:
int u0=50;
+
double angle, v, m, n;
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 - проэкции скорости на оси х и у.
+
public:
a=a1*M_PI/180; //Градусы в радианы
+
// Конструктор
t=0;
+
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
{
                                        //Движение без сопротивления воздуха
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
F.open("C:\\1.txt",ios::out);
+
V.X = 0;
while(y>=0)
+
V.Y = sin(angle) * v;
{
+
V.Z = cos(angle) * v;
    x=x0+u0*cos(M_PI/6)*t;
+
}
    y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t; //Расчитываем координаты в каждой точке через шаг
+
  F<<x<<" "<<y<<endl;
+
// Конструктор
  t=t+dt;
+
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;
F.close();
+
V.Y = sin(angle) * v;
                                        //Точное решение для линейной зависимости
+
V.Z = cos(angle) * v;
F.open("C:\\2.txt",ios::out);
+
}
y=y0;
+
x=x0;
+
// Отрисовка объекта
t=0;                                                                            //Расчитываем координаты в каждой точке через шаг
+
void Render( sagl::anim &Ani )
while(y>=0)
+
{
{
+
// Вектор ускорения свободного падения и вектор полного ускорения
        ux = u0 * cos(a);
+
sagl::vec g = sagl::vec(0, -9.8, 0), a;
        uy = u0 * sin(a);
+
// Размер комнаты
        x = x0+ (m * ux / r)* (1 - exp(-1 * r * t / m));                      //подстановка формул
+
double Size = 120;
        y = y0+(m/r)*((uy + g * m / r)*(1 - exp(-1 * r * t / m)) - g * t);
+
 
        t = t + dt;
+
// Изменение вектора ускорения
+
a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
      F << x << ' ' << y << endl;
+
 
+
// Изменение вектора скорости
+
V += a * Ani.DeltaTime;
+
// Изменение вектора перемещения
}
+
P += V * Ani.DeltaTime;
  F.close();
+
 
                                                        //метод Верле 1
+
// Ограничения - стенки
ypr = y0 - u0*sin(a)*dt;
+
if (P.X > Size / 4)
yt=ypr;
+
V.X = -fabs(V.X);
    xpr = x0 - u0*cos(a)*dt;
+
if (P.X < -Size / 4)
    x = x0;                          //Начальные условия
+
V.X = fabs(V.X);
    y = y0;
+
 
    u = u0;
+
if (P.Y > Size / 4)
    ux = u0 * cos(a);
+
V.Y = -fabs(V.Y);
    uy = u0 * sin(a);                       
+
if (P.Y < -Size / 4)
F.open("C:\\3.txt",ios::out);
+
V.Y = fabs(V.Y);
 
    while (y >= y0)
 
    {
 
        xsl = 2 * x - xpr - (r / m) * u * ux * (dt * dt);
 
        ux = ( xsl - xpr )/ (2 * dt);
 
        ysl = 2 * y - ypr - (g + (r / m) * u * uy) * (dt * dt);      //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
 
        uy =  (ysl - ypr)/ (2 * dt);
 
        u = sqrt(uy*uy + ux*ux );
 
        F << x << ' ' << y << endl;
 
 
        xpr = x;
 
        x = xsl;
 
        ypr = y;
 
        y = ysl;
 
    }
 
    F.close();
 
                                                      //Метод Верле 2
 
    ypr = y0 - u0*sin(a)*dt;
 
yt=ypr;
 
    xpr = x0 - u0*cos(a)*dt;
 
    x = x0;                                                                            //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
 
    y = y0;
 
    u = u0;
 
    ux = u0 * cos(a);                            
 
    uy = u0 * sin(a);
 
F.open("C:\\4.txt",ios::out);
 
 
    while (y >= y0)
 
    {
 
        xsl = 2 * x - xpr - (r / m) * ux * (dt * dt);
 
        ux = ( xsl - xpr )/ (2 * dt);
 
        ysl = 2 * y - ypr - (g + (r / m) * uy) * (dt * dt);
 
        uy =  (ysl - ypr)/ (2 * dt);
 
        u = sqrt(uy*uy + ux*ux );
 
        F << x << ' ' << y << endl;
 
 
        xpr = x;
 
        x = xsl;
 
        ypr = y;
 
        y = ysl;
 
    }
 
    F.close();
 
 
 
return 0;
 
 
 
}
 
  
</syntaxhighlight>
+
if (P.Z > Size / 4)
</div>
+
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();
'''Описание программы''':
+
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
+
// Рисование стенок
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
+
glutWireCube(Size / 2);
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении          воздуха от скорости
+
// Задача перемещения мяча
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
+
glTranslated(P.X, P.Y, P.Z);
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
+
// Цвет мяча
Скачать можно  [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 тут].
+
glColor3d(1, 0, 0);
<div class="mw-collapsible-content">
+
// Рисование мяча
[[File:Снимок.PNG]]
+
glutSolidSphere(0.5, 30, 30);
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
+
Файл "'''main.cpp'''"
+
// Восстановление последнего запоминания состояния изменения текущей СК
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
glPopMatrix();
#include <iostream>
+
}
#include <fstream>
+
}; // end of 'ball_air' class
#include <math.h>
 
#include <cmath>
 
using namespace std;
 
int o;
 
double v,a,m,k;
 
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
 
  
 
+
// Шар, летящий с сопротивлением воздуха
 
+
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
int rez_1(double v, double a)
+
class ball_air_2 : public sagl::object
 
{
 
{
    fout<<"---------------Первый режим-------------------------"<<endl;
+
private:
    fout<<" T=0 x=0 y=0";
+
double angle, v, m, n;
    fout<<endl;
+
public:
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
+
// Конструктор
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
+
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
    V0y=v*sin(a/180*M_PI);
+
{
    Ty=2*V0y/g;//время полета
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
+
V.X = 0;
    {
+
V.Y = sin(angle) * v;
        x=x+V0x*t;               //ф-лы для рассчета x и y в данный момент времени
+
V.Z = cos(angle) * v;
        y=y+V0y*t-g*pow(t,2)/2;
+
}
 
+
        if (y<0) //если y<0
+
// Конструктор
            {
+
ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
+
{
                x=x+V0x*t1;//используя это время находим координату по х
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
                fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
+
V.X = 0;
                break;
+
V.Y = sin(angle) * v;
            }
+
V.Z = cos(angle) * v;
            else
+
}
                {
+
                    V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
+
// Отрисовка объекта
                    fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
+
void Render( sagl::anim &Ani )
                    T=T+t;//увел время на шаг
+
{
                }
+
// Вектор ускорения свободного падения и вектор полного ускорения
    }
+
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 +
// Размер комнаты
 +
double Size = 120;
  
 +
// Изменение вектора скорости
 +
V.Z = V.Z * exp(-n / m * Ani.DeltaTime);
 +
V.Y = (V.Y - g.Y * m / n) * exp(-n / m * Ani.DeltaTime) + g.Y * m / n;
 +
// Изменение вектора перемещения
 +
P += V * Ani.DeltaTime;
  
}
+
// Ограничения - стенки
 +
if (P.X > Size / 4)
 +
V.X = -fabs(V.X);
 +
if (P.X < -Size / 4)
 +
V.X = fabs(V.X);
  
 +
if (P.Y > Size / 4)
 +
V.Y = -fabs(V.Y);
 +
if (P.Y < -Size / 4)
 +
V.Y = fabs(V.Y);
  
int rez_2(double v, double a, double k, double m)
+
if (P.Z > Size / 4)
{
+
V.Z = -fabs(V.Z);
    fout<<"---------------Второй режим работы-------------------------"<<endl;
+
if (P.Z < -Size / 4)
    fout<<" T=0 x=0 y=0";
+
V.Z = fabs(V.Z);
    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;
 
    }
 
  
 +
// Запоминание состояния изменения текущей СК
 +
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 rez_3(double v, double a, double k, double m)
+
class ball_air_3 : public sagl::object
 
{
 
{
  fout<<"---------------Третий режим работы-------------------------"<<endl;
+
private:
    fout<<" T=0 x=0 y=0";
+
double angle, v, m, n;
    fout<<endl;
+
public:
    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,
+
ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
    y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
+
{
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Конструктор
 +
ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Отрисовка объекта
 +
void Render( sagl::anim &Ani )
 +
{
 +
// Вектор ускорения свободного падения и вектор полного ускорения
 +
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 +
// Размер комнаты
 +
double Size = 120;
  
 +
// Изменение вектора ускорения
 +
a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
  
    x3=2*x2-x1-k/m*Vxn*pow(t,2);  //координаты в момент времени T
+
// Изменение вектора скорости
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
+
V += a * Ani.DeltaTime;
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
+
// Изменение вектора перемещения
    Vyn=(y3-y1)/(2.0*t);
+
P += V * Ani.DeltaTime;
    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)
+
// Ограничения - стенки
        {
+
if (P.X > Size / 4)
            t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
+
V.X = -fabs(V.X);
            x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
+
if (P.X < -Size / 4)
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
+
V.X = fabs(V.X);
        }
 
  
        T=T+t;
+
if (P.Y > Size / 4)
        x1=x2;
+
V.Y = -fabs(V.Y);
        y1=y2;
+
if (P.Y < -Size / 4)
        x2=x3;
+
V.Y = fabs(V.Y);
        y2=y3;
 
  
    }
+
if (P.Z > Size / 4)
 +
V.Z = -fabs(V.Z);
 +
if (P.Z < -Size / 4)
 +
V.Z = fabs(V.Z);
  
}
+
// Запоминание состояния изменения текущей СК
 +
glPushMatrix();
  
 +
// Рисование стенок
 +
glutWireCube(Size / 2);
 +
// Задача перемещения мяча
 +
glTranslated(P.X, P.Y, P.Z);
 +
// Цвет мяча
 +
glColor3d(1, 0.5, 0);
 +
// Рисование мяча
 +
glutSolidSphere(0.5, 30, 30);
 +
 +
// Восстановление последнего запоминания состояния изменения текущей СК
 +
glPopMatrix();
 +
}
 +
}; // end of 'ball_air_3' class
  
int rez_4(double v, double a, double k, double m)
+
#endif /*__SAMPLE_H_ */
{
 
  fout<<"---------------Четвертый режим работы-------------------------"<<endl;
 
    fout<<" T=0 x=0 y=0";
 
    fout<<endl;
 
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
 
    x3=0,x1=0, x2=x1+Vxn*t, y3=0, y1=0,
 
    y2=y1+Vyn*t, g=9.8, t1, T=0.1, V=v;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
 
  
 +
// END OF 'SAMPLE.H' FILE
 +
</syntaxhighlight>
 +
</div>
 +
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
 +
<br>
  
    x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
 
    y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
 
    Vxn=(x3-x1)/(2.0*t);
 
    Vyn=(y3-y1)/(2.0*t);
 
    V=sqrt(pow(Vxn,2)+pow(Vyn,2.0));
 
    x1=x2;
 
    y1=y2;
 
    x2=x3;
 
    y2=y3;
 
    while (y2>0)
 
    {
 
        x3=2.0*x2-x1-(k/m)*Vxn*V*pow(t,2);
 
        y3=2.0*y2-y1-(g+(k/m)*Vyn*V)*pow(t,2);
 
        Vxn=(x3-x1)/(2.0*t);
 
        Vyn=(y3-y1)/(2.0*t);
 
        V=sqrt(pow(Vxn,2)+pow(Vyn,2));
 
        fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
 
 
        if (y3<0)
 
        {
 
            t1=sqrt(abs((-y1+2.0*y2)/(g+(k/m)*Vyn*V)));
 
            x3=2.0*x2-x1-(k/m)*Vxn*V*pow((t+t1),2);
 
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 
        }
 
  
 +
'''[[Абрамов Игорь]]'''
  
        T=T+t;
+
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
        x1=x2;
 
        y1=y2;
 
        x2=x3;
 
        y2=y3;
 
  
    }
+
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
  
}
+
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
  
 +
</div>
  
int main()
+
'''[[Лобанов Илья]]'''
{
+
 
 +
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
  
setlocale(LC_ALL, "rus");
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
cout<<"Введите скорость тела и угол"<<endl;
+
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
cin>>v>>a;
+
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
while (1>0){
 
cout<<"Выберите режим работы программы:"<<endl;
 
cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
 
cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
 
cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
 
cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
 
cout<<"5 - Выйти";
 
cin>>o;
 
  
if (o==1)
+
'''Краткая инструкция''':
    rez_1(v,a);
 
if (o==2)
 
    {
 
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 
    cin>>m>>k;
 
    rez_2(v,a,k,m);
 
    }
 
  
if (o==3)
+
В окне консоли пользователю предлагается вывести следующие значения: начальную скорость , угол и шаг.
    {
+
После этого полученные в результате работы программы данные выводятся в файл.
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 
    cin>>m>>k;
 
    rez_3(v,a,k,m);
 
    }
 
  if (o==4)
 
    {
 
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 
    cin>>m>>k;
 
    rez_4(v,a,k,m);
 
    }
 
  if (o==5)
 
        break;
 
  
            }
+
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
}
+
[[http://tm.spbstu.ru/File:phys.rar тут]]
  
 
</syntaxhighlight>
 
 
</div>
 
</div>
  
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''[[Тимошенко Валентина]]'''
 
  
'''Описание программы''': при запуске пользователь вводит шаг функции, угол, под которым бросают тело, массу тела, сопротивление воздуха и скорость.
+
</div>
Программа записывает в четыре файла результаты вычисления:
 
#Координаты, рассчитанные по формуле для движения без сопротивления воздуха;
 
#Координаты, рассчитанные по формуле для движения с учетом сопротивления воздуха;
 
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивления воздуха от скорости.
 
#Координаты, полученные методом Верле при линейной зависимости силы сопротивления воздуха от скорости;
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:motion.zip тут.]
+
'''[[Капитанюк Светлана]]'''
  
<div class="mw-collapsible-content">
+
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
  
'''Визуализированный результат работы программы'''
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
[[File:Grafics.png]]
+
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
+
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
</div>
  
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
+
</div>
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
 
#include <math.h>
 
#include<stdlib.h>
 
using namespace std;
 
  
int main()
+
'''[[Бальцер Анастасия]]'''
{
 
    double a, step, Pi, g, Vo, m, r;
 
    ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
 
  
    double x, y, x_0, y_0, x0, y0, Vx, Vy;
+
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
    ///переменные для движения точки без учёта сопротивления и с его учётом
 
    ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
 
    ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
 
    ///Vx - скорость тела по оси Ох, Vу - скорость тела по оси Оу
 
    ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
 
  
    double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
    ///переменные для 1го варианта метода Верле
+
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
    ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
+
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
    ///у1 - координата тела по оси Оу на (n-1) шаге, у2 - координата тела по оси Оу на (n) шаге, у3 - координата тела по оси Оу на (n+1) шаге
+
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
    ///Vx0 - начальная скорость тела по оси Ох, Vy0 - начальная скорость тела по оси Оу
 
    ///Vxn - скорость тела в данный момент времени по оси Ох, Vyn - скорость тела в данный момент времени по оси Оу
 
  
    double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
+
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
    ///переменные для 2го варианта метода Верле
 
    ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
 
    ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
 
    ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
 
  
    g=10; ///значение ускорения свободного падения
+
</div>
    Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
+
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Демченко Артём]]'''
  
    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; ///вывод значение угла на экран
+
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
    a=(Pi*a)/180.0;
 
    cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
 
    cin >> m; ///вывод величины массы на экран
 
  
    do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
 
    {
 
        cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
 
        cin >> r; ///вывод значения сопротивления на экран
 
    }
 
    while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
 
  
    cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
+
<div class="mw-collapsible-content">
    cin >> Vo; ///вывод значения скорости на экран
 
  
    ///для движения без учёта сопротивления
 
    x0=0; ///обнуление переменных
 
    y0=0;
 
    x=0;
 
    y=0;
 
  
    ///для движения с учётом сопротивления
 
    x_0=0; ///обнуление переменных
 
    y_0=0;
 
  
    ///для 1го варианта метода Верле
+
'''Визуализированный результат работы программы'''
  
    Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
+
[[:File:Throws.png]]
    Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
 
  
    x2=0; ///обнуление переменных
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    y2=0;
 
    x3=0;
 
    y3=0;
 
  
    y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
+
#include <iostream>
    x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
+
#include <math.h>
 +
#include <iomanip>
 +
#include <fstream>
 +
#include <conio.h>
 +
#include <stdio.h>
  
    ///для 2го варианта метода Верле
 
  
    x_2=0; ///обнуление переменных
+
using namespace std;
    y_2=0;
 
    x_3=0;
 
    y_3=0;
 
  
    Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
+
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
 
  
    y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
+
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
     x_1=-Vo*cos(a)*step;   ///расчет начального значения координаты на (п-1) шаге по оси Ох
+
{
 +
     FILE *Coord;
 +
  Coord = fopen ("Throws Without Resistance.txt", "w");
 +
    double X = 0, Y = 0; // Координаты начала
  
    ofstream out("For method without resistance.txt");
+
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
    ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
+
    {
  
    for (int i=0; y>=0; ++i) ///цикл для подсчета координат при движении тела без учёта сопротивления
+
      X = Vo*t*cos(alpha);
    {
+
      Y = Vo*t*sin(alpha) - (g*t*t)*0.5;
        x=Vo*step*i*cos(a); ///расчет координаты тела по оси х
+
      t+= dt;
        y=Vo*sin(a)*i*step-(g*i*step*i*step)*0.5; ///расчет координаты тела по оси y
+
    if (Y > Yo )
 +
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 +
    else
 +
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
 +
    }
  
        out << x << "    " << y <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
+
}
    }
 
    out.close();
 
  
     ofstream out1 ("For method with resistance.txt");
+
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;
  
     for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
+
     while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
    {
+
    {
        Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
 
        Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
 
        x_0=x0+(m/r)*Vx*(1.0 - exp((-r*i*step)/m)); ///расчет координаты тела по оси х
 
        y_0=y0+(m/r)*(Vy+g*(m/r))*(1.0 - exp((-r*i*step)/m))-g*i*step*(m/r); ///расчет координаты тела по оси y
 
  
         out1 << x_0 << "   " << y_0 <<'\n'; ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
+
      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;
    out1.close();
+
      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); // используется аналогично прошлому пункту
 +
      }
 +
}
  
     ofstream out2 ("For method Verle 1.txt");
+
int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
    ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
+
{                                                                                                    // для Квадратичной зависимости сопротивления от скорости
 +
     FILE *Coord;
 +
  Coord = fopen ("VerleSq.txt", "w");
  
     for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
+
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
    {
+
                                                                  // Xop, Yop - вспомогательные координаты для (-1)-го шага
        x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
 
        y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
 
        Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
 
        Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
 
        Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
 
  
        x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
+
    Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
        x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
+
    Xop = Xo - Vo*cos(alpha)*dt;
        y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
+
    X = Xo;
        y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
+
    Y = Yo;
 
+
    Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
        out2 << x3 << "  " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
+
    Vx = (1.0/(2.0*dt))*(Xnext - Xop);
     }
+
    Ynext = 2.0*Y - Yop - (g +(R/m)*Vo*Vo*sin((alpha)))*(dt*dt);
     out2.close();
+
    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;
  
    ofstream out3 ("For method Verle 2.txt");
 
    ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
 
  
     for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
+
     while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
 
     {
 
     {
        x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
+
    Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
        y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
+
    Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
        Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
+
    Ynext = 2.0*Y - Yprev - (g +(R/m)*V*Vy)*(dt*dt);
        Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
+
    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
  
        x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
+
      fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
        x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
 
        y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
 
        y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
 
 
 
        out3 << x_3 << "   " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
 
  
 +
    Xprev = X;
 +
    X = Xnext;
 +
    Yprev = Y;
 +
    Y = Ynext;
 
     }
 
     }
    out3.close();
 
  
    cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
 
    cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
 
    return 0;
 
 
}
 
}
</syntaxhighlight>
+
int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
</div>
+
{                                                                                                  // для линейной зависимости сопротивления от скорости
 +
    FILE *Coord;
 +
  Coord = fopen ("VerleL.txt", "w");
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    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)));
  
<div class="mw-collapsible-content">
+
    fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
  
[[File:Methods.rar|Скачать архив]]
+
    Xprev = X;
 
+
    X = Xnext;
[[File:1.png]]
+
    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;
 +
    }
 +
 
 +
}
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
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
  
</syntaxhighlight>
+
  cout << "Enter start speed:\n";
 +
  cin >> Vo; // Вводим с клавиатуры начальную скорость
 +
  cout << "Enter angle in grades ( from 0 to 180 ):\n";
 +
  cin >> alpha; // Вводим с клавиатуры угол броска в градусах
 +
  alpha = alpha*Pi / 180; // переводим угол броска из градусов в радианы
 +
  cout << "Enter mass:\n";
 +
  cin >> m; // Вводим с клавиатуры массу
 +
  cout << "Enter precision:\n";
 +
  cin >> dt; // Вводим с клавиатуры шаг по времени
 +
  cout << "Enter resistance:\n";
 +
  cin >> R; // Вводим сопротивление воздуха
 +
  cout << "Press 1 to draw graph without resistance\n\n"
 +
          "Press 2 to draw graph in Exact form\n\n"
 +
          "Press 3 to draw graph in VerleSq form\n\n"
 +
          "Press 4 to draw graph in VerleL form\n\n"
 +
          "Press 5 to draw all graphs at the same time\n\n"
 +
          "Press 0 to quit\n\n";
 +
  cin >> i;
 +
  cout << "\nPress any button\n";
 +
 
 +
 
 +
    FILE *Gnu;
 +
    Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
 +
 
 +
switch ( i )
 +
{
 +
case 1:
 +
    {
 +
    WoutR(alpha,dt,t,Yo,Vo);
 +
    fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
 +
    break;
 +
    }
 +
case 2:
 +
    {
 +
    ExactForm(alpha,dt,t,Yo,Vo,R,m);
 +
    fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
 +
    break;
 +
    }
 +
case 3:
 +
    {
 +
    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 +
    fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
 +
    break;
 +
    }
 +
case 4:
 +
    {
 +
    VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
 +
    fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
 +
    break;
 +
    }
 +
case 5:
 +
    {
 +
  WoutR(alpha,dt,t,Yo,Vo);
 +
  ExactForm(alpha,dt,t,Yo,Vo,R,m);
 +
  VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 +
  VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
 +
  fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l, \"ExactForm.txt\" using 1:2 w l, \"VerleSq.txt\" using 1:2 w l, \"VerleL.txt\" using 1:2 w l"); // записываем в Throws.gp названия четырех файлов
 +
  break;
 +
    }                                                  // с координатами таким образом, чтобы программа gnuplot смогла их увидеть и прочесть
 +
case 0:
 +
    break;
 +
default:
 +
    break;
 +
}
 +
    return 0;
 +
}
 +
 
 +
</syntaxhighlight>
 
</div>
 
</div>
 +
 +
'''[[Гильманов Илья]]'''
 +
 +
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 +
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 +
Скачать можно [[http://mech.spbstu.ru/File:Qwertyui.rar тут]]
 +
 +
'''[[Киселёв Лев]]'''
 +
 +
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
 +
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 +
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
 +
 +
'''[[Ляжков Сергей]]'''
 +
 +
'''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
 +
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
 +
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
 +
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
Вам запрещено изменять защиту статьи. Edit Создать редактором

Обратите внимание, что все добавления и изменения текста статьи рассматриваются как выпущенные на условиях лицензии Public Domain (см. Department of Theoretical and Applied Mechanics:Авторские права). Если вы не хотите, чтобы ваши тексты свободно распространялись и редактировались любым желающим, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого.
НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ МАТЕРИАЛЫ, ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ!

To protect the wiki against automated edit spam, we kindly ask you to solve the following CAPTCHA:

Отменить | Справка по редактированию  (в новом окне)