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

Материал из Department of Theoretical and Applied Mechanics
Перейти к: навигация, поиск
м
 
(не показаны 2 промежуточные версии этого же участника)
Строка 1: Строка 1:
 +
<div>
 +
'''[[Абрамов Игорь]]'''
 +
 +
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
 +
 +
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
 +
 +
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
 +
 +
</div>
 +
 +
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
'''[[Андреева Полина]]'''  
 
'''[[Андреева Полина]]'''  
Строка 121: Строка 133:
 
</div>
 
</div>
  
 +
<div>
 +
 +
'''[[Бальцер Анастасия]]'''
 +
 +
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
 +
 +
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
 +
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
 +
 +
</div>
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
Строка 274: Строка 300:
 
</div>
 
</div>
  
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Васильева Анастасия]]'''
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
'''Описание программы''': пользователь вводит начальную скорость полета, угол падения и шаг, с которым будут рассчитаны точки.
'''[[Лебедев Станислав]]'''  
 
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
Программа записывает в один файл результаты вычисления:
 
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
# Координаты, полученные при численном интегрировании - метод Эйлера;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Шарик.rar тут].
+
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
 +
 
  
 
<div class="mw-collapsible-content">
 
<div class="mw-collapsible-content">
 
[[File:1.png]]
 
  
  
 
'''Визуализированный результат работы программы'''
 
'''Визуализированный результат работы программы'''
[[File:graph.png]]
+
[[File:graphick.png]]
  
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
# "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
 +
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
 +
# "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
  
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 
  
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
Файл "'''main.cpp'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
 
#include <iostream>
 
#include <iostream>
 +
#include <fstream>
 +
#include <iomanip>
 +
#include <time.h>
 +
#include <conio.h>
 +
#include <stdlib.h>
 
#include <math.h>
 
#include <math.h>
#include "Vector.h"
 
 
#include <cstring>
 
#include <cstring>
#include <cmath>
 
#include <malloc.h>
 
#include <fstream>
 
 
 
using namespace std;
 
using namespace std;
  
int n = 100;
+
class pad ///создаем класс
ofstream outfile;
 
 
 
class Ball                                          //класс бросаемого тела
 
 
{
 
{
    private:
+
private: ///в закрытом доступе
        double angle,m,k;                           //угол броска,масса,коэффицент сопротивления воздуха
+
    double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
        Vector3D r,v,a;                             //радиус-вектор,вектор скорости,ускорения
+
    double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
     public:
+
    int Size; ///размер массива- сколько точек считать в первом способе
 +
     double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
  
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
+
    void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
         Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
+
    {
 +
        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 (для нуля мы задали), чтобы считать координаты
 
         {
 
         {
             angle = _angle;
+
             t += shag; ///каждый раз прибавляем по времени шаг
             r    = _r;
+
             X[i] = v * cos(a) * t; ///координаты по х для простого падения
             v     = _v;
+
             E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
            a     = _a;
 
 
         }
 
         }
 +
    }
  
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
+
    void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
         Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
+
    {
         {
+
        g = 9.8; ///коэфф свободного падения
            angle = _angle;
+
         double Vy; /// переменная для значение скорости по у для метода эйлера
            r    = _r;
+
         float t = 0; ///время
            v    = _v;
+
        Y = new double [Size];///создаем массив для координат по у для простого падения
            a     = _a;
+
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
            m    = _m;
+
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
            k    = _k;
+
        Y[0] = 0;///задаем значение по у в нуле
         }
+
        G[0] = 0;///задаем значение по у в нуле по эйлеру
 
+
         for (int i = 1; i < Size; i++)///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
        //точная формула зависимости координаты от времени
 
        Vector3D positionReal(double t)
 
 
         {
 
         {
             double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
+
             t += shag; ///каждый раз прибавляем по времени шаг
             return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
+
            Y[i] = v * sin (a) *t - (g * t * t) * 0.5; ///координаты по у для простого падения
 +
            Vy -= g * shag; ///значение скорости по у для метода эйлера
 +
             G[i] = G[i-1] + Vy  * shag;///у из интегрирования по эйлеру
 
         }
 
         }
 +
    }
  
         //вывод положения на экран
+
    void SetVerle() ///функция для метода верле
         void writePosToScreen()
+
    {
 +
        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; ///значение у метод верле
 +
        Z[0] = -vy * shag; ///значение в нуле
 +
        for (int i = 0; i < Size1-2; i++) ///задаем цикл
 
         {
 
         {
             cout << r.x << "  " << r.y << "  " << r.z << endl;
+
             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() ///функция для точного метода верле
         void writePosToFile(char s[])
+
    {
 +
        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++)
 
         {
 
         {
             outfile.open(s,ios :: app);
+
             t += shag; ///увеличиваем время на шаг
             outfile << r.x << "          " << r.y << endl;
+
             V[i] = vx * (m / k) * (1.0 - exp(((-k) / m) * t)); ///значения по х для точного верле
             outfile.close();
+
             U[i] = (m / k) * (vy +  g * (m / k)) * (1.0 -  (exp(((-k) / m) * t))) - g * t * (m / k);///значения по х для точного верле
 
         }
 
         }
 +
    }
  
         //вывод произвольного вектора на экран
+
public: ///в открытом
         void WVTS(Vector3D v)
+
    pad()
         {
+
    {
            cout.width(15);
+
         X = 0; ///зануляем значения
            cout << v.x;
+
         Y = 0;
            cout.width(15);
+
        Size = 0;
            cout << v.y;
+
        v = 0;
            cout.width(15);
+
        shag = 0;
            cout << v.z << endl;
+
        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() ///функция записи в файл
         void WVTF(Vector3D v,char s[])
+
    {
         {
+
         ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
            outfile.open(s,ios :: app);
+
         fout << "X:    " << "    Y:    " << "    E:  " << "  G:  " << "  S:  " << "  Z:  "<< "  V:  "<< "    U:    "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
            outfile << v.x << "           " << v.y << endl;
+
        for (int i = 0; i < Size; i++) ///цикл
            outfile.close();
+
        fout << X[i] << "    " << Y[i] << "    " << E[i] << "    "  << G[i] << "  " << S[i] << "  " << Z[i] << "  " << V[i] <<"   "<< U[i] <<"\n"; ///забивает сами значения массивов
        }
+
        fout.close();///закрываем файл
 +
    };
 +
};
  
        //"пересчет" координаты по Верле(Линейная зависмость)
+
int main()/// основная функция
        void changeR(Vector3D r1, double dt)
+
{
        {
+
    double shag, b, v; ///шаг, угол в градусах, скорость начальная
            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 );
+
    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>
  
        //"пересчет" координаты по Верле(Квадратичная зависимость)
+
'''[[Гильманов Илья]]'''
        void changeRSQ(Vector3D r1, double dt)
 
        {
 
            r = MakeVector(2 * r.x -  r1.x - k/m*Length(v)*v.x*dt*dt,2*r.y - r1.y - (abs(a.y) + k/m*Length(v)*v.y)*dt*dt, 0 );
 
        }
 
        //пересчет скорости по Верле
 
        void changeV(Vector3D r1,double dt)
 
        {
 
            v =VS((VmV(r,r1)),1/(2*dt));
 
        }
 
  
        //рассчет предыдущегт к 0ому элементу
+
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
        Vector3D MR1(double dt)
+
#  Полет тела без сопротивления воздуха;
        {
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
            return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
        }
+
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 
 +
Скачать можно [[http://mech.spbstu.ru/File:Движение_тела_в_среде.rar тут]]
  
        //возращает координату тела
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
        Vector3D getR()
+
'''[[Демченко Артём]]'''
        {
 
            return r;
 
        }
 
  
        //рассчет времени полета
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
        double TimeOfFly()
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
        {
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
            return (2*Length(v)*sin(angle)/Length(a));
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
        }
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
        //рассчет координаты по точной формуле. без сопротивления воздуха.
+
''' Инструкция ''':
        Vector3D position(double t)
+
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
        {
 
            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()
+
<div class="mw-collapsible-content">
{
+
 
    //задание начальных параметров
 
    Vector3D g = {0,-9.8,0};
 
    double a,dt = 0;
 
    char s[20];
 
  
//    cin >> dt;
 
  
    dt = 0.1;
+
'''Визуализированный результат работы программы'''
    a = (M_PI * 30)/180;
 
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
 
  
    double tof = b1.TimeOfFly()+1;  //единичка прибавлена,чтобы график красивым был
+
[[:File:Throws.png]]
  
    //Без сопротивления возлуха
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    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);
 
    }
 
  
 +
#include <iostream>
 +
#include <math.h>
 +
#include <iomanip>
 +
#include <fstream>
 +
#include <conio.h>
 +
#include <stdio.h>
  
    //Верле(Линейная зависимость)
 
    dt = 0.1;
 
    a = (M_PI * 30)/180;
 
    Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
 
  
    strcpy(s,"");
+
using namespace std;
    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;
 
    }
 
  
    //Точное решение (Линейная зависимость)
+
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
    dt = 0.1;
 
    a = (M_PI * 30)/180;
 
    Ball b3(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
 
  
    strcpy(s,"");
+
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
    strcat(s, "o3.txt");
+
{
    outfile.open(s, ios :: trunc);
+
    FILE *Coord;
    outfile.close();
+
  Coord = fopen ("Throws Without Resistance.txt", "w");
    for (double i = 0; i <= 20; i += dt)
+
    double X = 0, Y = 0; // Координаты начала
    {
 
        b3.WVTS(b3.positionReal(i));
 
        b3.WVTF(b3.positionReal(i), s);
 
    }
 
  
 +
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
 +
    {
  
    //Верле (Квадратичная зависимость)
+
      X =  Vo*t*cos(alpha);
    dt = 0.1;
+
      Y = Vo*t*sin(alpha) - (g*t*t)*0.5;
     a = (M_PI * 30)/180;
+
      t+= dt;
    Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
+
     if (Y > Yo )
 +
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 +
    else
 +
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
 +
    }
  
    strcpy(s,"");
 
    strcat(s, "o4.txt");
 
    outfile.open(s, ios :: trunc);
 
    outfile.close();
 
    r1 = b4.MR1(dt);
 
    for (double i = 0; i <= 20; i += dt)
 
    {
 
        rp = b4.getR();
 
        b4.writePosToFile(s);
 
        b4.writePosToScreen();
 
        b4.changeRSQ(r1,dt);
 
        b4.changeV(r1,dt);
 
        r1.x = rp.x;
 
        r1.y = rp.y;
 
    }
 
 
    return 0;
 
 
}
 
}
</syntaxhighlight>
 
  
Файл "'''Vector.h'''"
+
int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
{                                                                                          // для линейной зависимости
#ifndef VECTOR_H_INCLUDED
+
    FILE *Coord;
#define VECTOR_H_INCLUDED
+
  Coord = fopen ("ExactForm.txt", "w");
 +
    double X, Y = 0, Vx, Vy;
  
struct Vector3D
+
    while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
{
+
    {
  double x,y,z;
 
};
 
  
Vector3D VmV(Vector3D v1,Vector3D v2)               //векторное вычитание
+
      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;
    Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
+
      Vx = Vo*cos(alpha);
    return v;
+
      Vy = Vo*sin(alpha);
};
+
      t+= dt;
Vector3D VpV(Vector3D v1,Vector3D v2)               //векторное сложение
+
    if (Y > Yo )
{
+
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
    Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
+
    else
    return v;
+
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
 +
      }
 
}
 
}
  
double VV(Vector3D v1,Vector3D v2)               //скалярное умножение
+
int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
{
+
{                                                                                                   // для Квадратичной зависимости сопротивления от скорости
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
+
    FILE *Coord;
}
+
  Coord = fopen ("VerleSq.txt", "w");
  
Vector3D VxV(Vector3D v1,Vector3D v2)              //векторное умножение
+
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
{
+
                                                                  // Xop, Yop - вспомогательные координаты для (-1)-го шага
  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)
+
    Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
{
+
    Xop = Xo - Vo*cos(alpha)*dt;
  return ((v1.x/v2.x == v1.y/v2.y)&&(v1.z/v2.z == v1.y/v2.y))? true:false;
+
    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)));
  
Vector3D VS(Vector3D v1, double s)
+
    fprintf(Coord, "%.3lf \t %.3lf\n", X, Y); // Записываем первую координату в файл
{
 
    Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
 
    return v;
 
}
 
  
double Length(Vector3D v1)
+
    Xprev = X; // Меняем координаты местами. Так (n-1)-ый шаг становится n-ым шагом, n-ый шаг становится (n+1)-ым шагом. Далее аналогично
{
+
    X = Xnext;
     return sqrt(VV(v1,v1));
+
     Yprev = Y;
}
+
    Y = Ynext;
  
Vector3D MakeVector(double x,double y,double z)
 
{
 
    Vector3D v = {x,y,z};
 
    return v;
 
}
 
  
Vector3D MakeVector(double length,double angle)
+
    while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
{
+
    {
     Vector3D v = {length * cos(angle), length * sin(angle),0};
+
     Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
     return v;
+
    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
  
double Proection(Vector3D base, Vector3D dir)
+
      fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
{
 
    return (VV(base,dir)/Length(base));
 
}
 
#endif // VECTOR_H_INCLUDED
 
</syntaxhighlight>
 
</div>
 
  
 +
    Xprev = X;
 +
    X = Xnext;
 +
    Yprev = Y;
 +
    Y = Ynext;
 +
    }
  
 +
}
 +
int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
 +
{                                                                                                  // для линейной зависимости сопротивления от скорости
 +
    FILE *Coord;
 +
  Coord = fopen ("VerleL.txt", "w");
  
<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)));
  
Программа записывает в один файл результаты вычисления:
+
    fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные при численном интегрировании - метод Эйлера;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:fly.zip тут].
+
    Xprev = X;
 +
    X = Xnext;
 +
    Yprev = Y;
 +
    Y = Ynext;
  
  
<div class="mw-collapsible-content">
+
    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;
 +
    }
  
'''Визуализированный результат работы программы'''
+
}
[[File:graphick.png]]
 
  
Для тела с массой 0.5 кг,сопротивлением воздуха 0.1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2, шаг 0.001;
+
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
  
# "output.txt" using 1 : 2 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
  cout << "Enter start speed:\n";
# "output.txt" using 3 : 4 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости (численное интегрирование - метод Эйлера);
+
  cin >> Vo; // Вводим с клавиатуры начальную скорость
# "output.txt" using 5 : 6 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости;
+
  cout << "Enter angle in grades ( from 0 to 180 ):\n";
# "output.txt" using 7 : 8 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости.
+
  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";
  
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    FILE *Gnu;
 +
    Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
  
