Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Санкт-Петербургский Государственный Политехнический Университет
Лабораторная работа
Дисциплина: Компьютерная графика.
Тема: визуализация эффекта дождя.
Выполнил:
студент группы 4172/11
Акимов А.Э.
Проверил:
Проф. Курочкин М.А.
Санкт-Петербург
2012 год
Оглавление 1
Задание 2
Цель. 3
Описание предметной области. 3
Описание программной реализации. 4
Текст программы. 5
Результат выполнения. 8
Заключение. 9
Список литературы 10
Реализовать модель физического эффекта, используя одно из средств программирования.
Разработать модель изменения яркости точек экрана, которая создавала бы иллюзию физического эффекта «Дождь». Модель можно реализовать с помощью любого средства программирования.
Дождь это множество капель воды, которые движутся сверху вниз. При наличии ветра капли воды падают под углом, зависящем от силы и направления ветра. В зависимости от интенсивности дождя, капли падают на поверхность с разной плотностью.
Плотность дождя в данной модели зависит от максимального числа капель, выводимых одновременно на экран. Чем больше это число, тем больше плотность. Интенсивность дождя зависит от скорости изменения положения капли по оси У. Для создания реалистичного эффекта, капли генерируются разной длинны, что создает эффект глубины картины. Как и реальный дождь, капли случайно распределяются по всей длине окна. В данной модели не учитывается влияние ветра на капли, поэтому они падают строго вертикально.
Приложение создано с помощью библиотеки Windows. Она используется для создания окна Windows, в которой будет происходить визуализация. Также в этой библиотеке реализованы методы рисования таких примитивов как линия, овал и так далее. В программе можно задать несколько параметров: ширина и высота окна, количество капель, скорость падения капель. Капля создается с помощью функции CreatePen(PS_SOLID, 1, RGB(255, 255, 255)). Эта функция создает объект «капля» и рисует прямую линию. Параметрами являются: тип линии, ее толщина и цвет. Для того, чтобы переместить каплю используются следующие функции: MoveToEx(hdc, pos_x[i], pos_y[i], NULL), LineTo(hdc, pos_x[i], pos_y[i] + length[i]). Первая функция получает на вход дескриптор окна, координаты капли и, удаляет каплю с прежнего места. Параметрами второй функции являются: дескриптор окна и координаты, в которые надо переместить каплю. В данной реализации капли являются отдельными объектами и никак не взаимодействуют друг с другом. В качестве фона в данной модели используется черный фон, которой также никак не взаимодействует с каплями. Моделирование продолжается до тех пор, пока не была нажата кнопка «Esc». Нажатие кнопки KEYDOWN(VK_ESCAPE) обрабатывается с помощью методов библиотеки Windows. После того, как были перерисованы все капли, выполняется функция Sleep(1), которая заставляет программу остановится на некоторое время в миллисекундах, указанное как параметр.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define WINDOW_CLASS_NAME "WINCLASS1"
#define WINDOW_WIDTH 700
#define WINDOW_HEIGHT 700
#define A_SIZE 500
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
HWND main_window_handle = NULL;
HINSTANCE hinstance_app = NULL;
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_CREATE:
{
return(0);
} break;
case WM_PAINT:
{
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
} break;
case WM_DESTROY:
{
PostQuitMessage(0);
return(0);
} break;
default:break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASSEX winclass;
HWND hwnd;
MSG msg;
HDC hdc;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = WINDOW_CLASS_NAME;
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
hinstance_app = hinstance;
if (!RegisterClassEx(&winclass))
return(0);
if (!(hwnd = CreateWindowEx(NULL,
WINDOW_CLASS_NAME,
"Rain effect",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hinstance,
NULL)))
return(0);
main_window_handle = hwnd;
hdc = GetDC(hwnd);
srand(GetTickCount());
HPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
HPEN green_pen = CreatePen(PS_SOLID, 1, RGB(0,255,0));
HPEN black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
HBRUSH null_brush = (HBRUSH)GetStockObject(NULL_BRUSH);
SelectObject(hdc, null_brush);
int pos_x[A_SIZE];
int pos_y[A_SIZE];
int yv[A_SIZE];
int length[A_SIZE];
HPEN rand_pen[A_SIZE];
int r[A_SIZE];
int dr = 5;
int flag[A_SIZE];
for (int i = 0; i < A_SIZE; i++)
{
pos_x[i] = rand()%700;
pos_y[i] = -15 + rand()%30;
yv[i] = 5 + rand()%10;
length[i] = 5 + rand()%15;
rand_pen[i] = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
flag[i] = 0;
r[i] = 5;
}
while(TRUE)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
for (int i = 0; i < A_SIZE; i++)
{
SelectObject(hdc, black_pen);
if (flag[i] == 0)
{
MoveToEx(hdc, pos_x[i], pos_y[i], NULL);
LineTo(hdc, pos_x[i], pos_y[i] + length[i]);
}
else
{
Ellipse(hdc, pos_x[i] - r[i], 655, pos_x[i] + r[i], 665);
}
}
for (int i = 0; i < A_SIZE; i++)
{
if (flag[i] == 0)
{
pos_y[i] += length[i];
}
else
{
r[i] += dr;
if (r[i] > 30)
{
flag[i] = 0;
r[i] = 5;
pos_y[i] -= 670;
}
}
}
for (int i = 0; i < A_SIZE; i ++)
{
SelectObject(hdc, rand_pen[i]);
if (pos_y[i] > 660)
{
flag[i] = 1;
Ellipse(hdc, pos_x[i]-r[i], 655, pos_x[i]+r[i], 665);
DeleteObject(rand_pen[i]);
pos_x[i] = rand()%700;
yv[i] = 5 + rand()%10;
length[i] = 5 + rand()%15;
rand_pen[i] = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));
}
else
{
MoveToEx(hdc, pos_x[i], pos_y[i], NULL);
LineTo(hdc, pos_x[i], pos_y[i] + length[i]);
}
}
if (KEYDOWN(VK_ESCAPE))
SendMessage(hwnd, WM_CLOSE, 0,0);
Sleep(1);
}
DeleteObject(black_pen);
DeleteObject(null_brush);
ReleaseDC(hwnd,hdc);
return(msg.wParam);
}
В данной работе была реализована модель, имитирующая эффект дождя при безветренной погоде. В ходе выполнения данной лабораторной работы были получены знания о библиотеке Windows и ее процедурах, методе обработки события при нажатии клавиш на клавиатуре. Разработанное приложение должно ассоциироваться с падающим дождем у независимого зрителя, в чем необходимо удостовериться.