404

Разработка программы реализирующей цветное движущееся изображение

Курсовая

Информатика, кибернетика и программирование

написание программы для DOS и Windows, отображающую рисование дворников автомобиля. Предусмотрение возможности задания скорости исполнения и приостановки/возобновления выполнения по нажатию клавиши на клавиатуре или мыши (для версии под Windows).

Русский

2013-01-06

97 KB

22 чел.

Министерство образования РФ

Южно-Уральский государственный университет

Кафедра ЭВМ

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовой работе

по компьютерной графике

Выполнил:

студент группы ПС-479

Горра О.С.

 «8»января 2002

Проверила:

Ярош Е.С.

       «    »                        .

Челябинск

2012


ЮУрГУ

Факультет ПС

Кафедра ЭВМ

Задание

по курсовой работе

студенту группы ПС-479 Горра О.С.

1. Тема работы: разработать программу, реализующую цветное движущееся изображение.

2. Срок сдачи работы ___________.

3. Исходные данные к работе: написать программу для DOS и Windows, отображающую рисование дворников автомобиля. Предусмотреть возможность задания скорости исполнения  и приостановки/возобновления выполнения по нажатию клавиши на клавиатуре или мыши (для версии под Windows).

4. Содержание расчётно - пояснительной записки должно соответствовать ГОСТам ЕСПД.

5. Дата выдачи задания ___________.

Руководитель Ярош Е.С.

Задание принял к исполнению ___________

Подпись студента __________

СОДЕРЖАНИЕ

Общие сведения и функциональное назначение 4

Описание логической структуры 4

Используемые технические средства 5

Вызов и загрузка 5

Входные и выходные данные 5

Системные  требования  5

ПРИЛОЖЕНИЕ 1. Текст программы для Windows 7

ПРИЛОЖЕНИЕ 2. Текст программы для DOS 8


Общие сведения и функциональное назначение

 Версия программы для DOS содержится в файле dvor_dos.exe и представляет собой независимый модуль, запускаемый из DOS. Он требует присутствия в текущем каталоге файла egavga.bgi. Параметры вводятся в командной строке, при пустой командной строке подставляются значения по умолчанию. Программа написана на языке C в среде Borland C++ 5.02.

Версия для MS Windows содержится в файле dvor_win.exe и запускается из среды Windows. Здесь параметры вводтся в форме задания значений. Программа написана на языке С++ в среде Borland C++ 5.02.

После запуска программы на экране рисуются дворники очищающие стекло от дождя. Скорость анимации можно изменять в соответствии с желанием пользователя и возможностями аппаратуры. В процессе работы анимация может быть остановлена по нажатию клавиши на клавиатуре (и мыши в версии для Windows).

Описание логической структуры 

Текст программы для Windows содержится в Приложении 1, для DOS - в Приложении 2.

Главной частью программы под Windows является цикл обработки сообщений. В нем обрабатываются сообщения:

WM_CREATE - производится инициализация переменных начальными значениями и запускается таймер;

WM_DESTROY – позволяет закрыть окно, освободив все системные ресурсы;

WM_CHAR - интерпретирует нажатие клавиши на клавиатуре: если нажата клавиша “-”, то пауза между перерисовками уменьшается на 1мс; “+” - увеличивается на 1мс. При нажатии любой другой клавиши рост диаграммы приостанавливается до следующего нажатия;

WM_LBUTTONDOWN - срабатывает на нажатие левой клавиши мыши. Рост диаграмм останавливается до следующего нажатия;

WM_TIMER - приходит, когда таймер отсчитывает заданный промежуток времени. По приходу этого сообщения дворник перемещается на одно деление.   

В версии программы для DOS главной процедурой является DrawD.

Эта процедура отображает работу дворников  с заданной скоростью, а так же осуществляет прорисовку. Движение дворника может быть приостановлено/возобновлено нажатием любой клавиши на клавиатуре.

Используемые технические средства

Для работы DOS-версии требуется наличие EGA адаптера или лучше.

Для работы Windows-версии нужен видеоадаптер, совместимый с Windows.

Вызов и загрузка 

Для запуска DOS-версии необходимо запустить файл dvor_dos.exe из командной строки или любой файловой оболочки.

Windows-версия начинает работать после запуска файла dvor_win.exe.

Входные и выходные данные

Для DOS и Windows-версии значение задержки при запуске программы устанавливается равным 100 мс, и пользователь может менять его в процессе работы программы.

Результат работы программ одинаков - последовательность кадров. Вид экрана на заключительном этапе работы программ показан на рис. 1 (DOS), и рис. 2 (Windows).