#include <iostream>
+
switch ( i )
#include <fstream>
+
{
#include <iomanip>
+
case 1:
#include <time.h>
+
    {
#include <conio.h>
+
    WoutR(alpha,dt,t,Yo,Vo);
#include <stdlib.h>
+
    fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
#include <math.h>
+
    break;
#include <cstring>
+
    }
using namespace std;
+
case 2:
 
+
    {
class pad ///создаем класс
+
     ExactForm(alpha,dt,t,Yo,Vo,R,m);
{
+
    fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
private: ///в закрытом доступе
+
    break;
     double *X, *Y, *E, *G, *Z, *S, *V, *U; ///координаты по х и у; *E, *G : численное интегрирование метод Эйлера, *Z, *S- метод верле, *V, *U- точный метод
+
    }
     double a, g , pi;///ускорение, коэфф свободного падения, значение числа пи
+
case 3:
     int Size; ///размер массива- сколько точек считать в первом способе
+
    {
     double v, shag, b, vx, vy;///скорость, шаг по времени, угол в градусах скорость по х, скорость по у
+
    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 
+
     fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
     void SetX() ///создаем функцию для вычисления значенй по х для простого падения и по эйлеру
+
     break;
     {
+
    }
        g = 9.8;///коэфф свободного падения
+
case 4:
        float t = 0; ///время
+
    {
        X = new double [Size];///создаем массив для координат по х для простого падения
+
     VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
        E = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
+
     fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
        X[0] = 0; ///задаем значение по х в нуле
+
     break;
        E[0] = 0 ; ///задаем значение по х в нуле по эйлеру
+
    }
        for (int i = 1; i < Size; i++) ///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
+
case 5:
        {
+
    {
            t += shag; ///каждый раз прибавляем по времени шаг
+
  WoutR(alpha,dt,t,Yo,Vo);
            X[i] = v * cos(a) * t; ///координаты по х для простого падения
+
  ExactForm(alpha,dt,t,Yo,Vo,R,m);
            E[i] = E[i-1] + v * cos(a) * shag; ///х из интегрирования по эйлеру
+
  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;
 +
}
  
    void SetY()///создаем функцию для вычисления значенй по у для простого падения и по эйлеру
+
</syntaxhighlight>
    {
+
</div>
        g = 9.8; ///коэфф свободного падения
+
 
        double Vy; /// переменная для значение скорости по у для метода эйлера
+
 
        float t = 0; ///время
+
'''[[Иванова Яна]]'''
        Y = new double [Size];///создаем массив для координат по у для простого падения
+
 
        G = new double [Size];///создаем массив для координат по х для интегрирования по эйлеру
+
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
        Vy = v * sin (a);/// значение скорости по у для метода эйлера
+
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
        Y[0] = 0;///задаем значение по у в нуле
+
 
        G[0] = 0;///задаем значение по у в нуле по эйлеру
+
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
        for (int i = 1; i < Size; i++)///задаем цикл от 1 (для нуля мы задали), чтобы считать координаты
+
 
        {
+
<div class="mw-collapsible-content">
            t += shag; ///каждый раз прибавляем по времени шаг
+
'''Визуализированный результат работы программы'''[[File:graph.png]]
            Y[i] = v * sin (a) *t - (g * t * t) * 0.5; ///координаты по у для простого падения
 
            Vy -= g * shag; ///значение скорости по у для метода эйлера
 
            G[i] = G[i-1] + Vy  * shag;///у из интегрирования по эйлеру
 
        }
 
    }
 
  
    void SetVerle() ///функция для метода верле
+
[[:File:graph.png]]
    {
 
        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; ///значение у метод верле
 
        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: ///в открытом
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    pad()
+
#include <iostream>
    {
+
#include <math.h>
        X = 0; ///зануляем значения
+
#include <iomanip>
        Y = 0;
+
#include <fstream>
        Size = 0;
+
#include <conio.h>
        v = 0;
 
        shag = 0;
 
        b = 0;
 
    }
 
    pad(double _v, double _shag, double _b) ///конструктор с параметрами
 
    {
 
        pi = M_PI; ///значение числа пи
 
        g = 9.8; ///коэфф свободного падения
 
        v = _v;/// присваиваем значения переменных значению параметров в конструкторе
 
        shag = _shag;
 
        b = _b;
 
        a = (pi * b) / 180.0 ; ///вычисляем значение угла в радианах
 
        double t = (2.0 * v * sin(a)) / g; /// считаем значение времени
 
        Size = abs( t / shag )+1;///ищем значение размера массива
 
        SetX(); ///вызываем функции зависящие от параметров конструктора
 
        SetY();
 
        SetVerle();
 
        SetVerleLast();
 
    }
 
  
    void FilePrint() ///функция записи в файл
 
    {
 
        ofstream fout("output.txt"); ///открываем файл уже созданный в папке с программой
 
        fout << "X:    " << "    Y:    " << "    E:  " << "  G:  " << "  S:  " << "  Z:  "<< "  V:  "<< "    U:    "<<"\n" ; ///выводим стоку с разными названиями массивов, соотв. координатам по х и у различных методов
 
        for (int i = 0; i < Size; i++) ///цикл
 
        fout << X[i] << "    " << Y[i] << "    " << E[i] << "    "  << G[i] << "  " << S[i] << "  " << Z[i] << "  " << V[i] <<"    "<< U[i] <<"\n"; ///забивает сами значения массивов
 
        fout.close();///закрываем файл
 
    };
 
};
 
  
int main()/// основная функция
+
using namespace std;
 +
 
 +
ofstream outfile;
 +
 
 +
double perevod (double angle) //перевод из градусов в радианы
 
{
 
{
     double shag, b, v; ///шаг, угол в градусах, скорость начальная
+
     return (angle * M_PI / 180 );
    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>
 
  
  
 +
int main()
 +
{
 +
    //объявление переменных и задание начальных значений
 +
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
 +
    m = 1 , dt = 0.1 , g = 9.8,t = 0,
 +
    ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
  
'''[[Иванова Яна]]'''
+
    alpha = perevod (ugol);
  
'''Описание программы''': в программе выполняются четыре метода подсчета координат тела, брошенного под углом к горизонту. Координаты записываются в файл, строятся четыре графика, иллюстрирующие поведение тела при полете. Код написан для определенных начальных условий (для примера), если Вы хотите выполнить расчет для другой конфигурации, внесите изменения в начальные данные программы в самом коде.
+
    //точное решение для случая движения без сопротивления воздуха
Начальная скорость: 40 м/с, угол бросания: 45 градусов, коэффициент сопротивления воздуха: 0.023, шаг по времени : 0.1 секунды.
+
    Y = Yo;
 +
    X = Xo;
  
Скачать программу можно [http://tm.spbstu.ru/File:main.zip здесь]
+
    outfile.open("1.txt");
  
<div class="mw-collapsible-content">
+
    while (Y >= Yo)
'''Визуализированный результат работы программы'''[[File:graph.png]]
+
    {
 +
        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;
  
[[:File:graph.png]]
+
        outfile << X << ' ' << Y << endl;
 +
    }
 +
    outfile.close();
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    //начальные условия для квадратичной зависимости (метод Верле)
#include <iostream>
+
    Yprev = Yo - Vo*sin(alpha)*dt;
#include <math.h>
+
    Xprev = Xo - Vo*cos(alpha)*dt;
#include <iomanip>
+
    X = Xo;
#include <fstream>
+
    Y = Yo;
#include <conio.h>
+
    V = Vo;
 +
    Vx = Vo * cos(alpha);
 +
    Vy = Vo * sin(alpha);
  
 +
    outfile.open("2.txt");
  
using namespace std;
+
    while (Y >= Yo)
 +
    {
 +
        Xnext = 2.0 * X - Xprev - (R / m) * V * Vx * (dt * dt);
 +
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 +
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * V * Vy) * (dt * dt);
 +
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 +
        V = sqrt(Vy*Vy + Vx*Vx );
 +
        outfile << X << ' ' << Y << endl;
  
ofstream outfile;
+
        Xprev = X;
 
+
         X = Xnext;
double perevod (double angle) //перевод из градусов в радианы
+
         Yprev = Y;
{
+
         Y = Ynext;
    return (angle * M_PI / 180 );
 
}
 
 
 
 
 
int main()
 
{
 
    //объявление переменных и задание начальных значений
 
    double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,
 
    m = 1 , dt = 0.1 , g = 9.8,t = 0,
 
    ugol = 45, alpha, R = 0.023, Xo = 0, Yo = 0, Vo = 40;
 
 
 
    alpha = perevod (ugol);
 
 
 
    //точное решение для случая движения без сопротивления воздуха
 
    Y = Yo;
 
    X = Xo;
 
 
 
    outfile.open("1.txt");
 
 
 
    while (Y >= Yo)
 
    {
 
         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;
 
 
     }
 
     }
 
     outfile.close();
 
     outfile.close();
  
     //начальные условия для квадратичной зависимости (метод Верле)
+
     //начальные условия для линейной зависимости (метод Верле)
 
     Yprev = Yo - Vo*sin(alpha)*dt;
 
     Yprev = Yo - Vo*sin(alpha)*dt;
 
     Xprev = Xo - Vo*cos(alpha)*dt;
 
     Xprev = Xo - Vo*cos(alpha)*dt;
Строка 833: Строка 823:
 
     Vy = Vo * sin(alpha);
 
     Vy = Vo * sin(alpha);
  
     outfile.open("2.txt");
+
     outfile.open("3.txt");
  
 
     while (Y >= Yo)
 
     while (Y >= Yo)
 
     {
 
     {
        Xnext = 2.0 * X - Xprev - (R / m) * V * Vx * (dt * dt);
+
         Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
        Vx = ( Xnext - Xprev )/ (2.0 * dt);
 
        Ynext = 2.0 * Y - Yprev - (g + (R / m) * V * Vy) * (dt * dt);
 
        Vy =  (Ynext - Yprev)/ (2.0 * dt);
 
        V = sqrt(Vy*Vy + Vx*Vx );
 
        outfile << X << ' ' << Y << endl;
 
 
 
        Xprev = X;
 
        X = Xnext;
 
        Yprev = Y;
 
        Y = Ynext;
 
    }
 
    outfile.close();
 
 
 
    //начальные условия для линейной зависимости (метод Верле)
 
    Yprev = Yo - Vo*sin(alpha)*dt;
 
    Xprev = Xo - Vo*cos(alpha)*dt;
 
    X = Xo;
 
    Y = Yo;
 
    V = Vo;
 
    Vx = Vo * cos(alpha);
 
    Vy = Vo * sin(alpha);
 
 
 
    outfile.open("3.txt");
 
 
 
    while (Y >= Yo)
 
    {
 
         Xnext = 2.0 * X - Xprev - (R / m) * Vx * (dt * dt);
 
 
         Vx = ( Xnext - Xprev )/ (2.0 * dt);
 
         Vx = ( Xnext - Xprev )/ (2.0 * dt);
 
         Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
 
         Ynext = 2.0 * Y - Yprev - (g + (R / m) * Vy) * (dt * dt);
Строка 903: Строка 866:
 
</div>
 
</div>
  
 +
<div>
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
'''[[Капитанюк Светлана]]'''
'''[[Уманский Александр]]'''  
 
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
<div class="mw-collapsible-content">
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
 
 +
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
  
[[File:Methods.rar|Скачать архив]]
+
</div>
  
[[File:1.png]]
+
<div>
 +
'''[[Киселёв Лев]]'''
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
 +
#  Полет тела без сопротивления воздуха;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 +
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
  
</syntaxhighlight>
+
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
 
</div>
 
</div>
 
  
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 
<div class="mw-collapsible mw-collapsed" style="width:100%" >
'''[[Лосева Татьяна ]]'''  
+
'''[[Лебедев Станислав]]'''  
  
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела  и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
 
 +
Скачать можно  [http://tm.spbstu.ru/Файл:Шарик.rar тут].
  
 
<div class="mw-collapsible-content">
 
<div class="mw-collapsible-content">
  
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
+
[[File:1.png]]
 +
 
  
[[File:загружено (1).png]][[:File:загружено (1).png]]
+
'''Визуализированный результат работы программы'''
 +
[[File:graph.png]]
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
# o1 - координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
#include<iostream>
+
# o2 - координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
using namespace std;
+
# o3 - координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
#define N 1
+
# o4 - координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
#define PI 3.14159265
+
 
 +
 
 +
Для тела с массой 10,сопротивлением воздуха 1, угол бросания 30°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 +
 
 +
''Примечание: графики o1 и o2 намеренно посчитаны с малой точностью, чтобы графики не сливались.''
 +
 
 +
Файл "'''main.cpp'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
 +
#include <math.h>
 +
#include "Vector.h"
 +
#include <cstring>
 +
#include <cmath>
 +
#include <malloc.h>
 
#include <fstream>
 
#include <fstream>
#include<cmath>
 
double g=9.8;
 
double step=0.01;
 
#include<math.h>
 
  
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
using namespace std;
 +
 
 +
int n = 100;
 +
ofstream outfile;
  
 +
class Ball                                          //класс бросаемого тела
 
{
 
{
double x,y;
+
    private:
+
        double angle,m,k;                           //угол броска,масса,коэффицент сопротивления воздуха
ofstream fout;//открытие файла
+
        Vector3D r,v,a;                            //радиус-вектор,вектор скорости,ускорения
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
+
    public:
cout<<"method1"<<endl;
 
 
 
  for(double t=0.01;t<N;t=t+0.01)
 
{
 
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);
+
        Ball(double _angle, Vector3D _r, Vector3D _v, Vector3D _a)
 +
        {
 +
            angle = _angle;
 +
            r    = _r;
 +
            v    = _v;
 +
            a    = _a;
 +
        }
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
+
        //задание начальных параметров через угол,начальное положение,скорость и ускорение,с которым движется тело. Без сопротивления воздуха
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
+
        Ball(double _angle, double _m, double _k, Vector3D _r, Vector3D _v, Vector3D _a)
 
+
        {
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
+
            angle = _angle;
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
+
            r    = _r;
  ofstream fout;//открытие файла
+
            v    = _v;
fout.open("C:\\Users\\Light\\Desktop\\2.txt");//путь записи в файл
+
            a    = _a;
cout<<"Verle1"<<endl<<endl;
+
            m     = _m;
for(double t=0.02;t<N;t=t+step)
+
            k    = _k;
{
+
        }
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;
 
 
  
}
+
        //точная формула зависимости координаты от времени
}
+
        Vector3D positionReal(double t)
 +
        {
 +
            double c1 = m/k,c2 = fabs(a.y)*c1, c3 = exp(-t/c1), c4 = c2*t;
 +
            return MakeVector(v.x*c1*(1 - c3), c1*(v.y + c2)*(1 - c3) - c4 , 0 );
 +
        }
  
void Verle2( double n,double m ,double v0,double r)//3.Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
        //вывод положения на экран
 
+
        void writePosToScreen()
{  
+
        {
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 << r.x << "  " << r.y << "  " << r.z << endl;
 +
        }
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
+
        //вывод положения в файл
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
+
        void writePosToFile(char s[])
 +
        {
 +
            outfile.open(s,ios :: app);
 +
            outfile << r.x << "          " << r.y << endl;
 +
            outfile.close();
 +
        }
  
  xn_1=x0-vx*step;//X(n-1) для первого случая n=0
+
        //вывод произвольного вектора на экран
  yn_1=y0-vy*step;//Y(n-1) для первого случая n=0
+
        void WVTS(Vector3D v)
  ofstream fout;//открытие файла
+
        {
  fout.open("C:\\Users\\Light\\Desktop\\3.txt");//путь записи
+
            cout.width(15);
cout<<"Verle2"<<endl<<endl;
+
            cout << v.x;
for(double t=0.02;t<N;t=t+step)
+
            cout.width(15);
{
+
            cout << v.y;
 +
            cout.width(15);
 +
            cout << v.z << endl;
 +
        }
  
  v=sqrt(vx*vx+vy*vy);//скорость V
+
        //вывод произвольного вектора в файл
 
+
        void WVTF(Vector3D v,char s[])
x=2*x0-xn_1-(n*v*vx*step*step)/m;//Xn+1
+
         {
vx=(x-xn_1)/(2*step);//скорость Vx
+
            outfile.open(s,ios :: app);
         xn_1=x0;//для следущего шага Xn-1=Xn
+
            outfile << v.x << "           " << v.y << endl;
x0=x;//для следущего шага Xn=Xn+1
+
            outfile.close();
+
        }
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)//Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
        //"пересчет" координаты по Верле(Линейная зависмость)
{
+
        void changeR(Vector3D r1, double dt)
double x,y,x0=0,y0=0;//x0,y0 начальные значения;
+
        {
 +
            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 );
 +
        }
  
double vx=v0*cos(r*PI / 180);//рассчитваем Vx
+
        //"пересчет" координаты по Верле(Квадратичная зависимость)
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vy
+
        void changeRSQ(Vector3D r1, double dt)
 
+
        {
  ofstream fout;//открытие файла
+
            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 );
  fout.open("C:\\Users\\Light\\Desktop\\4.txt");
+
        }
cout<<"4"<<endl<<endl;
+
        //пересчет скорости по Верле
for(double t=0.01;t<N;t=t+step)
+
        void changeV(Vector3D r1,double dt)
{
+
        {
x=x0+m*vx*(1-(exp((-1*n)*t/m)))/n;//координата х
+
            v =VS((VmV(r,r1)),1/(2*dt));
+
        }
y = y0+(m/n)*((vy + g * m / n)*(1 - exp(-1 * n * t / m))) - g * t*m/n;//координата у
 
  
//вывод в файл  и на экран
+
        //рассчет предыдущегт к 0ому элементу
    cout<<"X="<<x<<endl;
+
        Vector3D MR1(double dt)
cout<<"Y="<<y<<endl<<endl;
+
        {
fout<<x<<" ";
+
            return MakeVector(r.x - v.x * dt,r.y - v.y * dt,0);
fout<<y<<" ";
+
        }
fout<<endl;
 
  
}
+
        //возращает координату тела
}
+
        Vector3D getR()
 
+
        {
int main(void)
+
            return r;
{
+
        }
  
double v0,r,m,n;//v0-начальная скорость,r-угол в градусах,m-масса;n-коэф.сопротивления ветра
+
        //рассчет времени полета
 
+
        double TimeOfFly()
cout<<"Enter  start speed:"<<endl;
+
        {
cin>>v0;
+
            return (2*Length(v)*sin(angle)/Length(a));
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);
 
  
 +
        //рассчет координаты по точной формуле. без сопротивления воздуха.
 +
        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 k;
+
int main()
cin>>k;
+
{
return 0;
+
    //задание начальных параметров
}
+
    Vector3D g = {0,-9.8,0};
 +
    double a,dt = 0;
 +
    char s[20];
  
</syntaxhighlight>
+
//    cin >> dt;
</div>
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
+
    dt = 0.1;
 +
    a = (M_PI * 30)/180;
 +
    Ball b1(a, MakeVector(0,0,0),MakeVector(30,a),g);
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    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);
 +
    }
  
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
 
  
<div class="mw-collapsible-content">
+
    //Верле(Линейная зависимость)
[[File:graph239.png]]
+
    dt = 0.1;
 +
    a = (M_PI * 30)/180;
 +
    Ball b2(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
  
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
+
    strcpy(s,"");
 
+
    strcat(s, "o2.txt");
 
+
    outfile.open(s,ios :: trunc);
 
+
    outfile.close();
Файл "'''main.cpp'''"
+
    Vector3D r1 = b2.MR1(dt),rp;
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    for (double i = 0; i <= 20; i += dt)
#include <iostream>
+
    {
#include <locale.h>
+
        rp = b2.getR();
#include <math.h>
+
        b2.writePosToFile(s);
#include <fstream>
+
        b2.writePosToScreen();
#include<iomanip>
+
        b2.changeR(r1,dt);
#include <cmath>
+
        b2.changeV(r1,dt);
using namespace std;
+
        r1.x = rp.x;
main ()
+
        r1.y = rp.y;
{
+
    }
     ofstream F;                                                                    //a1-угол в градусах,dt-шаг,r-сопротивление воздуха
+
 
int u0=50;
+
     //Точное решение (Линейная зависимость)
double x,y,t,a,a1=30,dt=0.1,y0=0,x0=0,g=9.8,r=0.05,m=1,ux,uy,ypr,xpr,ysl,xsl,u,yt; //ux,uy - проэкции скорости на оси х и у.
+
    dt = 0.1;
a=a1*M_PI/180; //Градусы в радианы
+
    a = (M_PI * 30)/180;
t=0;
+
    Ball b3(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
+
 
                                        //Движение без сопротивления воздуха
+
    strcpy(s,"");
F.open("C:\\1.txt",ios::out);
+
    strcat(s, "o3.txt");
while(y>=0)
+
    outfile.open(s, ios :: trunc);
{
+
    outfile.close();
    x=x0+u0*cos(M_PI/6)*t;
+
    for (double i = 0; i <= 20; i += dt)
    y=y0+u0*sin(M_PI/6)*t - 0.5 * g * t * t; //Расчитываем координаты в каждой точке через шаг
+
    {
  F<<x<<" "<<y<<endl;
+
        b3.WVTS(b3.positionReal(i));
  t=t+dt;
+
        b3.WVTF(b3.positionReal(i), s);
+
    }
 +
 
 +
 
 +
    //Верле (Квадратичная зависимость)
 +
    dt = 0.1;
 +
    a = (M_PI * 30)/180;
 +
    Ball b4(a,10 , 1, MakeVector(0,0,0),MakeVector(30,a),g);
 +
 
 +
    strcpy(s,"");
 +
    strcat(s, "o4.txt");
 +
    outfile.open(s, ios :: trunc);
 +
    outfile.close();
 +
    r1 = b4.MR1(dt);
 +
    for (double i = 0; i <= 20; i += dt)
 +
    {
 +
        rp = b4.getR();
 +
        b4.writePosToFile(s);
 +
        b4.writePosToScreen();
 +
        b4.changeRSQ(r1,dt);
 +
        b4.changeV(r1,dt);
 +
        r1.x = rp.x;
 +
        r1.y = rp.y;
 +
    }
 +
 
 +
    return 0;
 
}
 
}
+
</syntaxhighlight>
F.close();
+
 
                                        //Точное решение для линейной зависимости
+
Файл "'''Vector.h'''"
F.open("C:\\2.txt",ios::out);
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
y=y0;
+
#ifndef VECTOR_H_INCLUDED
x=x0;
+
#define VECTOR_H_INCLUDED
t=0;                                                                           //Расчитываем координаты в каждой точке через шаг
+
 
while(y>=0)
+
struct Vector3D
 +
{
 +
  double x,y,z;
 +
};
 +
 
 +
Vector3D VmV(Vector3D v1,Vector3D v2)               //векторное вычитание
 +
{
 +
    Vector3D v = {v1.x - v2.x,v1.y - v2.y,v1.z - v2.z };
 +
    return v;
 +
};
 +
Vector3D VpV(Vector3D v1,Vector3D v2)               //векторное сложение
 
{
 
{
        ux = u0 * cos(a);
+
    Vector3D v = {v1.x + v2.x,v1.y + v2.y,v1.z + v2.z };
        uy = u0 * sin(a);
+
    return v;
        x = x0+ (m * ux / r)* (1 - exp(-1 * r * t / m));                      //подстановка формул
 
        y = y0+(m/r)*((uy + g * m / r)*(1 - exp(-1 * r * t / m)) - g * t);
 
        t = t + dt;
 
 
      F << x << ' ' << y << endl;
 
 
 
 
 
}
 
}
  F.close();
+
 
                                                        //метод Верле 1
+
double VV(Vector3D v1,Vector3D v2)               //скалярное умножение
ypr = y0 - u0*sin(a)*dt;
+
{
yt=ypr;
+
  return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
    xpr = x0 - u0*cos(a)*dt;
+
}
    x = x0;                          //Начальные условия
+
 
    y = y0;
+
Vector3D VxV(Vector3D v1,Vector3D v2)               //векторное умножение
    u = u0;
+
{
    ux = u0 * cos(a);
+
  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};
    uy = u0 * sin(a);                      
+
  return v;
F.open("C:\\3.txt",ios::out);
+
}
+
 
    while (y >= y0)
+
bool Kol(Vector3D v1,Vector3D v2)
    {
+
{
        xsl = 2 * x - xpr - (r / m) * u * ux * (dt * dt);
+
  return ((v1.x/v2.x == v1.y/v2.y)&&(v1.z/v2.z == v1.y/v2.y))? true:false;
        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);
+
Vector3D VS(Vector3D v1, double s)
        u = sqrt(uy*uy + ux*ux );
+
{
        F << x << ' ' << y << endl;
+
     Vector3D v = {v1.x*s, v1.y*s, v1.z*s};
+
     return v;
        xpr = x;
+
}
        x = xsl;
+
 
        ypr = y;
+
double Length(Vector3D v1)
        y = ysl;
+
{
    }
+
     return sqrt(VV(v1,v1));
    F.close();
+
}
                                                      //Метод Верле 2
+
 
    ypr = y0 - u0*sin(a)*dt;
+
Vector3D MakeVector(double x,double y,double z)
yt=ypr;
+
{
     xpr = x0 - u0*cos(a)*dt;
+
    Vector3D v = {x,y,z};
     x = x0;                                                                           //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
+
    return v;
    y = y0;
+
}
    u = u0;
+
 
    ux = u0 * cos(a);                           
+
Vector3D MakeVector(double length,double angle)
     uy = u0 * sin(a);
+
{
F.open("C:\\4.txt",ios::out);
+
    Vector3D v = {length * cos(angle), length * sin(angle),0};
+
     return v;
    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;
 
 
 
 
}
 
}
  
 +
double Proection(Vector3D base, Vector3D dir)
 +
{
 +
    return (VV(base,dir)/Length(base));
 +
}
 +
#endif // VECTOR_H_INCLUDED
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div>
 
</div>
  
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
<div>
'''[[Александр Сюрис]]'''  
+
'''[[Лобанов Илья]]'''
 +
 
 +
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
  
'''Описание программы''':
+
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
+
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
+
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении           воздуха от скорости
+
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 
Скачать можно  [http://mech.spbstu.ru/File:%D0%9F%D0%BE%D0%BB%D0%B5%D1%82_%D1%82%D0%B5%D0%BB%D0%B0(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip тут].
 
<div class="mw-collapsible-content">
 
[[File:Снимок.PNG]]
 
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 
Файл "'''main.cpp'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
#include <iostream>
 
#include <fstream>
 
#include <math.h>
 
#include <cmath>
 
using namespace std;
 
int o;
 
double v,a,m,k;
 
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
 
  
  
 +
'''Краткая инструкция''':
  
int rez_1(double v, double a)
+
В окне консоли пользователю предлагается вывести следующие значения: начальную скорость , угол и шаг.
{
+
После этого полученные в результате работы программы данные выводятся в файл.
    fout<<"---------------Первый режим-------------------------"<<endl;
 
    fout<<" T=0 x=0 y=0";
 
    fout<<endl;
 
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
 
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
 
    V0y=v*sin(a/180*M_PI);
 
    Ty=2*V0y/g;//время полета
 
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
 
    {
 
        x=x+V0x*t;              //ф-лы для рассчета x и y в данный момент времени
 
        y=y+V0y*t-g*pow(t,2)/2;
 
  
        if (y<0) //если y<0
+
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
            {
+
[[http://tm.spbstu.ru/File:phys.rar тут]]
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
+
 
                x=x+V0x*t1;//используя это время находим координату по х
+
</div>
                fout<<" T="<<Ty<<" x="<<x<<" y=0"<<endl;//ввод в текстовый файл
+
 
                break;
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
            }
+
'''[[Лосева Татьяна ]]'''
            else
+
 
                {
+
'''Описание:''' Пользователя попросят ввести начальную скорость,угол бросания,массу тела  и коэф.сопротивления воздуха,тогда программа запишет в 4 разных файла результаты следующих вычислений:
                    V0y=V0y-g*t;// иначе находим новую скорость по y (по x не меняется)
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
                    fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
                    T=T+t;//увел время на шаг
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
                }
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
    }
 
  
 +
<div class="mw-collapsible-content">
  
}
+
''Графики полученные при скорости =10 m/c;угле = 30 градусам;массе=10 кг;коэф.сопротивления=1;''
  
 +
[[File:загружено (1).png]][[:File:загружено (1).png]]
  
int rez_2(double v, double a, double k, double m)
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
{
+
#include<iostream>
    fout<<"---------------Второй режим работы-------------------------"<<endl;
+
using namespace std;
    fout<<" T=0 x=0 y=0";
+
#define N 1
    fout<<endl;
+
#define PI 3.14159265
    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;
+
#include <fstream>
    x=(m*Vx/k)*(1-exp(-1*k*T/m));            //ф-лы для рассчета x и y в данный момент времени
+
#include<cmath>
    y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T);  //точное решение при лин завсисимости
+
double g=9.8;
    while (y>0)
+
double step=0.01;
    {
+
#include<math.h>
        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;
 
    }
 
  
 +
void Func(double v,double r)//1.Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
  
}
 
 
 
 
int rez_3(double v, double a, double k, double m)
 
 
{
 
{
  fout<<"---------------Третий режим работы-------------------------"<<endl;
+
double x,y;
    fout<<" T=0 x=0 y=0";
+
    fout<<endl;
+
ofstream fout;//открытие файла
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
+
  fout.open("C:\\Users\\Light\\Desktop\\1.txt");//указываем путь записи
    x3=0,x2=0,x1=x2-Vxn*t,  y3=0,
+
cout<<"method1"<<endl;
    y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
 
  
 +
  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)//Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
  
    x3=2*x2-x1-k/m*Vxn*pow(t,2);  //координаты в момент времени T
+
{
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
+
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);
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
 
    Vyn=(y3-y1)/(2.0*t);
 
    x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
 
    y1=y2;
 
    x2=x3;//-//- к координате в n шаге значение в момент времени T
 
    y2=y3;
 
    while (y2>0)
 
    {
 
        x3=2*x2-x1-k/m*Vxn*pow(t,2);
 
        y3=2*y2-y1-(g+k/m*Vyn)*pow(t,2);
 
        Vxn=(x3-x1)/(2.0*t);
 
        Vyn=(y3-y1)/(2.0*t);
 
        fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
 
 
 
        if (y3<0)
 
        {
 
            t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
 
            x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
 
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 
        }
 
  
        T=T+t;
+
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
        x1=x2;
+
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
        y1=y2;
 
        x2=x3;
 
        y2=y3;
 
  
    }
+
  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_4(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";
+
double vx=v0*cos(r*PI / 180);//рассчитваем Vn для первого случая n=0 для x
    fout<<endl;
+
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vn для первого случая n=0 для y
    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,
 
  
 +
  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\\3.txt");//путь записи
 +
cout<<"Verle2"<<endl<<endl;
 +
for(double t=0.02;t<N;t=t+step)
 +
{
  
    x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
+
  v=sqrt(vx*vx+vy*vy);//скорость V
    y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
 
    Vxn=(x3-x1)/(2.0*t);
 
    Vyn=(y3-y1)/(2.0*t);
 
    V=sqrt(pow(Vxn,2)+pow(Vyn,2.0));
 
    x1=x2;
 
    y1=y2;
 
    x2=x3;
 
    y2=y3;
 
    while (y2>0)
 
    {
 
        x3=2.0*x2-x1-(k/m)*Vxn*V*pow(t,2);
 
        y3=2.0*y2-y1-(g+(k/m)*Vyn*V)*pow(t,2);
 
        Vxn=(x3-x1)/(2.0*t);
 
        Vyn=(y3-y1)/(2.0*t);
 
        V=sqrt(pow(Vxn,2)+pow(Vyn,2));
 
        fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
 
 
 
        if (y3<0)
 
        {
 
            t1=sqrt(abs((-y1+2.0*y2)/(g+(k/m)*Vyn*V)));
 
            x3=2.0*x2-x1-(k/m)*Vxn*V*pow((t+t1),2);
 
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 
        }
 
 
 
 
 
        T=T+t;
 
        x1=x2;
 
        y1=y2;
 
        x2=x3;
 
        y2=y3;
 
 
 
    }
 
  
 +
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 main()
 
 
{
 
{
 +
double x,y,x0=0,y0=0;//x0,y0 начальные значения;
  
  setlocale(LC_ALL, "rus");
+
  double vx=v0*cos(r*PI / 180);//рассчитваем Vx
cout<<"Введите скорость тела и угол"<<endl;
+
  double vy=v0*sin(r*PI/ 180)-g*step;//рассчитваем Vy
cin>>v>>a;
+
 
 +
  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;//координата у
  
  while (1>0){
+
//вывод в файл и на экран
cout<<"Выберите режим работы программы:"<<endl;
+
    cout<<"X="<<x<<endl;
cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
+
cout<<"Y="<<y<<endl<<endl;
cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
fout<<x<<" ";
cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
fout<<y<<" ";
cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
+
fout<<endl;
cout<<"5 - Выйти";
+
 
cin>>o;
+
}
 +
}
 +
 
 +
int main(void)
 +
{
 +
 
 +
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);
  
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;
 
  
            }
+
int k;
 +
cin>>k;
 +
return 0;
 
}
 
}
 
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div>
 
</div>
  
 +
Скачать можно  [http://tm.spbstu.ru/Файл:Verle.rar  тут].
 +
 +
<div>
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
'''[[Ляжков Сергей]]'''
'''[[Тимошенко Валентина]]'''  
 
  
'''Описание программы''': при запуске пользователь вводит шаг функции, угол, под которым бросают тело, массу тела, сопротивление воздуха и скорость.  
+
'''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
Программа записывает в четыре файла результаты вычисления:
+
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
#Координаты, рассчитанные по формуле для движения без сопротивления воздуха;
+
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
#Координаты, рассчитанные по формуле для движения с учетом сопротивления воздуха;
+
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивления воздуха от скорости.
+
</div>
#Координаты, полученные методом Верле при линейной зависимости силы сопротивления воздуха от скорости;
 
  
Скачать можно  [http://tm.spbstu.ru/Файл:motion.zip тут.]
+
<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
 +
*/
  
<div class="mw-collapsible-content">
+
#include "ANIM.H"
 +
#include "SAMPLE.H"
  
'''Визуализированный результат работы программы'''
+
/* Main function */
[[File:Grafics.png]]
+
void main( void )
 
+
{
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
+
// Получение единственного экземпляра класса анимации
 
+
sagl::anim &My = sagl::anim::Get();
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
 
 +
// Шар, летящий без сопротивлением воздуха
 +
        for (int i = 0; i < 1; i++)
 +
                My << new ball(Pi / 6, 10 + i);
  
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
+
// Шар, летящий с сопротивлением воздуха
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
+
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
#include <math.h>
+
for (int i = 0; i < 1; i++)
#include<stdlib.h>
+
My << new ball_air(Pi / 6, 10 + i, 10, 0.01);
using namespace std;
 
  
int main()
+
// Шар, летящий с сопротивлением воздуха
{
+
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
    double a, step, Pi, g, Vo, m, r;
+
for (int i = 0; i < 1; i++)
    ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
+
My << new ball_air_2(Pi / 6, 10 + i, 10, 0.01);
  
    double x, y, x_0, y_0, x0, y0, Vx, Vy;
+
// Шар, летящий с сопротивлением воздуха
    ///переменные для движения точки без учёта сопротивления и с его учётом
+
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
    ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
+
for (int i = 0; i < 1; i++)
    ///х0 - начальная координата тела по оси Ох, у0 - начальная координата тела по оси Оу
+
My << new ball_air_3(Pi / 6, 10 + i, 10, 0.01);
    ///Vx - скорость тела по оси Ох, Vу - скорость тела по оси Оу
 
    ///x_0 - изменяющаяся пошагово координата тела по оси Ох с учётом сопротивления, у_0 - изменяющаяся пошагово координата тела по оси Оу с учётом сопротивления
 
  
    double Vy0, Vx0, x1, x2, x3, y1, y2, y3, Vxn, Vyn, Vn;
+
// Запуск главного цикла
    ///переменные для 1го варианта метода Верле
+
  My.Run();
    ///х1 - координата тела по оси Ох на (n-1) шаге, х2 - координата тела по оси Ох на (n) шаге, х3 - координата тела по оси Ох на (n+1) шаге
+
} // End of 'main' function
    ///у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;
+
// END OF 'T43ANIM.CPP' FILE
    ///переменные для 2го варианта метода Верле
+
</syntaxhighlight>
    ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
+
"'''ANIM.CPP'''"
    ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
+
/* FILENAME: ANIM.CPP
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
    g=10; ///значение ускорения свободного падения
+
#include <stdio.h>
    Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
+
#include <stdlib.h>
 +
#include <time.h>
  
    do ///цикл, запрашивающий ввод пользователем значения шага функции
+
#include "ANIM.H"
    {
 
        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; ///вывод значение угла на экран
+
sagl::anim sagl::anim::Instance;
    a=(Pi*a)/180.0;
 
    cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
 
    cin >> m; ///вывод величины массы на экран
 
  
    do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
+
/* Reshape function */
    {
+
// Стандартная функция, вызываемая при изменении размеров окна
        cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
+
void sagl::anim::Reshape( int W, int H )
        cin >> r; ///вывод значения сопротивления на экран
+
{
    }
+
  // Установка области просмотра - все окно
    while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
+
glViewport(0, 0, W, H);
 +
  Instance.WinW = W;
 +
  Instance.WinH = H;
 +
  double ratio_x = 1, ratio_y = 1;
 +
  if (W > H)
 +
    ratio_x = (double)W / H;
 +
  else
 +
    ratio_y = (double)H / W;
 +
  double Size = 1, Near = 1, Far = 500;
 +
  // Установка системы координат "камеры"
 +
glMatrixMode(GL_PROJECTION);
 +
  glLoadIdentity();
 +
  glFrustum(-Size * ratio_x, Size * ratio_x,
 +
            -Size * ratio_y, Size * ratio_y,
 +
            Near, Far);
 +
// Установка "мировой" СК в состояние без преобразований
 +
  glMatrixMode(GL_MODELVIEW);
 +
} // End of 'Reshape' function
  
    cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
+
/* Timer function */
    cin >> Vo; ///вывод значения скорости на экран
+
// Подсчет времени
 
+
void sagl::anim::Timer( void )
    ///для движения без учёта сопротивления
+
{
    x0=0; ///обнуление переменных
+
  long Time = clock();
     y0=0;
+
 
     x=0;
+
  if (IsPause)
    y=0;
+
     DeltaTime = 0, PauseTime += Time - OldTime;
 +
  else
 +
     DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;  
 +
  OldTime = Time;
  
    ///для движения с учётом сопротивления
+
  SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
    x_0=0; ///обнуление переменных
+
} /* End of 'Timer' function */
    y_0=0;
 
  
    ///для 1го варианта метода Верле
+
/* Display function */
 +
// Стандартная функция, вызываемая при перерисовке окна
 +
void sagl::anim::Display( void )
 +
{
 +
// Запуск времени
 +
Instance.Timer();
 +
// Очищаем цветовой буфер для создания нового изображения
 +
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
    Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
+
  glLoadIdentity();
    Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
+
  // Позиционирование СК
 +
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
  
    x2=0; ///обнуление переменных
+
// Отрисовка объектов
    y2=0;
+
  Instance.Render();
    x3=0;
 
    y3=0;
 
  
    y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
+
  glFinish();
    x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
+
// Копируем вторичный буфер в окно
 +
glutSwapBuffers();
 +
// Вызываем функцию обновления кадра
 +
glutPostRedisplay();
 +
} // End of 'Display' function
  
     ///для 2го варианта метода Верле
+
/* Keyboard function */
 +
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 +
void sagl::anim::Keyboard( unsigned char Key, int X, int Y )
 +
{
 +
// Выход из программы
 +
if (Key == 27)
 +
     exit(0);
 +
// Открытие программы в полном экране
 +
else if (Key == 'f')
 +
    glutFullScreen();
 +
  // Пауза
 +
else if (Key == 'p' || Key == 'P')
 +
    Instance.IsPause = !Instance.IsPause;
 +
} // End of 'Keyboard' function
  
    x_2=0; ///обнуление переменных
+
sagl::anim::anim( void ) : IsPause(false), SyncTime(0), DeltaTime(0),
    y_2=0;
+
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
    x_3=0;
+
{
    y_3=0;
+
// Инициализации OpenGL и GLUT
 +
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
 +
 
 +
// Задача размеров и позиции окна
 +
glutInitWindowPosition(0, 0);
 +
  glutInitWindowSize(700, 700);
 +
// Создание окна
 +
glutCreateWindow("T06BALL");
  
    Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
+
// Установка функций 'обратного вызова'
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
+
  glutDisplayFunc(Display);
 +
  glutKeyboardFunc(Keyboard);
 +
  glutReshapeFunc(Reshape);
  
    y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
+
// Установка цвета закраски фона
    x_1=-Vo*cos(a)*step;   ///расчет начального значения координаты на (п-1) шаге по оси Ох
+
  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);
 +
}
  
    ofstream out("For method without resistance.txt");
+
// Деструктор
     ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
+
sagl::anim::~anim( void )
 +
{
 +
  // Чистка памяти
 +
for (int i = 0; i < StockSize; i++)
 +
     delete Stock[i];
 +
}
  
    for (int i=0; y>=0; ++i) ///цикл для подсчета координат при движении тела без учёта сопротивления
+
/* Render function */
    {
+
// Отрисовка объектов
        x=Vo*step*i*cos(a); ///расчет координаты тела по оси х
+
void sagl::anim::Render( void )
        y=Vo*sin(a)*i*step-(g*i*step*i*step)*0.5; ///расчет координаты тела по оси y
+
{
 +
for (int i = 0; i < StockSize; i++)
 +
Stock[i]->Render(*this);
 +
} // End of 'Render' function
  
        out << x << "    " << y <<'\n';  ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
+
/* Run function */
    }
+
// Запуск главного цикла
    out.close();
+
void sagl::anim::Run( void )
 +
{
 +
// Запуск основного цикла построения
 +
glutMainLoop();
 +
} // End of 'Run' function
  
    ofstream out1 ("For method with resistance.txt");
+
// END OF 'ANIM.CPP' FILE
    ///запись в файл значений координат по осям Ох и Оу для движения с учётом сопротивления
+
</syntaxhighlight>
 +
"'''ANIM.H'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: ANIM.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
    for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
+
#ifndef __ANIM_H_
    {
+
#define __ANIM_H_
        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 учётом сопротивления
+
#include <stdio.h>
    }
+
#include <stdlib.h>
    out1.close();
+
#include <time.h>
  
    ofstream out2 ("For method Verle 1.txt");
+
#include <GL\glut.h>
    ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
 
  
    for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
+
#include "VEC.H"
    {
 
        x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
 
        y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
 
        Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
 
        Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
 
        Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
 
  
        x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
+
// Константы
        x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
+
#define Pi 3.14159265358979323846
        y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
+
#define E 2.71828182845904523536
        y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
 
 
 
        out2 << x3 << "  " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
 
    }
 
    out2.close();
 
 
 
    ofstream out3 ("For method Verle 2.txt");
 
    ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
 
 
 
    for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
 
    {
 
        x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
 
        y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
 
        Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
 
        Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
 
 
 
        x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
 
        x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
 
        y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
 
        y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
 
 
 
        out3 << x_3 << "  " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
 
  
 +
// Собственное пространство имен 'sagl'
 +
namespace sagl
 +
{
 +
  // Объявления класса анимации наперед
 +
class anim;
 +
 
 +
// Функции получения случайных чисел
 +
inline double r0( void )
 +
  {
 +
    return rand() / (double)RAND_MAX;
 +
  }
 +
  inline double r1( void )
 +
  {
 +
    return 2.0 * rand() / RAND_MAX - 1;
 +
  }
 +
 
 +
// Класс объектов
 +
class object
 +
  {
 +
  public:
 +
    // Вектора перемещения и скоростей
 +
vec P, V, AbsV;
 +
   
 +
// Конструктор
 +
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
 +
    {
 
     }
 
     }
    out3.close();
+
 
+
// Отрисовка объектов
     cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
+
virtual void Render( anim &Ani )
     cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
+
    {
     return 0;
+
     } // End of 'Render' function
}
+
  }; // end of 'object' class
</syntaxhighlight>
+
 
</div>
+
// Класс анимации
 +
class anim
 +
  {
 +
  private:
 +
     // Функции 'обратного вызова'
 +
static void Display( void );
 +
     static void Keyboard( unsigned char Key, int X, int Y );
 +
    static void Reshape( int W, int H );
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
    // Единственный экземпляр класса
'''[[Савельева Ольга]]'''
+
static anim Instance;
 +
   
 +
    // Конструктор
 +
anim( void );
  
'''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
+
// Максимальное количество объектов
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
    static const int Max = 100;
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
    // 'Контейнер' объектов
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
+
object *Stock[Max];
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
    // Размер 'контейнера' объектов
 
+
int StockSize;
<div class="mw-collapsible-content">
+
   
 
+
// Переменные, хранящие время в секундах
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    long StartTime, OldTime, PauseTime;
#include <stdio.h>
+
   
#include <stdlib.h>
+
// Отрисовка объектов
#include <cmath>
+
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;
  
using namespace std;
+
// Переменные, хранящие время в секундах
 +
    double SyncTime, DeltaTime;
  
FILE *output;
+
    // Переменная, отвечающая за паузу
 +
bool IsPause;
  
double e = 0.0000001; //точность
+
    // Деструктор
double g = 9.8; //ускорение свободного падения
+
~anim( void );
double dt = 0.00001;  //шаг по времени
+
   
double windageLinearCoefficient = 0.1;
+
// Запуск главного цикла
double windageSquareCoefficient = 0.00001;
+
void Run( void );
 
+
      
struct Vector  //вектор
+
     // Метод, возвращающий переменную - единственный экземпляр данного типа
{
+
static anim & Get( void )
    double x, y;
 
    Vector():x(0), y(0)
 
     {}
 
     Vector(double x, double y):x(x), y(y)
 
    {}
 
    const Vector operator+(const Vector &v) const
 
 
     {
 
     {
        return Vector(this -> x + v.x, this -> y + v.y);
+
      return Instance;
 
     }
 
     }
    const Vector operator-(const Vector &v) const
+
  }; // end of 'anim' class
    {
+
} // end of 'sagl' namespace
        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)
+
#endif /*__ANIM_H_ */
{
 
    return Vector(v.x * a, v.y * a);
 
}
 
  
const Vector operator*(const int k, const Vector &v)
+
// END OF 'ANIM.H' FILE
{
+
</syntaxhighlight>
    return Vector(v.x * k, v.y * k);
+
"'''VEC.H'''"
}
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
/* FILENAME: VEC.H
 +
* LAST UPDATE: 17.01.2016
 +
*/
  
double abs(const Vector &v)
+
#ifndef __VEC_H_
{
+
#define __VEC_H_
    return sqrt(v.x * v.x + v.y * v.y);
 
}
 
  
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
+
#include <stdlib.h>
{
+
#include <math.h>
    fputs(description, output);
 
    fputs(": ", output);
 
    fprintf(output, "%lf", v.x);
 
    fputs(", ", output);
 
    fprintf(output, "%lf\n", v.y);
 
}
 
  
Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
+
// Собственное пространство имен 'sagl'
 +
namespace sagl
 
{
 
{
    double fallTime = 2 * velocity * sin(angle) / g;  //расчет времени падения
+
  // Класс векторов
    if((time < 0) or (time > fallTime))
+
class vec
        time = fallTime;
+
  {
    double x = velocity * cos(angle) * time;    // x = vx*t;
+
  public:
     double y = velocity * sin(angle) * time - g * time * time / 2;  // y = vy*t-(g*t^2)/2;
+
     // Координаты вектора
    return Vector(x, y);
+
double X, Y, Z;
}
+
      
 
+
// Конструктор
Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
+
vec( void ) : X(0), Y(0), Z(0)
{
 
    double nowTime = dt;
 
     Vector rsb(0, 0);
 
    if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
 
        return rsb; //вернитесь в начальную точку
 
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
 
    Vector r = v * dt;    //вторая точка
 
    Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
 
    a.y -= g;
 
    v = v + a * dt; //скорость во второй точке
 
    a = -windageLinearCoefficient * v; //ускорение во второй точке
 
    a.y -= g;
 
    while((r.y > 0) or ((time > 0) and (nowTime <= time)))  //пока точка выше 0 или не достигла заданного времени
 
 
     {
 
     {
        Vector rn = 2 * r - rsb + a * dt * dt;  // r(t+dt) = 2*r(t)-r(t-dt)+a(t)*dt^2;
 
        v = (rn - rsb) / (2 * dt);  // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
 
        rsb = r;    //обновление r(t-dt) and r(t)
 
        r = rn;
 
        a = -windageLinearCoefficient * v;  //обновление a(t)
 
        a.y -= g;
 
        nowTime += dt;  //обновленное время
 
 
     }
 
     }
     return r;
+
      
}
+
// Конструктор
 
+
vec( double A, double B, double C ) : X(A), Y(B), Z(C)
Vector calculateForTime(Vector &v, double time)
 
{
 
    Vector r;
 
    // x = vx/k*(1-e^(-k*t));
 
    r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
 
    // y = ((vy+g/k)*(1-e^(-k*t))-g*t)/k;
 
    r.y = ((v.y + g / windageLinearCoefficient) * (1 - exp(-windageLinearCoefficient * time)) - g * time) / windageLinearCoefficient;
 
    return r;
 
}
 
 
 
Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
 
{
 
    if(windageLinearCoefficient < e) //если коэффициент слишком близок к нулю
 
        return getCoordinatesWithoutWindage(velocity, angle, time);  //вычисляй будто это 0
 
    Vector r;
 
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
 
    if(time >= 0)  //время данное
 
 
     {
 
     {
        r = calculateForTime(v, time);
 
        if(r.y >= 0)    //если объект в воздухе или только приземлился
 
            return r;  //затем верните координаты объекта
 
        else    //еще
 
            return getCoordinatesAccurateLinear(velocity, angle);  //верните координаты приземления
 
 
     }
 
     }
     else
+
      
 +
// Функции получения случайных чисел
 +
static double R0( void )
 
     {
 
     {
        double timer, timel, timem;
+
      return rand() / (double)RAND_MAX;
        timer = v.y / g;
+
    }
        timel = 0;
+
   
        while(calculateForTime(v, timer).y > 0) //смотрим на некоторые значения времени, которые больше времени посадки
+
static double R1( void )
            timer *= 1.5;
+
    {
        timem = timel + (timer - timel) / 2;
+
      return 2 * rand() / (double)RAND_MAX - 1;
        r = calculateForTime(v, timem);
 
        while(abs(r.y) > e)   //бинарный поиск времени посадки
 
        {
 
            if(r.y > 0)
 
                timel = timem;
 
            else
 
                timer = timem;
 
            timem = timel + (timer - timel) / 2;
 
            r = calculateForTime(v, timem);
 
        }
 
        return r;
 
 
     }
 
     }
}
+
      
 
+
// Функции получения случайных векторов
Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
+
static vec Rnd( void )
{
 
    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;
+
      return vec(R0(), R0(), R0());
        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;
+
      
}
+
static vec Rnd1( void )
 
 
void err(const char *s) //печатает сообщение об ошибке и завершает работу
 
{
 
    fputs(s, output);
 
    exit(1);
 
}
 
 
 
int main(int argc, const char *argv[])
 
{
 
    double velocity, angle;
 
    bool needRead = true;
 
    if(argc==3) //если даны 2 аргумента
 
 
     {
 
     {
        velocity = atof(argv[1]);  //истолкование его как скорости и угла
+
      return vec(R1(), R1(), R1());
        angle = atof(argv[2]);
 
        needRead = false;
 
 
     }
 
     }
    if(needRead)
+
 +
vec operator+( vec V )
 +
{
 +
return vec(X + V.X, Y + V.Y, Z + V.Z);
 +
}
 +
 +
vec operator*( double t )
 
     {
 
     {
        puts("Enter initial velocity (m/s)");
+
      return vec(X * t, Y * t, Z * t);
        scanf("%lf", &velocity);
 
 
     }
 
     }
     if(velocity < 0)    //проверка, если скорость меньше 0
+
      
        err("Initial velocity must be above 0");
+
vec & operator+=( const vec &V )
    if(needRead)
 
 
     {
 
     {
        puts("Enter initial angle (0-180 degrees)");
+
      X += V.X;
        scanf("%lf", &angle);
+
      Y += V.Y;
 +
      Z += V.Z;
 +
     
 +
return *this;
 
     }
 
     }
    if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
+
        err("Initial angle must be from 0 to 180");
+
// Длина вектора
    angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
+
double operator!(void) const
    output = fopen("Coordinates.txt", "w"); //открытие результативного файла
+
{
    //вычисление и печать 4 значений
+
return sqrt(X * X + Y * Y + Z * Z);
    printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
+
} /* end of 'operator!' function */
    printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
+
  }; // end of 'vec' class
    printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
+
} // end of 'sagl' namespace
    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 здесь]
 
  
 +
#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
 +
*/
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
#ifndef __SAMPLE_H_
 +
#define __SAMPLE_H_
  
 +
#include <math.h>
  
'''[[Сенников Иван]]'''
+
#include "ANIM.H"
  
'''Суть программы:'''Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.
+
// Шар, летящий без сопротивлением воздуха
 
+
class ball : public sagl::object
'''Идея:''' Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.
+
{
 
+
private:
'''Инструкция:''' Результаты программы будут записаны в соответствующий файл (подробности смотри в самой программе). Пользователю будет предоставлена возможность ввести начальную скорость и угол, под которым и бросают тело.
+
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
 
+
public:
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Throws_v2.0.zip здесь].
+
  // Конструктор
 
+
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;
  
Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут].
+
// Изменение вектора скорости
 +
V += g * Ani.DeltaTime;
 +
// Изменение вектора перемещения
 +
P += V * Ani.DeltaTime;
  
<div class="mw-collapsible-content">
+
// Ограничения - стенки
 +
if (P.X > Size / 4)
 +
V.X = -fabs(V.X);
 +
if (P.X < -Size / 4)
 +
V.X = fabs(V.X);
  
[[File:Обычный.png]]
+
if (P.Y > Size / 4)
[[File:Точный.png]]
+
V.Y = -fabs(V.Y);
[[File:Верле2.png]]
+
if (P.Y < -Size / 4)
[[File:Верле1.png]]
+
      V.Y = fabs(V.Y);
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
if (P.Z > Size / 4)
// Первый случай
+
V.Z = -fabs(V.Z);
 +
if (P.Z < -Size / 4)
 +
V.Z = fabs(V.Z);
 +
 +
    // Запоминание состояния изменения текущей СК
 +
glPushMatrix();
 +
 +
// Рисование стенок
 +
glutWireCube(Size / 2);
 +
// Задача перемещения мяча
 +
glTranslated(P.X, P.Y, P.Z);
 +
    // Цвет мяча
 +
glColor3d(0, 1, 0);
 +
// Рисование мяча
 +
glutSolidSphere(0.5, 30, 30);
 +
   
 +
// Восстановление последнего запоминания состояния изменения текущей СК
 +
glPopMatrix();
 +
  }
 +
}; // end of 'ball' class
  
#include <iostream>
+
// Шар, летящий с сопротивлением воздуха
#include <math.h>
+
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
#include <cstdlib>
+
class ball_air : public sagl::object
#include <fstream>
+
{
 
+
private:
/// Программа, анализирующая полет тела;
+
double angle, v, m, n;
 +
public:
 +
// Конструктор
 +
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Конструктор
 +
ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Отрисовка объекта
 +
void Render( sagl::anim &Ani )
 +
{
 +
// Вектор ускорения свободного падения и вектор полного ускорения
 +
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 +
// Размер комнаты
 +
double Size = 120;
 +
 
 +
// Изменение вектора ускорения
 +
a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
  
using namespace std;
+
// Изменение вектора скорости
double a,s,H,p1,p2,X,f;   /// Создание переменных, необходимых для работы:
+
V += a * Ani.DeltaTime;
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
+
// Изменение вектора перемещения
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
+
P += V * Ani.DeltaTime;
                                                                                /// H - координата тела по оси Oy;
+
 
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
+
// Ограничения - стенки
                                                                                /// X - координата тела по оси Oy;
+
if (P.X > Size / 4)
                                                                                /// f - шаг по времени;
+
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 main()
+
if (P.Z > Size / 4)
{
+
V.Z = -fabs(V.Z);
    cout << "Enter speed and angle and step of time" << endl;  /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
+
if (P.Z < -Size / 4)
    cin >> s >> a >> f;    /// Считывание данных, введенных пользователем, в переменные;
+
V.Z = fabs(V.Z);
    double t=s*sin(a*3.14159/180.0)/9.8;        /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
+
    for (double i=f; i<(2*t+f); i+=f)      /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
// Запоминание состояния изменения текущей СК
    {
+
glPushMatrix();
        p1=s*sin(a*3.14159/180)*i;     /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
        p2=4.9*i*i;        /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
// Рисование стенок
        H=double(p1)-p2;    /// Вычисление координаты тела по оси Oy;
+
glutWireCube(Size / 2);
        X=s*cos(a*3.14159/180)*i;      /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
// Задача перемещения мяча
        cerr << X << " ";      /// Вывод на экран значения по оси Ox
+
glTranslated(P.X, P.Y, P.Z);
        cerr << H << endl;      /// и по оси Oy;
+
// Цвет мяча
    }
+
glColor3d(1, 0, 0);
    ofstream out("zap.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
+
// Рисование мяча
    for (double i=0; i<(2*t+f); i+=f)        /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
+
glutSolidSphere(0.5, 30, 30);
    {
+
        p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
+
// Восстановление последнего запоминания состояния изменения текущей СК
        p2=4.9*i*i;            /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
+
glPopMatrix();
        H=double(p1)-p2;        /// Вычисление координаты тела по оси Oy;
+
}
        X=s*cos(a*3.14159/180)*i;      /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
+
}; // end of 'ball_air' class
        out << X << " ";        /// Запись в файл значения по оси Ox
 
        out << H << endl;      /// и по оси Oy;
 
    }
 
    out.close();       /// Закрываем файл, с которым работали в течение программы;
 
    return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
  
// Второй случай
+
// Шар, летящий с сопротивлением воздуха
 
+
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
#include <iostream>
+
class ball_air_2 : public sagl::object
#include <math.h>
+
{
#include <cstdlib>
+
private:
#include <fstream>
+
double angle, v, m, n;
 +
public:
 +
// Конструктор
 +
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Конструктор
 +
ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Отрисовка объекта
 +
void Render( sagl::anim &Ani )
 +
{
 +
// Вектор ускорения свободного падения и вектор полного ускорения
 +
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 +
// Размер комнаты
 +
double Size = 120;
  
/// Программа, позволяющая описать полет точки при помощи точного метода;
+
// Изменение вектора скорости
 +
V.Z = V.Z * exp(-n / m * Ani.DeltaTime);
 +
V.Y = (V.Y - g.Y * m / n) * exp(-n / m * Ani.DeltaTime) + g.Y * m / n;
 +
// Изменение вектора перемещения
 +
P += V * Ani.DeltaTime;
  
using namespace std;
+
// Ограничения - стенки
double v,a,st,m;    /// Создание переменных, необходимых для работы:
+
if (P.X > Size / 4)
                        /// v - модуль скорости, который задает сам пользователь;
+
V.X = -fabs(V.X);
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
if (P.X < -Size / 4)
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
V.X = fabs(V.X);
                        /// m - масса тела, задается пользователем;
+
 
double *V,*X, *Y, *U;   /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
if (P.Y > Size / 4)
                        /// V - массив, хранящий значения скорости по оси Ox;
+
V.Y = -fabs(V.Y);
                        /// X - массив, хранящий координаты точки по оси Ox;
+
if (P.Y < -Size / 4)
                        /// Y - массив, хранящий значения скорости по оси Oy;
+
V.Y = fabs(V.Y);
                        /// U - массив, хранящий координаты точки по оси Oy;
+
 
 +
if (P.Z > Size / 4)
 +
V.Z = -fabs(V.Z);
 +
if (P.Z < -Size / 4)
 +
V.Z = fabs(V.Z);
  
int main()
+
// Запоминание состояния изменения текущей СК
{
+
glPushMatrix();
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
 
    cin >> v >> a >> st >> m;          /// Считывание данных, введенных пользователей в переменные;
 
    double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
 
    int n=2*t/st;      /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 
    //int p=1/st;
 
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 
    X[0]=0;        /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 
    U[0]=v*sin(3.14159*a/180.0);        /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 
    Y[0]=0;        /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 
    for (int i=1; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
    {
 
        Y[i]=(m/0.001)*(U[0]+9.8*(m/0.001))*(1-exp(((0-0.001)/m)*i*st))-9.8*(m/0.001)*i*st;        /// Вычисление координаты тела в момент времени (i*st) по оси Oy по формуле, выведенной через дифференциальное уравнение точки для вертикальной оси и находящей координату как функцию от времени и координаты тела в предыдущей рассматриваемой нами точке;
 
        X[i]=V[0]*(m/0.001)*(1-exp(((0-0.001)/m)*i*st));          /// Аналогично вычисляем координаты тела в момент времени (i*st) по оси Ox как функцию от времени и координате в предыдущей рассматриваемой точке;
 
                                                                  /// В приведенных выше формулах зачение 0.001 - это коэффициент сопротивления воздуха;
 
                                                                  /// Движение по горизонтальной оси рассматривается как равномерное прямолинейное движение;
 
                                                                  /// Движение по вертикальной оси рассматривается как равноускоренное прямолинейное движение;
 
        cerr << X[i] << " " << Y[i] << endl;        /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        out << X[i] << " " << Y[i] << endl;        /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
    }
 
    out.close();        /// Закрываем файл, с которым работали в течение программы;
 
    return 0;          /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
  
 +
// Рисование стенок
 +
glutWireCube(Size / 2);
 +
// Задача перемещения мяча
 +
glTranslated(P.X, P.Y, P.Z);
 +
// Цвет мяча
 +
glColor3d(0, 1, 1);
 +
// Рисование мяча
 +
glutSolidSphere(0.5, 30, 30);
 +
 +
// Восстановление последнего запоминания состояния изменения текущей СК
 +
glPopMatrix();
 +
}
 +
}; // end of 'ball_air_2' class
  
}
+
// Шар, летящий с сопротивлением воздуха
 
+
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
// Третий случай
+
class ball_air_3 : public sagl::object
 +
{
 +
private:
 +
double angle, v, m, n;
 +
public:
 +
// Конструктор
 +
ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Конструктор
 +
ball_air_3( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 +
{
 +
P = sagl::vec(sagl::r0() + 5, 5, 0);
 +
V.X = 0;
 +
V.Y = sin(angle) * v;
 +
V.Z = cos(angle) * v;
 +
}
 +
 +
// Отрисовка объекта
 +
void Render( sagl::anim &Ani )
 +
{
 +
// Вектор ускорения свободного падения и вектор полного ускорения
 +
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 +
// Размер комнаты
 +
double Size = 120;
  
#include <iostream>
+
// Изменение вектора ускорения
#include <math.h>
+
a = sagl::vec(0, g.Y - n / m * V.Y, -n / m * V.Z);
#include <cstdlib>
 
#include <fstream>
 
  
/// Программа, анализирующая полет тела при помощи модифицированного метода Верле;
+
// Изменение вектора скорости
 +
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);
  
using namespace std;
+
if (P.Y > Size / 4)
double v,a,st,m,x,y;    /// Создание переменных, необходимых для работы;
+
V.Y = -fabs(V.Y);
                        /// v - модуль скорости, который задает сам пользователь;
+
if (P.Y < -Size / 4)
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
V.Y = fabs(V.Y);
                        /// 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()
+
if (P.Z > Size / 4)
{
+
V.Z = -fabs(V.Z);
    cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
if (P.Z < -Size / 4)
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователей в переменные;
+
V.Z = fabs(V.Z);
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
 
    int n=2*t/st;  /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 
    //int p=1/st;
 
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 
    X[0]=0;    /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 
    x=X[0]-V[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 
    X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st;  /// Вычисление координаты тела по оси Ox в момент времени t=1;
 
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 
    Y[0]=0;    /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 
    y=Y[0]-U[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
 
    Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st;      /// Вычисление координаты тела по оси Oу в момент времени t=1;
 
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
 
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 
    out << X[1] << " " << Y[1] << endl;    /// Записываем в файл полученные значения координат тела в момент времени t=1;
 
    int k=1;        /// Создаем целочисленную переменную k=1 для работы в цикле;
 
    //cerr<<"N "<<n<<"\n";
 
    for (int i=0; i<n; ++i)    /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 
                                /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 
    {
 
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st;    /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k])*st*st;      /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 
        U[k]=(Y[k+1]-Y[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 
        //cerr <<i<<" "<<k<<" "<<
 
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 
                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 
    }
 
    out.close();   /// Закрываем файл, с которым работали в течение программы;
 
    return 0;      /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
  
// Четвертый случай
+
// Запоминание состояния изменения текущей СК
 +
glPushMatrix();
  
#include <iostream>
+
// Рисование стенок
#include <math.h>
+
glutWireCube(Size / 2);
#include <cstdlib>
+
// Задача перемещения мяча
#include <fstream>
+
glTranslated(P.X, P.Y, P.Z);
 +
// Цвет мяча
 +
glColor3d(1, 0.5, 0);
 +
// Рисование мяча
 +
glutSolidSphere(0.5, 30, 30);
 +
 +
// Восстановление последнего запоминания состояния изменения текущей СК
 +
glPopMatrix();
 +
}
 +
}; // end of 'ball_air_3' class
  
/// Программа, анализирующая полет тела при помощи метода Верле;
+
#endif /*__SAMPLE_H_ */
  
using namespace std;
+
// END OF 'SAMPLE.H' FILE
double v,a,st,m,x,y;       /// Создание переменных, необходимых для работы:
+
</syntaxhighlight>
                            /// v - модуль скорости, который задает сам пользователь;
+
</div>
                            /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
+
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
                            /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
+
<br>
                            /// m - масса тела, задается пользователем;
+
 
                            /// x - координата тела по оси Ox в мнимый момент времени t=-1;
+
'''[[Рубинова Раиса]]'''
                            /// y - координата тела по оси Oy в мнимый момент времени t=-1;
+
 
double *V,*X, *Y, *U;      /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
+
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
                            /// V - массив, хранящий значения скорости по оси Ox;
+
#  Полет тела без сопротивления воздуха;
                            /// X - массив, хранящий координаты точки по оси Ox;
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
                            /// Y - массив, хранящий значения скорости по оси Oy;
+
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
                            /// U - массив, хранящий координаты точки по оси Oy;
+
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 +
 
 +
Скачать можно [http://tm.spbstu.ru/File:Полет.rar тут].
 +
 
 +
<div class="mw-collapsible-content">
 +
 
 +
[[File:Обычный.png]]
 +
[[File:Точный.png]]
 +
[[File:Верле2.png]]
 +
[[File:Верле1.png]]
 +
 
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
// Первый случай
 +
 
 +
#include <iostream>
 +
#include <math.h>
 +
#include <cstdlib>
 +
#include <fstream>
 +
 
 +
/// Программа, анализирующая полет тела;
 +
 
 +
using namespace std;
 +
double a,s,H,p1,p2,X,f;   /// Создание переменных, необходимых для работы:
 +
                                                                                /// a - угол к горизонту, под которым летит тело, вводится пользователем;
 +
                                                                                /// s - начальная скорость, с которой тело начинает лететь, вводится пользователем;
 +
                                                                                /// H - координата тела по оси Oy;
 +
                                                                                /// p1, p2 - промежуточные переменные, предназначенные для расчетов;
 +
                                                                                /// X - координата тела по оси Oy;
 +
                                                                                /// f - шаг по времени;
  
 
int main()
 
int main()
 
{
 
{
     cout << "Enter speed and angle and step of time and weight" << endl;       /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
+
     cout << "Enter speed and angle and step of time" << endl;   /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту и шаг по времени;
     cin >> v >> a >> st >> m;       /// Считывание данных, введенных пользователем, в переменные;
+
     cin >> s >> a >> f;     /// Считывание данных, введенных пользователем, в переменные;
     double t=(v/9.8)*sin(3.14159*a/180.0);     /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
+
     double t=s*sin(a*3.14159/180.0)/9.8;       /// Создание новой переменной t, хранящей значение времени полета тела вверх (вычисленное через уравнение скорости по оси Oy);
     int n=2*t/st;          /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
+
     for (double i=f; i<(2*t+f); i+=f)       /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
    //int p=1/st;
 
    V = new double [n+2];  /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 
    X = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 
    Y = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    U = new double [n+2];  /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 
    X[0]=0;                /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 
    x=X[0]-V[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 
    X[1]=2*X[0]-x-(0.01/m)*V[0]*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;
+
         p1=s*sin(a*3.14159/180)*i;     /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
         V[k]=(X[k+1]-X[k-1])/(2*st);       /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
+
         p2=4.9*i*i;         /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
         Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k]*U[k])*st*st;     /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
+
         H=double(p1)-p2;   /// Вычисление координаты тела по оси Oy;
         U[k]=(Y[k+1]-Y[k-1])/(2*st);   /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
+
         X=s*cos(a*3.14159/180)*i;       /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
         //cerr <<i<<" "<<k<<" "<<
+
         cerr << X << " ";      /// Вывод на экран значения по оси Ox
         cerr << X[k+1] << " " << Y[k+1] << endl;   /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
+
         cerr << H << endl;     /// и по оси Oy;
        out << X[k+1] << " " << Y[k+1] << endl;     /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
+
    }
         k=k+1;     /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
+
    ofstream out("zap.txt");       /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
+
    for (double i=0; i<(2*t+f); i+=f)        /// Для вычисления координат тела в n-ом количестве точек мы создаем цикл, который повторяется то количество раз, сколько раз шаг по времени, введенным пользователем, вмещается во время полета всего тела;
 +
    {
 +
        p1=s*sin(a*3.14159/180)*i;      /// Вычисление первой компоненты координаты тела по оси Oy, представляемй как произведение скорости по этой оси на время (выражено из уравнения равноускоренного прямолинейного движения);
 +
         p2=4.9*i*i;             /// Вычисление второй компоненты координаты тела по оси Oy, представляемой как произведение квадрата времени на половину укорения свободного падения (выражено из уравнения РУПД);
 +
        H=double(p1)-p2;        /// Вычисление координаты тела по оси Oy;
 +
        X=s*cos(a*3.14159/180)*i;      /// Вычисление координаты тела по оси Ox как произведение скорости по оси Ox на время (выражено из уравнения равномерного движения);
 +
        out << X << " ";        /// Запись в файл значения по оси Ox
 +
        out << H << endl;      /// и по оси Oy;
 
     }
 
     }
     out.close();   /// Закрываем файл, с которым работали в течение программы;
+
     out.close();       /// Закрываем файл, с которым работали в течение программы;
     return 0;       /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
+
     return 0;           /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 
}
 
}
  
</syntaxhighlight>
+
// Второй случай
</div>
 
  
 +
#include <iostream>
 +
#include <math.h>
 +
#include <cstdlib>
 +
#include <fstream>
  
'''[[Козловская Анна]]'''
+
/// Программа, позволяющая описать полет точки при помощи точного метода;
  
 +
using namespace std;
 +
double v,a,st,m;    /// Создание переменных, необходимых для работы:
 +
                        /// v - модуль скорости, который задает сам пользователь;
 +
                        /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
 +
                        /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
 +
                        /// m - масса тела, задается пользователем;
 +
double *V,*X, *Y, *U;  /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
 +
                        /// V - массив, хранящий значения скорости по оси Ox;
 +
                        /// X - массив, хранящий координаты точки по оси Ox;
 +
                        /// Y - массив, хранящий значения скорости по оси Oy;
 +
                        /// U - массив, хранящий координаты точки по оси Oy;
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
int main()
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
 
 
Скачать можно  [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
 
*/
 
 
 
#include "ANIM.H"
 
#include "SAMPLE.H"
 
 
 
/* Main function */
 
void main( void )
 
 
{
 
{
// Получение единственного экземпляра класса анимации
+
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
sagl::anim &My = sagl::anim::Get();
+
    cin >> v >> a >> st >> m;          /// Считывание данных, введенных пользователей в переменные;
 
+
    double t=(v/9.8)*sin(3.14159*a/180.0);          /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
// Шар, летящий без сопротивлением воздуха
+
    int n=2*t/st;      /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
         for (int i = 0; i < 1; i++)
+
    //int p=1/st;
                My << new ball(Pi / 6, 10 + i);
+
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 +
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 +
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    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>
  My.Run();
+
#include <math.h>
} // End of 'main' function
+
#include <cstdlib>
 +
#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
 
*/
 
  
#include <stdio.h>
+
using namespace std;
#include <stdlib.h>
+
double v,a,st,m,x,y;    /// Создание переменных, необходимых для работы;
#include <time.h>
+
                        /// 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;
  
#include "ANIM.H"
+
int main()
 
+
{
// Единственный экземпляр класса
+
    cout << "Enter speed and angle and step of time and weight" << endl;    /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
sagl::anim sagl::anim::Instance;
+
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователей в переменные;
 +
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
 +
    int n=2*t/st;  /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 +
    //int p=1/st;
 +
    V = new double [n+2];      /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
 +
    X = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
 +
    Y = new double [n+2];      /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    U = new double [n+2];      /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    V[0]=v*cos(3.14159*a/180.0);    /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 +
    X[0]=0;    /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 +
    x=X[0]-V[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 +
    X[1]=2*X[0]-x-(0.01/m)*V[0]*st*st;  /// Вычисление координаты тела по оси Ox в момент времени t=1;
 +
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 +
    Y[0]=0;    /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 +
    y=Y[0]-U[0]*st;    /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
 +
    Y[1]=2*Y[0]-y-(0.01/m)*U[0]*st*st;      /// Вычисление координаты тела по оси Oу в момент времени t=1;
 +
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
 +
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 +
    out << X[1] << " " << Y[1] << endl;    /// Записываем в файл полученные значения координат тела в момент времени t=1;
 +
    int k=1;        /// Создаем целочисленную переменную k=1 для работы в цикле;
 +
    //cerr<<"N "<<n<<"\n";
 +
    for (int i=0; i<n; ++i)    /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 +
                                /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 +
    {
 +
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*st*st;    /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k])*st*st;     /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        U[k]=(Y[k+1]-Y[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        //cerr <<i<<" "<<k<<" "<<
 +
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 +
                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 +
    }
 +
    out.close();    /// Закрываем файл, с которым работали в течение программы;
 +
    return 0;      /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 +
}
  
/* Reshape function */
+
// Четвертый случай
// Стандартная функция, вызываемая при изменении размеров окна
+
 
void sagl::anim::Reshape( int W, int H )
+
#include <iostream>
{
+
#include <math.h>
  // Установка области просмотра - все окно
+
#include <cstdlib>
glViewport(0, 0, W, H);
+
#include <fstream>
  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 */
+
using namespace std;
// Подсчет времени
+
double v,a,st,m,x,y;        /// Создание переменных, необходимых для работы:
void sagl::anim::Timer( void )
+
                            /// v - модуль скорости, который задает сам пользователь;
{
+
                            /// a - угол относительно горизонта, под которым летит тело, задается пользователем;
  long Time = clock();
+
                            /// st - шаг по времени, через который расчитываются координаты точек, задается пользователем;
 
+
                            /// m - масса тела, задается пользователем;
  if (IsPause)
+
                            /// x - координата тела по оси Ox в мнимый момент времени t=-1;
    DeltaTime = 0, PauseTime += Time - OldTime;
+
                            /// y - координата тела по оси Oy в мнимый момент времени t=-1;
  else
+
double *V,*X, *Y, *U;      /// Создание массивов, хранящих значения типа double, в которых хранятся значения:
    DeltaTime = (Time - OldTime) / (double)CLOCKS_PER_SEC;  
+
                            /// V - массив, хранящий значения скорости по оси Ox;
  OldTime = Time;
+
                            /// X - массив, хранящий координаты точки по оси Ox;
 +
                            /// Y - массив, хранящий значения скорости по оси Oy;
 +
                            /// U - массив, хранящий координаты точки по оси Oy;
  
  SyncTime = (Time - PauseTime - StartTime) / (double)CLOCKS_PER_SEC;
+
int main()
} /* End of 'Timer' function */
 
 
 
/* Display function */
 
// Стандартная функция, вызываемая при перерисовке окна
 
void sagl::anim::Display( void )
 
 
{
 
{
// Запуск времени
+
    cout << "Enter speed and angle and step of time and weight" << endl;        /// Обращение к пользователю, где требуется ввести скорость тела, угол к горизонту, шаг по времени и массу тела;
Instance.Timer();
+
    cin >> v >> a >> st >> m;      /// Считывание данных, введенных пользователем, в переменные;
// Очищаем цветовой буфер для создания нового изображения
+
    double t=(v/9.8)*sin(3.14159*a/180.0);      /// Создание новой переменной t, хранящей значение времени всего полета тела, вычисленного, как два времени взлета (через уравнение скорости по оси Oy);
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
    int n=2*t/st;          /// Создание новой целочисленной переменной, которая равна времени полета тела (преобразование типов для переменной t) деленного на шаг, которая будет использоваться при создании массивов для размера;
 
+
    //int p=1/st;
   glLoadIdentity();
+
    V = new double [n+2];   /// Создание динамического массива V, предназначенного для хранения значений скорости по оси Ox, размером (n+2) (n показывает, сколько раз шаг по времени помещается во все время, то есть, сколько точек мы будем рассматривать, анализируя полет точки);
  // Позиционирование СК
+
    X = new double [n+2];  /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Ox и имеющего схожие характеристики с массивом V;
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
+
    Y = new double [n+2];   /// Создание динамического массива X, предназначенного для хранения координаты тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    U = new double [n+2];  /// Создание динамического массива U, предназначенного для хранения значений скорости тела по оси Oy и имеющего схожие характеристики с массивом V;
 +
    V[0]=v*cos(3.14159*a/180.0);        /// Вычисление значения скорости по оси Ox в начальный момент времени, как состовляющая модуля скорости, заданного пользователем;
 +
    X[0]=0;                /// Задание координаты точки по оси Ox в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому x=0;
 +
    x=X[0]-V[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Ox;
 +
    X[1]=2*X[0]-x-(0.01/m)*V[0]*V[0]/cos(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Ox в момент времени t=1;
 +
    U[0]=v*sin(3.14159*a/180.0);    /// Вычисление значения скорости по оси Oy в начальный момент времени, как компонента модуля скорости, заданного пользователем, по вертикальной оси;
 +
    Y[0]=0;                /// Задание координаты точки по оси Oy в начальный момент времени. Мы рассматриваем движение тела под углом к горизонту из начала координат, поэтому y=0;
 +
    y=Y[0]-U[0]*st;        /// Суть данного метода заключается в том, что мы находим значение параметров тела по предыдущим двум состояниям, поэтому нам нужно вычислить мнимые координаты тела в -1 момент времени. Это расчет коордлинаты по оси Oу;
 +
    Y[1]=2*Y[0]-y-(0.01/m)*U[0]*U[0]/sin(3.14159*a/180.0)*st*st;    /// Вычисление координаты тела по оси Oу в момент времени t=1;
 +
    cerr << X[1] << " " << Y[1] << endl;    /// Вывод на экран значений координат по обеим осям в момент времени t=1;
 +
    ofstream out("Res.txt");        /// Так как результаты анализа не только выводятся на экран, но и записываются в файл, мы создаем переменную, соответствующую файлу "Res.txt", находящемуся в папке с программой, и открываем файл для записи;
 +
    out << X[1] << " " << Y[1] << endl;        /// Записываем в файл полученные значения координат тела в момент времени t=1;
 +
    int k=1;            /// Создаем целочисленную переменную k=1 для работы в цикле;
 +
    //cerr<<"N "<<n<<"\n";
 +
    for (int i=0; i<n; ++i)        /// Для вычисления координат тела в пространстве в зависимости от времени мы создаем цикл, который позволяет, использая общую формулу нахождкения координат и компонент скорости, вычислять эти значения
 +
                                    /// Цикл повторяется (n-1) раз, так как значения в начальный момент времени были найдены отдельно от цикла, и повторяется столько раз, сколько точек траектории мы рассматриваем;
 +
    {
 +
        X[k+1]=2.0*X[k]-X[k-1]-(0.001/m)*V[k]*V[k]*st*st;      /// Нахождение координаты тела по оси Ox в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        V[k]=(X[k+1]-X[k-1])/(2*st);        /// Нахождение значения скорости тела по оси Ox в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        Y[k+1]=2.0*Y[k]-Y[k-1]-(9.8+(0.001/m)*U[k]*U[k])*st*st;    /// Нахождение координаты тела по оси Oy в момент времени t, основываясь на известных параметрах за моменты времени t-1 и t-2;
 +
        U[k]=(Y[k+1]-Y[k-1])/(2*st);    /// Нахождение значения скорости тела по оси Oy в момент времени t-1, основываясь на рассчитанных выше координатах тела по оси Ox длямоментов времени t и t-2;
 +
        //cerr <<i<<" "<<k<<" "<<
 +
        cerr << X[k+1] << " " << Y[k+1] << endl;    /// Выведение рассчитанных значений на экран в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        out << X[k+1] << " " << Y[k+1] << endl;    /// Запись рассчитанных значений в файл "Res.txt" в виде строки, где первым идет координата по оси Ox, вторым - по оси Oy;
 +
        k=k+1;      /// Увеличиваем число k на единицу, чтобы в следующем шаге цикла рассчитать значения для следующего момента времени;
 +
                                                    /// Таким образом, в результате работы программы мы получаем два столбика значений для координат по обеим осям, которые как записаны в файл, так и выведены на экран;
 +
    }
 +
    out.close();    /// Закрываем файл, с которым работали в течение программы;
 +
    return 0;      /// По умолчанию возвращаем функции int main значение 0, тем самым завершая программу;
 +
}
  
// Отрисовка объектов
+
</syntaxhighlight>
  Instance.Render();
+
</div>
 +
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Савельева Ольга]]'''
  
  glFinish();
+
'''Описание:''' Пользователя попросят ввести начальную скорость, угол бросания, тогда программа запишет в файл результаты следующих вычислений:
// Копируем вторичный буфер в окно
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
glutSwapBuffers();
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
// Вызываем функцию обновления кадра
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
glutPostRedisplay();
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
} // End of 'Display' function
 
  
/* Keyboard function */
+
<div class="mw-collapsible-content">
// Стандартная функция, вызываемая при нажатие клавиш на клавиатуре
 
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),
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  StartTime(clock()), OldTime(StartTime), PauseTime(0), StockSize(0)
+
#include <stdio.h>
{
+
#include <stdlib.h>
// Инициализации OpenGL и GLUT
+
#include <cmath>
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+
 
 
+
using namespace std;
// Задача размеров и позиции окна
 
glutInitWindowPosition(0, 0);
 
  glutInitWindowSize(700, 700);
 
// Создание окна
 
glutCreateWindow("T06BALL");
 
  
// Установка функций 'обратного вызова'
+
FILE *output;
  glutDisplayFunc(Display);
 
  glutKeyboardFunc(Keyboard);
 
  glutReshapeFunc(Reshape);
 
  
// Установка цвета закраски фона
+
double e = 0.0000001; //точность
  glClearColor(0.3, 0.5, 0.7, 1);
+
double g = 9.8; //ускорение свободного падения
  // Включение буфера глубины
+
double dt = 0.00001;  //шаг по времени
glEnable(GL_DEPTH_TEST);
+
double windageLinearCoefficient = 0.1;
  // Включение режима вычисления цвета согласно освещенности от источников света
+
double windageSquareCoefficient = 0.00001;
glEnable(GL_LIGHTING);
 
// Включение источника света
 
   glEnable(GL_LIGHT0);
 
// Включение упрощенного режима освещенности для простого способа описания свойств поверхности
 
  glEnable(GL_COLOR_MATERIAL);
 
// Приведение нормалей к единичной длине
 
  glEnable(GL_NORMALIZE);
 
}
 
  
// Деструктор
+
struct Vector  //вектор
sagl::anim::~anim( void )
 
 
{
 
{
  // Чистка памяти
+
    double x, y;
for (int i = 0; i < StockSize; i++)
+
    Vector():x(0), y(0)
     delete Stock[i];
+
    {}
 +
    Vector(double x, double y):x(x), y(y)
 +
    {}
 +
    const Vector operator+(const Vector &v) const
 +
    {
 +
        return Vector(this -> x + v.x, this -> y + v.y);
 +
    }
 +
    const Vector operator-(const Vector &v) const
 +
    {
 +
        return Vector(this -> x - v.x, this -> y - v.y);
 +
    }
 +
    const Vector operator*(const double k) const
 +
    {
 +
        return Vector(this -> x * k, this -> y * k);
 +
    }
 +
    const Vector operator*(const int k) const
 +
    {
 +
        return Vector(this -> x * k, this -> y * k);
 +
    }
 +
    const Vector operator/(const double k) const
 +
    {
 +
        return Vector(this -> x / k, this -> y / k);
 +
    }
 +
};
 +
 
 +
const Vector operator*(const double a, const Vector &v)
 +
{
 +
     return Vector(v.x * a, v.y * a);
 
}
 
}
  
/* Render function */
+
const Vector operator*(const int k, const Vector &v)
// Отрисовка объектов
 
void sagl::anim::Render( void )
 
 
{
 
{
for (int i = 0; i < StockSize; i++)
+
    return Vector(v.x * k, v.y * k);
Stock[i]->Render(*this);
+
}
} // End of 'Render' function
 
  
/* Run function */
+
double abs(const Vector &v)
// Запуск главного цикла
 
void sagl::anim::Run( void )
 
 
{
 
{
// Запуск основного цикла построения
+
    return sqrt(v.x * v.x + v.y * v.y);
glutMainLoop();
+
}
} // End of 'Run' function
 
  
// END OF 'ANIM.CPP' FILE
+
void printCoordinate(const char *description, const Vector &v)  //выводит координаты в более читаемом виде
</syntaxhighlight>
+
{
"'''ANIM.H'''"
+
    fputs(description, output);
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    fputs(": ", output);
/* FILENAME: ANIM.H
+
    fprintf(output, "%lf", v.x);
* LAST UPDATE: 17.01.2016
+
    fputs(", ", output);
*/
+
    fprintf(output, "%lf\n", v.y);
 +
}
  
#ifndef __ANIM_H_
+
Vector getCoordinatesWithoutWindage(double velocity, double angle, double time = -1)
#define __ANIM_H_
+
{
 
+
    double fallTime = 2 * velocity * sin(angle) / g;  //расчет времени падения
#include <stdio.h>
+
    if((time < 0) or (time > fallTime))
#include <stdlib.h>
+
        time = fallTime;
#include <time.h>
+
    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 <GL\glut.h>
+
Vector getCoordinatesVerletLinear(double velocity, double angle, double time = -1)
 
 
#include "VEC.H"
 
 
 
// Константы
 
#define Pi 3.14159265358979323846
 
#define E 2.71828182845904523536
 
 
 
// Собственное пространство имен 'sagl'
 
namespace sagl
 
 
{
 
{
  // Объявления класса анимации наперед
+
    double nowTime = dt;
class anim;
+
    Vector rsb(0, 0);
 
+
     if((time >= 0) and (dt / 2 - time > 0)) //если время расчета дается слишком малого промежутка
// Функции получения случайных чисел
+
        return rsb; //вернитесь в начальную точку
inline double r0( void )
+
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
  {
+
    Vector r = v * dt;    //вторая точка
     return rand() / (double)RAND_MAX;
+
     Vector a = -windageLinearCoefficient * v; //ускорение в начальной точке
  }
+
    a.y -= g;
  inline double r1( void )
+
    v = v + a * dt; //скорость во второй точке
  {
+
    a = -windageLinearCoefficient * v; //ускорение во второй точке
     return 2.0 * rand() / RAND_MAX - 1;
+
    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;
class object
+
        v = (rn - rsb) / (2 * dt);  // v(t) = (r(t+dt)-r(t-dt))/(2*dt);
  {
+
        rsb = r;    //обновление r(t-dt) and r(t)
  public:
+
        r = rn;
     // Вектора перемещения и скоростей
+
        a = -windageLinearCoefficient * v;  //обновление a(t)
vec P, V, AbsV;
+
        a.y -= g;
      
+
        nowTime += dt;  //обновленное время
// Конструктор
 
object( void ) : P(vec::Rnd1()), V(vec::Rnd()), AbsV(V)
 
    {
 
 
     }
 
     }
+
    return r;
// Отрисовка объектов
+
}
virtual void Render( anim &Ani )
+
 
     {
+
Vector calculateForTime(Vector &v, double time)
     } // End of 'Render' function
+
{
  }; // end of 'object' class
+
     Vector r;
 
+
     // x = vx/k*(1-e^(-k*t));
// Класс анимации
+
    r.x = v.x / windageLinearCoefficient * (1 - exp(-windageLinearCoefficient * time));
class anim
+
     // y = ((vy+g/k)*(1-e^(-k*t))-g*t)/k;
  {
+
     r.y = ((v.y + g / windageLinearCoefficient) * (1 - exp(-windageLinearCoefficient * time)) - g * time) / windageLinearCoefficient;
  private:
+
     return r;
     // Функции 'обратного вызова'
+
}
static void Display( void );
 
     static void Keyboard( unsigned char Key, int X, int Y );
 
     static void Reshape( int W, int H );
 
  
    // Единственный экземпляр класса
+
Vector getCoordinatesAccurateLinear(double velocity, double angle, double time = -1)
static anim Instance;
+
{
   
+
     if(windageLinearCoefficient < e)  //если коэффициент слишком близок к нулю
     // Конструктор
+
        return getCoordinatesWithoutWindage(velocity, angle, time);   //вычисляй будто это 0
anim( void );
+
     Vector r;
 
+
     Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
// Максимальное количество объектов
+
     if(time >= 0)  //время данное
     static const int Max = 100;
+
     {
     // 'Контейнер' объектов
+
        r = calculateForTime(v, time);
object *Stock[Max];
+
        if(r.y >= 0)    //если объект в воздухе или только приземлился
    // Размер 'контейнера' объектов
+
            return r;   //затем верните координаты объекта
int StockSize;
+
        else    //еще
      
+
            return getCoordinatesAccurateLinear(velocity, angle);  //верните координаты приземления
// Переменные, хранящие время в секундах
+
     }
     long StartTime, OldTime, PauseTime;
+
    else
   
 
// Отрисовка объектов
 
void Render( void );
 
 
// Подсчет времени
 
void Timer( void );
 
   public:
 
     // Добавление объектов в 'контейнер'
 
anim & operator<<( object *Obj )
 
 
     {
 
     {
      if (StockSize < Max )
+
        double timer, timel, timem;
         Stock[StockSize++] = Obj;
+
         timer = v.y / g;
      else
+
         timel = 0;
         delete Obj;
+
        while(calculateForTime(v, timer).y > 0) //смотрим на некоторые значения времени, которые больше времени посадки
     
+
            timer *= 1.5;
return *this;
+
        timem = timel + (timer - timel) / 2;
    }
+
        r = calculateForTime(v, timem);
   
+
        while(abs(r.y) > e)    //бинарный поиск времени посадки
// Ширина и высота окна
+
        {
    int WinW, WinH;
+
            if(r.y > 0)
 
+
                timel = timem;
// Переменные, хранящие время в секундах
+
            else
    double SyncTime, DeltaTime;
+
                timer = timem;
 
+
            timem = timel + (timer - timel) / 2;
    // Переменная, отвечающая за паузу
+
            r = calculateForTime(v, timem);
bool IsPause;
+
        }
 
+
        return r;
    // Деструктор
 
~anim( void );
 
   
 
// Запуск главного цикла
 
void Run( void );
 
   
 
    // Метод, возвращающий переменную - единственный экземпляр данного типа
 
static anim & Get( void )
 
    {
 
      return Instance;
 
 
     }
 
     }
  }; // end of 'anim' class
+
}
} // end of 'sagl' namespace
 
  
#endif /*__ANIM_H_ */
+
Vector getCoordinatesVerletSquare(double velocity, double angle, double time = -1)
 
+
{
// END OF 'ANIM.H' FILE
+
    double nowTime = dt;
</syntaxhighlight>
+
    Vector rsb(0, 0);
"'''VEC.H'''"
+
    if((dt / 2 - time > 0)and(time >= 0))  //если время слишком малое для рсчета
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
        return rsb; //вернитесь в начальную точку
/* FILENAME: VEC.H
+
    Vector v(velocity * cos(angle), velocity * sin(angle)); //проекции начальной скорости
* LAST UPDATE: 17.01.2016
+
    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;
 +
}
  
#ifndef __VEC_H_
+
void err(const char *s) //печатает сообщение об ошибке и завершает работу
#define __VEC_H_
+
{
 +
    fputs(s, output);
 +
    exit(1);
 +
}
  
#include <stdlib.h>
+
int main(int argc, const char *argv[])
#include <math.h>
 
 
 
// Собственное пространство имен 'sagl'
 
namespace sagl
 
 
{
 
{
  // Класс векторов
+
     double velocity, angle;
class vec
+
     bool needRead = true;
  {
+
    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");
static double R0( void )
+
    if(needRead)
 
     {
 
     {
      return rand() / (double)RAND_MAX;
+
        puts("Enter initial angle (0-180 degrees)");
 +
        scanf("%lf", &angle);
 
     }
 
     }
      
+
     if((angle < 0) or (angle > 180))    //проверка, что угол в нужном интервале
static double R1( void )
+
        err("Initial angle must be from 0 to 180");
    {
+
     angle = angle / 180 * M_PI; // a = a/180*pi; преобразование угла из градусов в радианы
      return 2 * rand() / (double)RAND_MAX - 1;
+
    output = fopen("Coordinates.txt", "w"); //открытие результативного файла
     }
+
     //вычисление и печать 4 значений
   
+
    printCoordinate("Without windage", getCoordinatesWithoutWindage(velocity, angle));
// Функции получения случайных векторов
+
     printCoordinate("Verlet, linear dependence", getCoordinatesVerletLinear(velocity, angle));
static vec Rnd( void )
+
     printCoordinate("Accurate, linear dependence", getCoordinatesAccurateLinear(velocity, angle));
     {
+
     printCoordinate("Verlet, square dependence", getCoordinatesVerletSquare(velocity, angle));
      return vec(R0(), R0(), R0());
+
    fclose(output); //закрытие файла
     }
+
     return 0;
   
+
}
static vec Rnd1( void )
+
</syntaxhighlight>
     {
+
</div>
      return vec(R1(), R1(), R1());
+
Скачать можно [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:%D0%9A%D0%BE%D0%BE%D1%80%D0%B4%D0%B8%D0%BD%D0%B0%D1%82%D1%8B.zip здесь]
     }
+
 
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
vec operator+( vec V )
+
 
{
+
 
return vec(X + V.X, Y + V.Y, Z + V.Z);
+
'''[[Сенников Иван]]'''
}
+
 
+
'''Суть программы:'''Программа позволяет отслеживать траекторию движения тела, брошенного под углом к горизонту, в каждом из четырех случаев/методов.
vec operator*( double t )
+
 
     {
+
'''Идея:''' Программа состоит из четырех методов: 1) движение тела без учета сопротивления воздуха; 2) движение тела с учетом сопротивления воздуха по первому методу Верле; 3) движение тела с учетом сопротивления воздуха по точному методу; 4) движение тела с учетом сопротивления воздуха по второму методу Верле.
      return vec(X * t, Y * t, Z * t);
 
    }
 
   
 
vec & operator+=( const vec &V )
 
    {
 
      X += V.X;
 
      Y += V.Y;
 
      Z += V.Z;
 
     
 
return *this;
 
    }
 
 
// Длина вектора
 
double operator!(void) const
 
{
 
return sqrt(X * X + Y * Y + Z * Z);
 
} /* end of 'operator!' function */
 
  }; // end of 'vec' class
 
} // end of 'sagl' namespace
 
  
#endif /*__VEC_H_ */
+
'''Инструкция:''' Результаты программы будут записаны в соответствующий файл (подробности смотри в самой программе). Пользователю будет предоставлена возможность ввести начальную скорость и угол, под которым и бросают тело.
  
// END OF 'VEC.H' FILE
+
Ссылка для скачиваний: [http://tm.spbstu.ru/Файл:Throws_v2.0.zip здесь].
</syntaxhighlight>
 
"'''SAMPLE.H'''"
 
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 
/* FILENAME: SAMPLE.H
 
* LAST UPDATE: 17.01.2016
 
*/
 
  
#ifndef __SAMPLE_H_
+
</div>
#define __SAMPLE_H_
+
 
 +
<div class="mw-collapsible mw-collapsed" style="width:100%" >
 +
'''[[Степанянц Степан]]'''
 +
 
 +
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
 +
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 +
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 +
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 +
 
 +
Скачать можно  [http://tm.spbstu.ru/%D0%A4%D0%B0%D0%B9%D0%BB:Mainpr.rar тут].
 +
 
 +
<div class="mw-collapsible-content">
 +
[[File:graph239.png]]
 +
 
 +
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 30°, начальная скорость 40 м/с, ускорение свободного падения 9.8 м/c^2;
  
#include <math.h>
 
  
#include "ANIM.H"
 
  
// Шар, летящий без сопротивлением воздуха
+
Файл "'''main.cpp'''"
class ball : public sagl::object
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
 +
#include <locale.h>
 +
#include <math.h>
 +
#include <fstream>
 +
#include<iomanip>
 +
#include <cmath>
 +
using namespace std;
 +
main ()
 
{
 
{
private:
+
    ofstream F;                                                                    //a1-угол в градусах,dt-шаг,r-сопротивление воздуха
  double angle, v; // угол вектора скорости к горизонту; модуль скорости
+
int u0=50;
public:
+
double x,y,t,a,a1=30,dt=0.1,y0=0,x0=0,g=9.8,r=0.05,m=1,ux,uy,ypr,xpr,ysl,xsl,u,yt; //ux,uy - проэкции скорости на оси х и у.
  // Конструктор
+
a=a1*M_PI/180; //Градусы в радианы
ball( void ) : angle(Pi / 3), v(1)
+
t=0;
  {
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
                                        //Движение без сопротивления воздуха
V.X = 0;
+
F.open("C:\\1.txt",ios::out);
V.Y = sin(angle) * v;
+
while(y>=0)
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;
ball( double angle1, double v1 ) : angle(angle1), v(v1)
+
  t=t+dt;
{
+
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
}
V.X = 0;
+
V.Y = sin(angle) * v;
+
F.close();
V.Z = cos(angle) * v;
+
                                        //Точное решение для линейной зависимости
}
+
F.open("C:\\2.txt",ios::out);
 
+
y=y0;
// Отрисовка объекта
+
x=x0;
void Render( sagl::anim &Ani )
+
t=0;                                                                            //Расчитываем координаты в каждой точке через шаг
  {
+
while(y>=0)
// Вектор ускорения свободного падения
+
{
sagl::vec g = sagl::vec(0, -9.8, 0);
+
        ux = u0 * cos(a);
// Размер комнаты
+
        uy = u0 * sin(a);
double Size = 120;
+
        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;
V += g * Ani.DeltaTime;
+
// Изменение вектора перемещения
+
      F << x << ' ' << y << endl;
P += V * Ani.DeltaTime;
+
 
+
// Ограничения - стенки
+
if (P.X > Size / 4)
+
}
V.X = -fabs(V.X);
+
  F.close();
if (P.X < -Size / 4)
+
                                                        //метод Верле 1
V.X = fabs(V.X);
+
ypr = y0 - u0*sin(a)*dt;
 
+
yt=ypr;
if (P.Y > Size / 4)
+
    xpr = x0 - u0*cos(a)*dt;
V.Y = -fabs(V.Y);
+
    x = x0;                          //Начальные условия
if (P.Y < -Size / 4)
+
    y = y0;
      V.Y = fabs(V.Y);
+
    u = u0;
 
+
    ux = u0 * cos(a);
if (P.Z > Size / 4)
+
    uy = u0 * sin(a);                      
V.Z = -fabs(V.Z);
+
F.open("C:\\3.txt",ios::out);
if (P.Z < -Size / 4)
+
V.Z = fabs(V.Z);
+
    while (y >= y0)
+
    {
     // Запоминание состояния изменения текущей СК
+
        xsl = 2 * x - xpr - (r / m) * u * ux * (dt * dt);
glPushMatrix();
+
        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);
glutWireCube(Size / 2);
+
        u = sqrt(uy*uy + ux*ux );
// Задача перемещения мяча
+
        F << x << ' ' << y << endl;
glTranslated(P.X, P.Y, P.Z);
+
     // Цвет мяча
+
        xpr = x;
glColor3d(0, 1, 0);
+
        x = xsl;
// Рисование мяча
+
        ypr = y;
glutSolidSphere(0.5, 30, 30);
+
        y = ysl;
      
+
     }
// Восстановление последнего запоминания состояния изменения текущей СК
+
    F.close();
glPopMatrix();
+
                                                      //Метод Верле 2
  }
+
    ypr = y0 - u0*sin(a)*dt;
}; // end of 'ball' class
+
yt=ypr;
 
+
    xpr = x0 - u0*cos(a)*dt;
// Шар, летящий с сопротивлением воздуха
+
     x = x0;                                                                            //xsl,ysl - координаты на шаге вперед. xpr,ypr- назад
// Координаты получены методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
+
    y = y0;
class ball_air : public sagl::object
+
    u = u0;
{
+
    ux = u0 * cos(a);                            
private:
+
     uy = u0 * sin(a);
double angle, v, m, n;
+
F.open("C:\\4.txt",ios::out);
public:
+
// Конструктор
+
    while (y >= y0)
ball_air( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    {
{
+
        xsl = 2 * x - xpr - (r / m) * ux * (dt * dt);
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
        ux = ( xsl - xpr )/ (2 * dt);
V.X = 0;
+
        ysl = 2 * y - ypr - (g + (r / m) * uy) * (dt * dt);
V.Y = sin(angle) * v;
+
        uy = (ysl - ypr)/ (2 * dt);
V.Z = cos(angle) * v;
+
        u = sqrt(uy*uy + ux*ux );
}
+
        F << x << ' ' << y << endl;
+
// Конструктор
+
        xpr = x;
ball_air( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
+
        x = xsl;
{
+
        ypr = y;
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
        y = ysl;
V.X = 0;
+
    }
V.Y = sin(angle) * v;
+
    F.close();
V.Z = cos(angle) * v;
+
}
+
+
return 0;
// Отрисовка объекта
+
void Render( sagl::anim &Ani )
+
{
+
}
// Вектор ускорения свободного падения и вектор полного ускорения
 
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 
// Размер комнаты
 
double Size = 120;
 
  
// Изменение вектора ускорения
+
</syntaxhighlight>
a = sagl::vec(0, g.Y - n / m * !V * V.Y, -n / m * !V * V.Z);
+
</div>
  
// Изменение вектора скорости
 
V += a * Ani.DeltaTime;
 
// Изменение вектора перемещения
 
P += V * Ani.DeltaTime;
 
  
// Ограничения - стенки
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
if (P.X > Size / 4)
+
'''[[Александр Сюрис]]'''
V.X = -fabs(V.X);
+
 
if (P.X < -Size / 4)
+
'''Описание программы''':
V.X = fabs(V.X);
+
Программа записывает в текстовый файл результаты вычисления координат по x и y с шагом в 0.1 секунду(возможно изменить) четырьмя различными способами:
 +
#Координаты, рассчитанные по формуле, при движении без сопротивления воздуха
 +
#Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении          воздуха от скорости
 +
#Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 +
#Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости
 +
Скачать можно  [http://mech.spbstu.ru/File:%D0%9F%D0%BE%D0%BB%D0%B5%D1%82_%D1%82%D0%B5%D0%BB%D0%B0(%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%A1%D1%8E%D1%80%D0%B8%D1%81).zip тут].
 +
<div class="mw-collapsible-content">
 +
[[File:Снимок.PNG]]
 +
Для тела с массой 1,сопротивлением воздуха 0.05, угол бросания 45°, начальная скорость 30 м/с, ускорение свободного падения 9.8 м/c^2;
 +
Файл "'''main.cpp'''"
 +
<syntaxhighlight lang="cpp" line start="1" enclose="div">
 +
#include <iostream>
 +
#include <fstream>
 +
#include <math.h>
 +
#include <cmath>
 +
using namespace std;
 +
int o;
 +
double v,a,m,k;
 +
ofstream fout("file.txt");//создаем объект, сяванный с файлом file.txt
 +
 
  
if (P.Y > Size / 4)
 
V.Y = -fabs(V.Y);
 
if (P.Y < -Size / 4)
 
V.Y = fabs(V.Y);
 
 
if (P.Z > Size / 4)
 
V.Z = -fabs(V.Z);
 
if (P.Z < -Size / 4)
 
V.Z = fabs(V.Z);
 
 
// Запоминание состояния изменения текущей СК
 
glPushMatrix();
 
 
// Рисование стенок
 
glutWireCube(Size / 2);
 
// Задача перемещения мяча
 
glTranslated(P.X, P.Y, P.Z);
 
// Цвет мяча
 
glColor3d(1, 0, 0);
 
// Рисование мяча
 
glutSolidSphere(0.5, 30, 30);
 
 
// Восстановление последнего запоминания состояния изменения текущей СК
 
glPopMatrix();
 
}
 
}; // end of 'ball_air' class
 
  
// Шар, летящий с сопротивлением воздуха
+
int rez_1(double v, double a)
// Координаты получены из точного решения при линейной зависимости силы сопротивлении воздуха от скорости
 
class ball_air_2 : public sagl::object
 
 
{
 
{
private:
+
    fout<<"---------------Первый режим-------------------------"<<endl;
double angle, v, m, n;
+
    fout<<" T=0 x=0 y=0";
public:
+
    fout<<endl;
// Конструктор
+
    double x=0,y=0,t=0.1, V0x, V0y, g=9.8,t1, T=0.1, Ty;
ball_air_2( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    V0x=v*cos(a/180*M_PI);//рассчет проекций начальных скоростей на оси x и y с переводом угла в радианы
{
+
    V0y=v*sin(a/180*M_PI);
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    Ty=2*V0y/g;//время полета
V.X = 0;
+
    while (y>0 || x==0)//условие: пока тело не упадет на землю(те y=0, при этом не учитывая начало полета
V.Y = sin(angle) * v;
+
    {
V.Z = cos(angle) * v;
+
        x=x+V0x*t;              //ф-лы для рассчета x и y в данный момент времени
}
+
        y=y+V0y*t-g*pow(t,2)/2;
 
// Конструктор
 
ball_air_2( double angle1, double v1, double m1, double n1 ) : angle(angle1), v(v1), m(m1), n(n1)
 
{
 
P = sagl::vec(sagl::r0() + 5, 5, 0);
 
V.X = 0;
 
V.Y = sin(angle) * v;
 
V.Z = cos(angle) * v;
 
}
 
 
// Отрисовка объекта
 
void Render( sagl::anim &Ani )
 
{
 
// Вектор ускорения свободного падения и вектор полного ускорения
 
sagl::vec g = sagl::vec(0, -9.8, 0), a;
 
// Размер комнаты
 
double Size = 120;
 
  
// Изменение вектора скорости
+
        if (y<0) //если y<0
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;
+
                t1=Ty-T; //рассчитываем время,которое осталось лететь телу до земли
// Изменение вектора перемещения
+
                x=x+V0x*t1;//используя это время находим координату по х
P += V * Ani.DeltaTime;
+
                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;//увел время на шаг
 +
                }
 +
    }
  
// Ограничения - стенки
 
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)
 +
{
 +
    fout<<"---------------Второй режим работы-------------------------"<<endl;
 +
    fout<<" T=0 x=0 y=0";
 +
    fout<<endl;
 +
    double t=0.1, Vx=v*cos(a/180*M_PI), Vy=v*sin(a/180*M_PI),y,x,T=0.1,g=9.8;
 +
    x=(m*Vx/k)*(1-exp(-1*k*T/m));            //ф-лы для рассчета x и y в данный момент времени
 +
    y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T); //точное решение при лин завсисимости
 +
    while (y>0)
 +
    {
 +
        x=(m*Vx/k)*(1-exp(-1*k*T/m));
 +
        y =(m/k)*((Vy+g*m/k)*(1-exp(-1*k*T/m))-g*T);
 +
        fout<<" T="<<T<<" x="<<x<<" y="<<y<<endl;
 +
        T=T+t;
 +
    }
 +
 
 +
 
 +
}
  
if (P.Z > Size / 4)
 
V.Z = -fabs(V.Z);
 
if (P.Z < -Size / 4)
 
V.Z = fabs(V.Z);
 
  
// Запоминание состояния изменения текущей СК
 
glPushMatrix();
 
 
// Рисование стенок
 
glutWireCube(Size / 2);
 
// Задача перемещения мяча
 
glTranslated(P.X, P.Y, P.Z);
 
// Цвет мяча
 
glColor3d(0, 1, 1);
 
// Рисование мяча
 
glutSolidSphere(0.5, 30, 30);
 
 
// Восстановление последнего запоминания состояния изменения текущей СК
 
glPopMatrix();
 
}
 
}; // end of 'ball_air_2' class
 
  
// Шар, летящий с сопротивлением воздуха
+
int rez_3(double v, double a, double k, double m)
// Координаты получены методом Верле при линейной зависимости силы сопротивлении воздуха от скорости
 
class ball_air_3 : public sagl::object
 
 
{
 
{
private:
+
  fout<<"---------------Третий режим работы-------------------------"<<endl;
double angle, v, m, n;
+
    fout<<" T=0 x=0 y=0";
public:
+
    fout<<endl;
// Конструктор
+
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
ball_air_3( void ) : angle(Pi / 3), v(1), m(1), n(0.1)
+
    x3=0,x2=0,x1=x2-Vxn*t, y3=0,
{
+
    y2=0, y1=y2-Vyn*t, g=9.8, t1, T=0.1;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
P = sagl::vec(sagl::r0() + 5, 5, 0);
+
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
V.X = 0;
 
V.Y = sin(angle) * v;
 
V.Z = cos(angle) * v;
 
}
 
 
// Конструктор
 
ball_air_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
V += a * Ani.DeltaTime;
+
    y3=2*y2-y1-(g-+k/m*Vyn)*pow(t,2);
// Изменение вектора перемещения
+
    Vxn=(x3-x1)/(2.0*t); //скорость в момент времени T
P += V * Ani.DeltaTime;
+
    Vyn=(y3-y1)/(2.0*t);
 +
    x1=x2;// приравнивание к координате на n-1 шаге значение координаты в n шаге
 +
    y1=y2;
 +
    x2=x3;//-//- к координате в n шаге значение в момент времени T
 +
    y2=y3;
 +
    while (y2>0)
 +
    {
 +
        x3=2*x2-x1-k/m*Vxn*pow(t,2);
 +
        y3=2*y2-y1-(g+k/m*Vyn)*pow(t,2);
 +
        Vxn=(x3-x1)/(2.0*t);
 +
        Vyn=(y3-y1)/(2.0*t);
 +
        fout<<" T="<<T<<" x="<<x2<<" y="<<y2<<endl;
  
// Ограничения - стенки
+
        if (y3<0)
if (P.X > Size / 4)
+
        {
V.X = -fabs(V.X);
+
            t1=sqrt(abs((-y1+2*y2)/(g+k/m*Vyn)));
if (P.X < -Size / 4)
+
            x3=2*x2-x1-k/m*Vxn*pow((t+t1),2);
V.X = fabs(V.X);
+
            fout<<" T="<<T+t1<<" x="<<x3<<" y="<<0<<endl;
 +
        }
  
if (P.Y > Size / 4)
+
        T=T+t;
V.Y = -fabs(V.Y);
+
        x1=x2;
if (P.Y < -Size / 4)
+
        y1=y2;
V.Y = fabs(V.Y);
+
        x2=x3;
 +
        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
 
  
#endif /*__SAMPLE_H_ */
+
int rez_4(double v, double a, double k, double m)
 
+
{
// END OF 'SAMPLE.H' FILE
+
  fout<<"---------------Четвертый режим работы-------------------------"<<endl;
</syntaxhighlight>
+
    fout<<" T=0 x=0 y=0";
</div>
+
    fout<<endl;
[http://tm.spbstu.ru/File:T06BALL.7z Скачать архив]
+
    double t=0.1, Vxn=v*cos(a/180*M_PI), Vyn=v*sin(a/180*M_PI),
<br>
+
    x3=0,x1=0, x2=x1+Vxn*t, y3=0, y1=0,
 +
    y2=y1+Vyn*t, g=9.8, t1, T=0.1, V=v;//шаг, скорость по х в момент времени T, -\\- по y в момент времени Т
 +
    //координата по х в в момент времени T, -\\- в n-1 шаг, -\\- в n шаге, аналогично для y,
  
  
'''[[Абрамов Игорь]]'''
+
    x3=2.0*x2-x1-(k/m)*V*Vxn*pow(t,2);
 
+
    y3=2.0*y2-y1-(g+(k/m)*V*Vyn)*pow(t,2);
'''Алгоритм''': в специализированном классе хранятся данные о мяче, функции-члены, задающие различные типы движения тела, функции отрисовки движения мяча. Все расчёты ведутся в режиме реального времени с помощью дополнительных функций. Отрисовка движения мяча происходит с помощью графических средств библиотеки OpenGL.
+
    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;
  
'''Инструкция''': при запуске программы пользователь видит полёт четырёх мячей в замкнутом пространстве с равными начальными условиями, но различными алгоритмами движения. При желании изменить тип движения мяча достаточно изменить лишь название функции движения конкретного объекта в функции Display.
+
        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;
 +
        }
  
Ссылка для скачивания: [http://tm.spbstu.ru/File:Ball_Abramov.rar]
 
  
</div>
+
        T=T+t;
 +
        x1=x2;
 +
        y1=y2;
 +
        x2=x3;
 +
        y2=y3;
  
'''[[Лобанов Илья]]'''
+
    }
  
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
+
}
  
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
 
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
 +
int main()
 +
{
  
'''Краткая инструкция''':
+
setlocale(LC_ALL, "rus");
 +
cout<<"Введите скорость тела и угол"<<endl;
 +
cin>>v>>a;
  
В окне консоли пользователю предлагается вывести следующие значения: начальную скорость , угол и шаг.
+
while (1>0){
После этого полученные в результате работы программы данные выводятся в файл.
+
cout<<"Выберите режим работы программы:"<<endl;
 +
cout<<"1 - Координаты, рассчитанные по формуле, при движении без сопротивления воздуха"<<endl;
 +
cout<<"2 - Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
 +
cout<<"3- Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости"<<endl;
 +
cout<<"4 - Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости"<<endl;
 +
cout<<"5 - Выйти";
 +
cin>>o;
  
Скачивать [[http://tm.spbstu.ru/File:Air.rar тут]]
+
if (o==1)
[[http://tm.spbstu.ru/File:phys.rar тут]]
+
    rez_1(v,a);
 +
if (o==2)
 +
    {
 +
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 +
    cin>>m>>k;
 +
    rez_2(v,a,k,m);
 +
    }
  
</div>
+
if (o==3)
 
+
    {
 
+
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 
+
    cin>>m>>k;
</div>
+
    rez_3(v,a,k,m);
 +
    }
 +
  if (o==4)
 +
    {
 +
    cout<<"Введите массу тела и коэф сопротивления воздуха:"<<endl;
 +
    cin>>m>>k;
 +
    rez_4(v,a,k,m);
 +
    }
 +
  if (o==5)
 +
        break;
  
'''[[Капитанюк Светлана]]'''
+
            }
 +
}
  
'''Описание программы''' : программа записывает в четыре файла результаты вычисления:
 
  
Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;
+
</syntaxhighlight>
Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
</div>
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Скачивать [http://tm.spbstu.ru/File:Point_03.zip тут]
 
  
</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]]
Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
 
Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
Посмотреть программу можно [http://tm.spbstu.ru/File:falling.zip здесь]
+
Графики приведены для движения тела массой 1, со скоростью 50, под углом 45 градусов. Сопротивление воздуха принято равным 0.0001, шаг 0,1.
  
</div>
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
  
<div class="mw-collapsible mw-collapsed" style="width:100%" >
+
#include <iostream> ///программа, подсчитывающая и записывающая в файл координаты движения тела для двух вариантов метода Верле
'''[[Демченко Артём]]'''
+
#include <fstream> /// и для движений с учётом сопротивления и без его учёта
 +
#include <math.h>
 +
#include<stdlib.h>
 +
using namespace std;
  
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
+
int main()
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
+
{
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
+
    double a, step, Pi, g, Vo, m, r;
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
+
    ///а - угол, под которым движется тело, step - шаг функции, Vo - начальная скорость тела, m - масса тела, r - величина сопротивления
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
 
  
''' Инструкция ''':
+
    double x, y, x_0, y_0, x0, y0, Vx, Vy;
Пользователь вводит начальные данные ( массу, скорость, угол броска, шаг по времени и сопротивление воздуха). Выбираем режим работы программы, после этого в папке с программой создается файл, который требуется открыть программой gnuplot для просмотра графика, построенного на полученных координатах.
+
    ///переменные для движения точки без учёта сопротивления и с его учётом
 +
    ///х - изменяющаяся пошагово координата тела по оси Ох, у - изменяющаяся пошагово координата тела по оси Оу,
 +
    ///х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 - скорость тела в данный момент времени по оси Оу
  
<div class="mw-collapsible-content">
+
    double Vxn2, Vyn2, x_1, x_2, x_3, y_1, y_2, y_3;
 +
    ///переменные для 2го варианта метода Верле
 +
    ///х_1 - координата тела по оси Ох на (n-1) шаге, х_2 - координата тела по оси Ох на (n) шаге, х_3 - координата тела по оси Ох на (n+1) шаге
 +
    ///у_1 - координата тела по оси Оу на (n-1) шаге, у_2 - координата тела по оси Оу на (n) шаге, у_3 - координата тела по оси Оу на (n+1) шаге
 +
    ///Vxn2 - скорость тела в данный момент времени по оси Ох, Vyn2 - скорость тела в данный момент времени по оси Оу
  
 +
    g=10; ///значение ускорения свободного падения
 +
    Pi=3.14159265; /// значение числа П, используем для перевода радиан в градусы
  
 +
    do ///цикл, запрашивающий ввод пользователем значения шага функции
 +
    {
 +
        cout << "Input the step, it must be less than 1" << endl; ///ввод с клавиатуры шага(то же самое, что дельта t), шаг должен быть маленьким (меньше 1)
 +
        cin >> step;  ///вывод величины шага на экран
 +
    }
 +
    while (step>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
  
'''Визуализированный результат работы программы'''
+
    cout << '\n' << "Input the corner in degrees,the corner is in the range from 0 to 90 degrees" << endl; ///ввод с клавиатуры угла в радианах (угол от 0 до 90 градусов)
 +
    cin >> a; ///вывод значение угла на экран
 +
    a=(Pi*a)/180.0;
 +
    cout << '\n' << "Input the weight" << endl; ///ввод с клавиатуры значения массы
 +
    cin >> m; ///вывод величины массы на экран
  
[[:File:Throws.png]]
+
    do ///цикл, запрашивающий ввод пользователем значения сопротивления воздуха
 +
    {
 +
        cout << '\n' << "Input the value of the resistance, it must be less than 1" << endl; ///ввод с клавиатуры величины сопротивления
 +
        cin >> r; ///вывод значения сопротивления на экран
 +
    }
 +
    while (r>=1); ///выход из цикла не будет обеспечен, пока пользователь не введет число, меньшее 1
  
<syntaxhighlight lang="cpp" line start="1" enclose="div">
+
    cout << '\n' << "Input the speed" << endl; ///ввод с клавиатуры значения начальной скорости
 +
    cin >> Vo; ///вывод значения скорости на экран
  
#include <iostream>
+
    ///для движения без учёта сопротивления
#include <math.h>
+
    x0=0; ///обнуление переменных
#include <iomanip>
+
    y0=0;
#include <fstream>
+
    x=0;
#include <conio.h>
+
    y=0;
#include <stdio.h>
 
  
 +
    ///для движения с учётом сопротивления
 +
    x_0=0; ///обнуление переменных
 +
    y_0=0;
  
using namespace std;
+
    ///для 1го варианта метода Верле
  
double g = 9.8, Pi = 3.1415; // Задаем две глобальные переменные ускорения свободного падения и числа Pi
+
    Vx0=Vo*cos(a); ///расчет проекции начальной скорости по оси Ох
 +
    Vy0=Vo*sin(a); ///расчет проекции начальной скорости по оси Оу
  
int WoutR(double alpha, double dt, double t, double Yo, double Vo) // Функция, записывающая в файл Throws Without Resistance.txt координаты тела, которое движется без сопротивления
+
    x2=0; ///обнуление переменных
{
+
     y2=0;
     FILE *Coord;
+
    x3=0;
  Coord = fopen ("Throws Without Resistance.txt", "w");
+
    y3=0;
    double X = 0, Y = 0; // Координаты начала
 
  
    while ( Y >= Yo) // Yo используем для того, чтобы цикл прекратился тогда, когда тело упадет
+
    y1=y2-Vy0*step; ///расчет начального значения координаты по оси Оу
    {
+
    x1=x2-Vx0*step; ///расчет начального значения координаты по оси Ох
  
      X =  Vo*t*cos(alpha);
+
     ///для 2го варианта метода Верле
      Y =  Vo*t*sin(alpha) - (g*t*t)*0.5;
 
      t+= dt;
 
     if (Y > Yo )
 
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 
    else
 
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // Используем такой else для того, чтобы не получить отрицательную координату
 
    }
 
  
}
+
    x_2=0; ///обнуление переменных
 
+
     y_2=0;
int ExactForm(double alpha, double dt, double t, double Yo, double Vo, double R, double m) // Функция, записывающая в файл ExactForm.txt координаты тела, рассчитывающиеся по формлуе точного решения
+
    x_3=0;
{                                                                                          // для линейной зависимости
+
     y_3=0;
     FILE *Coord;
 
  Coord = fopen ("ExactForm.txt", "w");
 
     double X, Y = 0, Vx, Vy;
 
  
     while ( Y >= Yo) // Использование Yo аналогично использованию в прошлом пункте.
+
     Vxn2=Vo*cos(a); ///расчет скорости тела на начальный момент времени по оси Ох
    {
+
    Vyn2=Vo*sin(a); ///расчет скорости тела на начальный момент времени по оси Оу
  
      X = ((m*Vx)/R) * (1 - exp(((-1)*R*t)/m));
+
    y_1=y_2-Vo*sin(a)*step; ///расчет начального значения координаты на (п-1) шаге по оси Оу
      Y = (m/R)*((Vy + (g*m)/R)*(1 - exp((-1)*R*t/m))) - (g*t*m)/R;
+
    x_1=-Vo*cos(a)*step;   ///расчет начального значения координаты на (п-1) шаге по оси Ох
      Vx = Vo*cos(alpha);
 
      Vy = Vo*sin(alpha);
 
      t+= dt;
 
    if (Y > Yo )
 
        fprintf(Coord, "%.3lf \t %.3lf\n", X, Y);
 
    else
 
        fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000); // используется аналогично прошлому пункту
 
      }
 
}
 
  
int VerleSq (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleSq.txt оординаты тела, рассчитывающиеся по формлуе Верле
+
    ofstream out("For method without resistance.txt");
{                                                                                                    // для Квадратичной зависимости сопротивления от скорости
+
    ///запись в файл значений координат по осям Ох и Оу для движения без сопротивления
    FILE *Coord;
 
  Coord = fopen ("VerleSq.txt", "w");
 
  
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V, Yop, Xop; // X, Y - текущие координаты; Xnext, Ynext - координаты следующего шага; Xprev, Yprev - координаты предыдущего шага.
+
     for (int i=0; y>=0; ++i) ///цикл для подсчета координат при движении тела без учёта сопротивления
                                                                  // Xop, Yop - вспомогательные координаты для (-1)-го шага
+
    {
 +
        x=Vo*step*i*cos(a); ///расчет координаты тела по оси х
 +
        y=Vo*sin(a)*i*step-(g*i*step*i*step)*0.5; ///расчет координаты тела по оси y
  
    Yop = Yo - Vo*sin(alpha)*dt; // Сторки 62-79 используются для просчитывания (-1)-го шага, так как в точке 0;0 у нас нету предыдущего шага
+
        out << x << "    " << y <<'\n'; ///вывод всех значений координат по оси х и по оси у при движении тела без учёта сопротивления
     Xop = Xo - Vo*cos(alpha)*dt;
+
     }
    X = Xo;
+
     out.close();
    Y = Yo;
+
 
     Xnext = 2.0*X - Xop - (R/m)*Vo*Vo*cos(alpha)*(dt*dt);
+
     ofstream out1 ("For method with resistance.txt");
     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); // Записываем первую координату в файл
+
     for (int i=0; y_0>=0; ++i) ///цикл для подсчета координат при движении тела с учётом сопротивления
 +
    {
 +
        Vx=Vo*cos(a); ///расчет скорости тела по оси Ох
 +
        Vy=Vo*sin(a); ///расчет скорости тела по оси Оу
 +
        x_0=x0+(m/r)*Vx*(1.0 - exp((-r*i*step)/m)); ///расчет координаты тела по оси х
 +
        y_0=y0+(m/r)*(Vy+g*(m/r))*(1.0 - exp((-r*i*step)/m))-g*i*step*(m/r); ///расчет координаты тела по оси y
  
    Xprev = X; // Меняем координаты местами. Так (n-1)-ый шаг становится n-ым шагом, n-ый шаг становится (n+1)-ым шагом. Далее аналогично
+
        out1 << x_0 << "    " << y_0 <<'\n'; ///вывод всех значений координат по оси х и по оси у при движении c учётом сопротивления
     X = Xnext;
+
     }
     Yprev = Y;
+
     out1.close();
    Y = Ynext;
 
  
 +
    ofstream out2 ("For method Verle 1.txt");
 +
    ///запись в файл значений координат по осям Ох и Оу для 1го варианта метода Верле
  
     while (Y >= Yo) // После выполнения строк 62-79 получаем все необходимые данные для выполнения алгоритма.
+
     for (int i=0; y3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 1го варианта метода Верле
 
     {
 
     {
    Xnext = 2.0*X - Xprev - (R/m)*V*Vx*(dt*dt);
+
        x3=2*x2-x1-(r/m)*Vn*Vxn*step*step; ///расчет координаты в данный момент времени по оси Ох
    Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
+
        y3=2*y2-y1-(g+(r/m)*Vn*Vyn)*step*step; ///расчет координаты в данный момент времени по оси Оу
    Ynext = 2.0*Y - Yprev - (g +(R/m)*V*Vy)*(dt*dt);
+
        Vxn=(x3-x1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
    Vy = (1.0/(2.0*dt))*(Ynext - Yprev);
+
        Vyn=(y3-y1)/(2.0*step); /// расчет скорости в данный момент времени по оси Ох
    V = sqrt((Vx*cos(alpha)*Vx*cos(alpha)) + (Vy*sin(alpha) - g*dt)*(Vy*sin(alpha) - g*dt));
+
         Vn=sqrt(Vxn*Vxn+Vyn*Vyn); ///расчет скорости тела по модулю
    if (Ynext > Yo )
 
         fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
 
    else
 
  
      fprintf(Coord, "%.3lf \t %.3lf\n", X, 0.000);
+
        x1=x2; ///присваивание значению координаты х1 на (n-1) шаге значение координаты х2 на n шаге
 +
        x2=x3; ///присваивание значению координаты х2 на (n) шаге значение координаты х3 на (n+1) шаге
 +
        y1=y2; ///присваивание значению координаты у1 на (n-1) шаге значение координаты у2 на n шаге
 +
        y2=y3; ///присваивание значению координаты у2 на (n) шаге значение координаты у3 на (n+1) шаге
  
    Xprev = X;
+
        out2 << x3 << "  " << y3 <<'\n'; ///вывод всех значений координат по оси Ох и по оси Оу на экран для 1го варианта метода Верле
    X = Xnext;
 
    Yprev = Y;
 
    Y = Ynext;
 
 
     }
 
     }
 +
    out2.close();
  
}
+
    ofstream out3 ("For method Verle 2.txt");
int VerleL (double alpha, double dt, double t, double Yo, double Xo, double Vo, double R, double m) // Функция, записывающая в файл VerleL.txt оординаты тела, рассчитывающиеся по формлуе Верле
+
    ///запись в файл значений координат по осям Ох и Оу для 2го варианта метода Верле
{                                                                                                  // для линейной зависимости сопротивления от скорости
 
    FILE *Coord;
 
  Coord = fopen ("VerleL.txt", "w");
 
  
     double X, Xnext, Xprev, Y, Ynext, Yprev, Vx, Vy, V,Yop, Xop; // Комментарии аналогичны переменным и формулам в VtrleSq
+
     for (int i=0; y_3>=0; ++i) ///цикл для подсчета координат и скорости по времени для 2го варианта метода Верле
 +
    {
 +
        x_3=2*x_2-x_1-(r/m)*Vxn2*step*step; ///расчет координаты в данный момент времени по оси Ох
 +
        y_3=2*y_2-y_1-(g+(r/m)*Vyn2)*step*step; ///расчет координаты в данный момент времени по оси Оу
 +
        Vxn2=(x_3-x_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Оу
 +
        Vyn2=(y_3-y_1)/(2.0*step); ///расчет скорости в данный момент времени по оси Ох
  
    Yop = Yo - Vo*sin(alpha)*dt;
+
        x_1=x_2; ///присваивание значению координаты х_1 на (n-1) шаге значение координаты х_2 на n шаге
    Xop = Xo - Vo*cos(alpha)*dt;
+
        x_2=x_3; ///присваивание значению координаты х_2 на (n) шаге значение координаты х_3 на (n+1) шаге
    X = Xo;
+
        y_1=y_2; ///присваивание значению координаты у_1 на (n-1) шаге значение координаты у_2 на n шаге
    Y = Yo;
+
        y_2=y_3; ///присваивание значению координаты у_2 на (n-1) шаге значение координаты у_3 на (n+1) шаге
    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);
+
        out3 << x_3 << "   " << y_3 <<'\n'; ///вывод на экран всех значений координат по оси Ох и по оси Оу для 2го варианта метода Верле
  
     Xprev = X;
+
     }
     X = Xnext;
+
     out3.close();
    Yprev = Y;
 
    Y = Ynext;
 
  
 +
    cout << '\n' << "All results are saved in files." << endl; ///вывод на экран сообщения о записи в файл всех результатов
 +
    cout << '\n' << "The program is finished." << endl; ///вывод на экран сообщения о завершении работы программы
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
</div>
  
    while (Y >= Yo)
+
<div class="mw-collapsible mw-collapsed" style="width:100%" >
    {
+
'''[[Уманский Александр]]'''
    Xnext = 2.0*X - Xprev - (R/m)*Vx*(dt*dt);
 
    Vx = (1.0/(2.0*dt))*(Xnext - Xprev);
 
    Ynext = 2.0*Y - Yprev - (g +(R/m)*Vy)*(dt*dt);
 
    Vy =  (1.0/(2.0*dt))*(Ynext - Yprev);
 
  if (Ynext > Yo )
 
        fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, Ynext);
 
    else
 
      fprintf(Coord, "%.3lf \t %.3lf\n", Xnext, 0.000);
 
  
    Xprev = X;
+
'''Описание программы''': программа записывает в четыре файла результаты вычисления:
    X = Xnext;
+
# Координаты, рассчитанные по формуле, при движении без сопротивления воздуха;  
    Yprev = Y;
+
# Координаты, полученные методом Верле при линейной зависимости силы сопротивлении воздуха от скорости;
    Y = Ynext;
+
# Координаты, полученные из точного решения, при линейной зависимости силы сопротивлении воздуха от скорости;
    }
+
# Координаты, полученные методом Верле при квадратичной зависимости силы сопротивлении воздуха от скорости.
  
}
+
<div class="mw-collapsible-content">
  
int main()
+
[[File:Methods.rar|Скачать архив]]
{
 
  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";
+
[[File:1.png]]
  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";
 
  
 
+
<syntaxhighlight lang="cpp" line start="1" enclose="div">
    FILE *Gnu;
 
    Gnu = fopen ("Throws.gp", "w"); // Создаем файл формата gp, который будем открывать программой gnuplot для того, чтобы построить наш график/ки по точкам
 
 
 
switch ( i )
 
{
 
case 1:
 
    {
 
    WoutR(alpha,dt,t,Yo,Vo);
 
    fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l");
 
    break;
 
    }
 
case 2:
 
    {
 
    ExactForm(alpha,dt,t,Yo,Vo,R,m);
 
    fprintf(Gnu, "plot \"ExactForm.txt\" using 1:2 w l");
 
    break;
 
    }
 
case 3:
 
    {
 
    VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 
    fprintf(Gnu, "plot \"VerleSq.txt\" using 1:2 w l");
 
    break;
 
    }
 
case 4:
 
    {
 
    VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
 
    fprintf(Gnu, "plot \"VerleL.txt\" using 1:2 w l");
 
    break;
 
    }
 
case 5:
 
    {
 
  WoutR(alpha,dt,t,Yo,Vo);
 
  ExactForm(alpha,dt,t,Yo,Vo,R,m);
 
  VerleSq(alpha,dt,t,Yo,Xo,Vo,R, m);
 
  VerleL(alpha,dt,t,Yo,Xo,Vo,R, m);
 
  fprintf(Gnu, "plot \"Throws Without Resistance.txt\" using 1:2 w l, \"ExactForm.txt\" using 1:2 w l, \"VerleSq.txt\" using 1:2 w l, \"VerleL.txt\" using 1:2 w l"); // записываем в Throws.gp названия четырех файлов
 
  break;
 
    }                                                  // с координатами таким образом, чтобы программа gnuplot смогла их увидеть и прочесть
 
case 0:
 
    break;
 
default:
 
    break;
 
}
 
    return 0;
 
}
 
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
</div>
 
</div>
 
'''[[Гильманов Илья]]'''
 
 
'''Описание программы''': программа состоит из четырех независимых друг от друга частей:
 
#  Полет тела без сопротивления воздуха;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
 
Скачать можно [[http://mech.spbstu.ru/File:Движение_тела_в_среде.rar тут]]
 
 
'''[[Киселёв Лев]]'''
 
 
'''Описание программы''': программа рассчитывает координаты точки при следующих случаях
 
#  Полет тела без сопротивления воздуха;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются точным методом;
 
#  Полет тела при линейной зависимости силы сопротивления воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
#  Полет тела при квадратичной зависимости силы сопротивлении воздуха от скорости, при котором координаты тела рассчитываются методом Верле;
 
 
Скачать можно [[http://mech.spbstu.ru/File:3zadanie.rar тут]]
 
 
'''[[Ляжков Сергей]]'''
 
 
'''Описание программы''': Программа рассчитывает координаты полета тела по х и у. Как и в программе шахмат и интерполяции, здесь представлено меню выбора функций. Вы вводите начальные координаты, начальную скорость и угол полета(например, мяча или снаряда)(Нет смысла вводить величину скорости света, так как парабола вряд ли получится).
 
Затем Вы выбираете в меню "вариант" сопротивления воздуха, после чего вводите массу тела и коэффициент сопротивления среды(без сопротивления воздуха этим можно пренебречь). Программа выводит массив точек и сохраняет их в текстовый файл. Эти точки - координаты полета до тех пор, пока значения y не станет ОТРИЦАТЕЛЬНЫМИ...
 
Это мой первый проект по моделированию, спасибо за предоставленную возможность попрактиковаться.
 
Скачать можно [[http://mech.spbstu.ru/File:Полет.zip тут]]
 

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

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

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

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

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


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

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

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

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



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

File:graphAP.png

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

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


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

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

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

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

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

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

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

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

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

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

Формулы.png

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

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

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


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

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

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

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

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

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



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

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

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


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

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

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

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

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

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

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

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

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



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

File:Throws.png

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


Иванова Яна

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

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

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

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

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

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

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

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

Киселёв Лев

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

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

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

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

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

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

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

1.png


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

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


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

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

Файл "main.cpp"

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

Файл "Vector.h"

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


Лобанов Илья

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

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


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

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

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

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

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

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

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

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

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

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

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

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


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

"T06BALL.CPP"

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

"ANIM.CPP"

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

"ANIM.H"

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

"VEC.H"

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

"SAMPLE.H"

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

Graph239.png

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


Файл "main.cpp"

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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