Системные  требования

 Для  программы  dvor_dos.exe  (DOS).

-  Операционная  система . . DOS 4.0  и  выше;

-  Процессор . . . . Intel 386 и совместимые.

 Для  программы  dvor_win.exe  (Windows).

-  Операционная  система . . Windows 3.1 и выше;

-  Процессор . . . . Intel 386 и совместимые.


Рис. 1. Фрагмент работы программы dvor_dos.exe.

Рис. 2. Фрагмент работы программы diag_win.exe.


ПРИЛОЖЕНИЕ 1. Текст программы для Windows

#define STRICT

#include <windows.h>

#include <windowsx.h>

#include <mem.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

#include <geometry.h>

#include "menu.hpp"

// Прототипы функций

BOOL InitApp(HINSTANCE);

LRESULT CALLBACK _export WndProc(HWND, UINT, WPARAM, LPARAM);

BOOL CALLBACK _export DlgProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE hInstance;

const int maxx=400;

const int maxy=380;

const int dx=200;

const int dy=200;

int speed=5;

int stop=0;

int j=0;

int dir;

HDC hdc, hMemDC;

HBITMAP memBM,  hMemOldBitmap;

#pragma argsused

void line(HDC hdc,int x1, int y1, int x2, int y2){

MoveToEx(hdc,x1,y1,NULL);

  LineTo(hdc,x2,y2);

}

#pragma argsused

//==================================

//функция рисования вывода времени

//==================================

void DrawTime (HDC hdc)

{

char str[10];

itoa(19-speed,str,10);

SetBkMode(hdc, TRANSPARENT);

TextOut(hdc,0,0,"Current speed :",15);

TextOut(hdc,120,0,str,lstrlen(str));

}

//=================

//функция рисования

//=================

void DrawHammer(HDC hdc, int h)

{

HBRUSH HammerBrush1, HammerBrush2, OldBrush;

HPEN OldPen, HammerPen1, HammerPen2;

  HammerBrush1=CreateSolidBrush(RGB(255,0,0));

HammerBrush2=CreateSolidBrush(RGB(255,255,255));

HammerPen1=CreatePen(PS_SOLID,3,RGB(0,0,0));

  HammerPen2=CreatePen(PS_SOLID,3,RGB(255,255,255));

  OldPen=SelectPen(hdc,HammerPen2);

SelectObject(hdc,HammerBrush2);

  if (stop==0) {

  if (h!=0){

  Pie(hdc,40,120,240,320,220+220*cos(h*0.008),260-260*sin(h*0.008),180+180*cos(h*0.008),220-220*sin(h*0.008));

  Pie(hdc,145,120,345,320,345+345*cos(h*0.008),260-260*sin(h*0.008),280+280*cos(h*0.008),220-220*sin(h*0.008));}

  SelectPen(hdc,HammerPen1);

  line(hdc,140,220,140+100*cos(h*0.007),220-100*sin(h*0.007));

  line(hdc,245,220,245+100*cos(h*0.007),220-100*sin(h*0.007));

   if (dir==0) {line(hdc,140,220,140+100,220);}

  AngleArc(hdc,140,340,100,5,5);

  if (dir>0) h-=20;

  else h+=20;

 SelectPen(hdc,HammerPen2);

  line(hdc,140,220,140+100*cos(h*0.007),220-100*sin(h*0.007));

  line(hdc,245,220,245+100*cos(h*0.007),220-100*sin(h*0.007));

  if (dir>0) h+=20;

  else h-=20;

  for (int qw=0;qw<30;qw++) SetPixel(hMemDC,80+random(350),100+random(200),RGB(0,0,255));

}else line(hdc,140,220,140+100,220);

  SelectObject(hdc,OldBrush);

SelectObject(hdc,OldPen);

DeleteObject(HammerBrush1);

DeleteObject(HammerBrush2);

DeleteObject(HammerPen1);

  DeleteObject(HammerPen2);

}

//-----------------------

//функция очистки битмэпа

//-----------------------

void Clear(HDC hdc, int x1, int y1, int x2, int y2)

{

HBRUSH WhiteBrush, OldBrush;

HPEN OldPen, WhitePen;

WhiteBrush=CreateSolidBrush(RGB(255,255,255));

WhitePen=CreatePen(PS_SOLID,1,RGB(255,255,255));

OldBrush=(HBRUSH)SelectObject(hdc,WhiteBrush);

OldPen=SelectPen(hdc,WhitePen);

Rectangle(hdc,x1, y1, x2, y2);

SelectObject(hdc,OldBrush);

SelectObject(hdc,OldPen);

DeleteObject(WhiteBrush);

DeleteObject(WhitePen);

}

// Имя класса окна

char const szClassName[]   = "MenuClass";

// Заголовок окна

char const szWindowTitle[] = "Дворники";

// =====================================

// Функция WinMain

// =====================================

#pragma argsused

int PASCAL

WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR     lpszCmdLine,

int       nCmdShow)

{

 MSG  msg;   // структура для работы с сообщениями

 HWND hwnd;  // идентификатор главного окна приложения

::hInstance = hInstance;

 // Инициализируем приложение

 if(!InitApp(hInstance))

 return FALSE;

 // После успешной инициализации приложения создаем

 // главное окно приложения

 hwnd = CreateWindow(

 szClassName,         // имя класса окна

 szWindowTitle,       // заголовок окна

 WS_OVERLAPPED | WS_SYSMENU, // стиль окна

 CW_USEDEFAULT,       // задаем размеры и расположение

 CW_USEDEFAULT,       // окна, принятые по умолчанию

 maxx,maxy,

 0,                   // идентификатор родительского окна

 0,                   // идентификатор меню

 hInstance,           // идентификатор приложения

 NULL);               // указатель на дополнительные

        // параметры

 // Если создать окно не удалось, завершаем приложение

 if(!hwnd)

 return FALSE;

 // Рисуем главное окно

 ShowWindow(hwnd, nCmdShow);

 UpdateWindow(hwnd);

     Clear(hMemDC,0,0,400,350);

 // Запускаем цикл обработки сообщений

 while(GetMessage(&msg, 0, 0, 0))

 {

 DispatchMessage(&msg);

 }

 return msg.wParam;

}

// =====================================

// Функция InitApp

// Выполняет регистрацию класса окна

// =====================================

BOOL

InitApp(HINSTANCE hInstance)

{

 ATOM aWndClass; // атом для кода возврата

 WNDCLASS wc;    // структура для регистрации

     // класса окна

 // Записываем во все поля структуры нулевые значения

 memset(&wc, 0, sizeof(wc));

 // Подключаем меню

 wc.lpszMenuName  = "APP_MENU";

 wc.style         = 0;

 wc.lpfnWndProc   = (WNDPROC) WndProc;

 wc.cbClsExtra    = 0;

 wc.cbWndExtra    = 0;

 wc.hInstance     = hInstance;

//  wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);

 wc.hIcon         = LoadIcon(NULL, "a_jb");

 wc.hCursor       = LoadCursor(NULL, IDC_ARROW);

//  wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);

 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

//  wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);

 wc.lpszClassName = (LPSTR)szClassName;

 // Регистрация класса

 aWndClass = RegisterClass(&wc);

 return (aWndClass != 0);

}

// =====================================

// Функция WndProc

// =====================================

#pragma argsused

LRESULT CALLBACK _export

WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

/*  PAINTSTRUCT ps;

 HDC hdc, hMemDC;

 HBITMAP memBM,  hMemOldBitmap;*/

 switch (msg)

 {

 case WM_CREATE:

 {

 hdc = GetDC(hwnd);

 hMemDC = CreateCompatibleDC(hdc);

 //выбираем битовое изображение в контексте памяти

 memBM = CreateCompatibleBitmap ( hdc,400,350 );

 //установаем его в конкест памяти:

 hMemOldBitmap=(HBITMAP)SelectObject ( hMemDC, memBM );

 SetTimer(hwnd,NULL,speed*25,NULL);

 return 0;

 }

 case WM_TIMER:

 {

     Clear(hMemDC,0,0,200,50);

 DrawHammer(hMemDC,j);

 DrawTime(hMemDC);

 if (j>=300) {dir=-20;}

 else

 {if (j<=0)

   {

  dir=20;

   }

 }

 if (!stop) j+=dir;

 BitBlt(hdc,0,0,400,350,hMemDC,0,0,SRCCOPY);

 return 0;

 }

   case WM_LBUTTONDOWN: // Нажали левую клавишу мыши

   {

     stop = !stop;  //нажата кнопка мыши - приостанавливаем

   return 0;

   }

 case WM_KEYDOWN:

 {

 if (wParam==0x6b){ //- - увеличение скорости

  KillTimer(hwnd,NULL);

  speed--; if (speed < 0) speed = 0;

  SetTimer(hwnd,NULL,speed*20,NULL);

  return 0;};

 if (wParam==0x6d){//+ - уменьшение скорости

  KillTimer(hwnd,NULL);

  speed++; if (speed>19) speed = 19;

  SetTimer(hwnd,NULL,speed*20,NULL);

  return 0;};

 stop = !stop; //если не + и не - приостанавливаем

 return 0;

 }

 case WM_COMMAND:

 {

 switch (wParam)

 {

   // Сообщения от меню

   case CM_HELPINDEX:

   {

   // На сообщение от любой строки меню кроме

   // завершающей работу программы реагируем

   // выводом сообщения об ошибке

   MessageBox(hwnd, "Функция не реализована",NULL, MB_OK);

   return 0;

   }

  case CM_HELPABOUT:

    {

   MessageBox(hwnd, "Дворники","About...", MB_OK);

    return 0;

    }

   // Завершаем работу приложения

   case CM_FILEEXIT:

   {

   KillTimer(hwnd,NULL);

   DestroyWindow(hwnd);

   return 0;

   }

   default:

   return 0;

 }

 }

 case WM_DESTROY:

 {

 SelectObject(hMemDC,hMemOldBitmap);

 //удаляем кисти и перья

 DeleteObject(memBM);//удаляем битмэп

 DeleteDC(hMemDC);//удаляем контекст памяти

 ReleaseDC(hwnd,hdc);

 PostQuitMessage(0);

 return 0;

 }

 default:

 break;

 }

 return DefWindowProc(hwnd, msg, wParam, lParam);

}


ПРИЛОЖЕНИЕ
2. Текст программы для DOS

#include <graphics.h>

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <dos.h>

#include <math.h>

void main()

{  int i,j,k,l,g,a,flag;

  int driver = EGA;

  int mode   = EGAHI;

  int   res;

// ----- Инициализируем графический режим

 initgraph (&driver,&mode,"" );

if ((res=graphresult())!=grOk) {printf("\nGraphics error: %s\n",grapherrormsg(res));exit(1);}

  settextjustify(CENTER_TEXT, CENTER_TEXT);

  setcolor(15);

  getch();

  j=250;

  k=30;

  a=0;

  g=0;

  flag=0;

  setfillstyle(6,0);

circle(150,280,10);

line(160,280,165,280);

outtextxy(140,250,"Speed of wiper");

outtextxy(150,260,"max");

outtextxy(150,300,"min");

outtextxy(340,260,"Idle time");

outtextxy(325,290,"min");

outtextxy(325,300,"max");

circle(350,280,10);

line(360,280,365,280);

  do {

  for(i=0;i<=30;)

   {setcolor(15);

   line(200,230,200+100*cos(i*0.07),230-100*sin(i*0.07));

   line(305,230,305+100*cos(i*0.07),230-100*sin(i*0.07));

   putpixel(100+random(400),130+random(100),12);

   delay(k);

   if (kbhit())l=getch();

   switch (l)

   {

    case 27:{exit(0);break;}

    case 42:{

    if ((k>=20)&(k<=50))

    { setcolor(16);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     k=k-10;

     g++;

     setcolor(15);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     }

    //if(j>=50) j=j-40;printf("j=%dk=%d",j,k);

    l=0;

    break;}

    case 45:{

    if(j>=50)

    //j=j-50;printf("j=%d",j);

    {

      setcolor(16);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

     j=j-50;

     a++;

     setcolor(15);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

      }

    l=0;break;}

    case 43:{

    //j=j+50;printf("j=%d",j);

    if(j<=350)

     {

      setcolor(16);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

     j=j+50;

     a--;

     setcolor(15);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

      }

    l=0;break;}

    case 47:{

    //k=k+10;

    if ((k>=10)&(k<50))

    { setcolor(16);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     k=k+10;

     g--;

     setcolor(15);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     }

    l=0;break;}

  case 13:

case 32:{ if (flag==0) while(!kbhit()); flag=1-flag; l=getch(); l=0; break;}

    default :break;

    }

   setcolor(16);

   sector(200,230,i*3.0,i*4.0+5,100,100);

   sector(305,230,i*3.0,i*4.0+5,100,100);

   line(200,230,200+100*cos(i*0.07),230-100*sin(i*0.07));

   line(305,230,305+100*cos(i*0.07),230-100*sin(i*0.07));

   i++;

   }

  for(i=30;i>=0;)

  {setcolor(15);

  line(200,230,200+100*cos(i*0.07),230-100*sin(i*0.07));

  line(305,230,305+100*cos(i*0.07),230-100*sin(i*0.07));

  putpixel(100+random(400),130+random(100),12);

  delay(k);

  if (kbhit())l=getch();

   switch (l)

   {

    case 27:{exit(0);break;}

    case 42:{

    //if (k>=20) k=k-10;

      if ((k>=20)&(k<=50))

    { setcolor(16);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     k=k-10;

     g++;

     setcolor(15);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     }

     //if (j>=50) j=j-40;printf("%d",j);

     l=0;break;}

    case 45:{

    if(j>=50)

    //j=j-50;

     {

      setcolor(16);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

     j=j-50;

     a++;

     setcolor(15);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

      }

    l=0;break;}

    case 43:{

    //j=j+50;

      if(j<=350)

     {

      setcolor(16);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

     j=j+50;

     a--;

     setcolor(15);

     line(350+10*cos(a*0.8),280-10*sin(a*0.8),350+15*cos(a*0.8),280-15*sin(a*0.8));

      }

    l=0;break;}

    case 47:{

    //k=k+10;

         if ((k>=10)&(k<50))

    { setcolor(16);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     k=k+10;

     g--;

     setcolor(15);

     line(150+10*cos(g*0.8),280-10*sin(g*0.8),150+15*cos(g*0.8),280-15*sin(g*0.8));

     }

    l=0;break;}

  case 13:

case 32:{

  if (flag==0) while(!kbhit());

  flag=1-flag;

  l=getch();

  l=0;

  break;}

    default :  break;

    }

  setcolor(16);

  sector(200,230,i*3.0,i*4.0+5,100,100);

  sector(305,230,i*3.0,i*4.0+5,100,100);

  line(200,230,200+100*cos(i*0.07),230-100*sin(i*0.07));

  line(305,230,305+100*cos(i*0.07),230-100*sin(i*0.07));

  i--;

  }

     //Esc is 27

     //+ is wait 43 speed work 42

     // - is     45            47

setcolor(15);line(200,230,300,230);

line(305,230,405,230);

delay(j);

  } while (l!=27);

closegraph();

}


 

А также другие работы, которые могут Вас заинтересовать

16229. Планирование и проведение машинного эксперимента 77 KB
  Методические указания к лабораторной работе по дисциплине Теоретические основы автоматизированного управления Лабораторная работа № 5 Планирование и проведение машинного эксперимента Цель работы: Приобрести навыки постановки эксперимента на модели с испол
16230. Изучение движения физического резонанса 151.5 KB
  Тема: Изучение движения физического резонанса. Введение Физическим маятником называется твердое тело находящееся в поле сил тяготения и имеющего ось вращения лежащую в плоскости перпендикулярной вектору ускорения свободного падения g. o
16231. Сложения двух гармонических колебаний точки 91.5 KB
  Лабораторная работа по физике на тему: Сложение гармонических колебаний. Колебание тела которое происходит по законам синуса или косинуса называется гармоническим Общее уравнение гармонических имеет вид. Гармонические колебания характеризуются...
16232. Определение скорости звука методом акустического резонанса 104.5 KB
  Определение скорости звука методом акустического резонанса. Краткая теория. Звуковые волны представляют собой последовательные сжатия и разряжения среды т. е. упругие волны частоты которых лежат в пределах от 20 до20000 Гц. Появление звука всегда обусловлено колебания...
16233. Определение логарифмического декремента затухания физического маятника 77 KB
  Лабораторная работа №2. Тема: Определение логарифмического декремента затухания физического маятника. Краткая теория Звуковые волны представляют собой последовательные сжатия и разряжения среды т. е. упругие волны частоты которых лежат в пределах от 20 до20000 Г...
16234. Создать поздравительную открытку 1.08 MB
  Создать поздравительную открытку. Описание задания: Любое из предложенных фото превратить в поздравительную открытку используя текст с применением спецэффекта по вашему усмотрению. Рекомендуем увеличить размер холста и сделать надпись выше или ниже изображения...
16235. Решение обыкновенных дифференциальных уравнений. Визуализация численных методов 223.5 KB
  КУРСОВАЯ РАБОТА по информатике: Визуализация численных методов. Решение обыкновенных дифференциальных уравнений. Содержание: Введение. Постановка задачи. Описание методов решения. Суть задачи. Геометрический смысл задачи. Численные методы реш...
16236. Визуализация численных методов 449.83 KB
  Курсовая работа Визуализация численных методов Cсодержание Содержание Введение 1. Постановка задачи и математическая модель 2. Описание используемых методов 3. Блоксхемы основных процедур 4. Виды формы проекта 5.Листинг программы на языке Visual Basic 6.Ре
16237. Визуализация численных методов. Решение обыкновенных дифференциальных уравнений 350 KB
  Визуализация численных методов. Решение обыкновенных дифференциальных уравнений. Содержание Введение. 1. Постановка задачи и математическая модель. 2. Описание численных методов применительно к конкретной задаче 3. Блоксхемы программ и основных подпрограм