Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Буферизация графики



Рассмотрим ещё один пример: по нажатию на кнопку в произвольной точке экрана возникает треугольник; увеличиваясь, фигура трансформируется в звездочку («примеры: простейшая анимация», кнопка «трансформация»). Для рисования используется поверхность компонента PaintBox.

System::Drawing::Graphics ^g;//указатель на объект graphics

int i;

float fi, R;

Point center_pos;

//Запуск таймера по нажатию на кнопку.

private: System::Void start_button_Click(System::Object^ sender, \

System::EventArgs^ e)

{

/*Создание объекта graphics, animation_box - указатель на PictureBox.*/

g=animation_box->CreateGraphics();

/*Параметры выводимой на экран фигуры: R - радиус описанной окружности, fi - угол поворота, center_pos - структура, содержащая координаты центра фигуры; все числа генерируются случайным образом.*/

R=rand()%50;

if(R<5)R=8;

fi=rand()%360;

center_pos.Y=rand()%(animation_box->Height);

center_pos.X=rand()%(animation_box->Width);

i=3;//установка значения итерационной переменной

my_timer->Start();//Запуск таймера.

}

//Обработчик таймера.

private:

System::Void my_timer_tick(System::Object^sender, System::EventArgs^ e)

{

int j;

Point p;

/*Массив вершин многоугольника, рисуемого на очередном шаге. Количество вершин равно значению итерационной переменной.*/

array <Point>^ control_points={Point(0,0)};

Array::Resize(control_points,i%15);

//Кисть для заливки.

SolidBrush^ liner=gcnew SolidBrush(Color:: MediumSlateBlue);

if(i<=14)

{

g->Clear(Color::White); //Затирание изображения.

//Формирование массива координат вершин многоугольника.

for(j=0; j<i; j++)

{

/*При нечетном i рисуем правильный i-угольник, при чётном - звездочку на основе правильного i-угольника.*/

if(i%2||i==4||j%2)

{

p.X= center_pos.X+R*cos(fi+j*2*pi/i);

p.Y= center_pos.Y+R*sin(fi+j*2*pi/i);

}

else

{

p.X= center_pos.X+R*cos(fi+j*2*pi/i)/2;

p.Y= center_pos.Y+R*sin(fi+j*2*pi/i)/2;

}

control_points->SetValue(p, j); //Очередная вершина задана.

}

g->FillPolygon(liner,control_points); //Вывод фигуры на экран.

i++;

R+=5; //Увеличение радиуса окружности, задающей многоугольник.

}

else

/*Остановка таймера. Поскольку затирание изображения не производится, последний кадр останется на экране (сравните с предыдущим примером).*/

my_timer->Enabled=false;

}

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

Буферизация может быть реализована несколькими способами. Рассмотрим один из них - создание в памяти битовой матрицы в качестве промежуточного буфера. Изображение рисуется в битовой матрице, а когда кадр завершается, копируется в отображаемую плоскость.

Следующий пример кода выполняет рисование тех же фигур, что и предыдущий, но уже с использованием буферизации изображения. Сравнить результат с результатом выполнения предыдущего кода вы можете, посмотрев пример под кнопкой «применение буфера» («примеры: простейшая анимация»). В листинге «10 отличий» выделены оранжевым цветом. Как видите, код почти не изменился.

System::Drawing::Graphics ^g;//указатель на объект graphics

System::Drawing::Bitmap ^canvas; //указатель на битовое изображение

int i;

float fi, R;

Point center_pos;

//Запуск таймера по нажатию на кнопку.

private: System::Void start_button_Click(System::Object^ sender, \

System::EventArgs^ e)

{

/*Создание битового изображения, которое будет выполнять роль буфера и объекта graphics на его основе; animation_box - указатель на PictureBox.*/

canvas = gcnew Drawing::Bitmap(animation_box->Width,\

animation_box->Height);

g=System::Drawing::Graphics::FromImage(canvas);

/*Параметры выводимой на экран фигуры: R - радиус описанной окружности, fi - угол поворота, center_pos - структура, содержащая координаты центра фигуры; все числа генерируются случайным образом.*/

R=rand()%50;

if(R<5)R=8;

fi=rand()%360;

center_pos.Y=rand()%(animation_box->Height);

center_pos.X=rand()%(animation_box->Width);

i=3;//установка значения итерационной переменной

my_timer->Start();//Запуск таймера.

}

//Обработчик таймера.

private:

System::Void my_timer_tick(System::Object^sender, System::EventArgs^ e)

{

int j;

Point p;

/*Массив вершин многоугольника, рисуемого на очередном шаге. Количество вершин равно значению итерационной переменной.*/

array <Point>^ control_points={Point(0,0)};

Array::Resize(control_points,i%15);

//Кисть для заливки.

SolidBrush^ liner=gcnew SolidBrush(Color:: MediumSlateBlue);

if(i<=14)

{

g->Clear(Color::White); //Затирание изображения.

//Формирование массива координат вершин многоугольника.

for(j=0; j<i; j++)

{

/*При нечетном i рисуем правильный i-угольник, при чётном - звездочку на основе правильного i-угольника.*/

if(i%2||i==4||j%2)

{

p.X= center_pos.X+R*cos(fi+j*2*pi/i);

p.Y= center_pos.Y+R*sin(fi+j*2*pi/i);

}

else

{

p.X= center_pos.X+R*cos(fi+j*2*pi/i)/2;

p.Y= center_pos.Y+R*sin(fi+j*2*pi/i)/2;

}

control_points->SetValue(p, j); //Очередная вершина задана.

}

//Рисование фигуры (на битовой матрице).

g->FillPolygon(liner,control_points);

/* PictureBox является контейнером для отображения точечного рисунка. Воспользуемся его свойством Image для вывода битового изображения из буфера на экран.*/

animation_box->Image=canvas;

i++;

R+=5; //Увеличение радиуса окружности, задающей многоугольник.

}

else

/*Остановка таймера. Поскольку затирание изображения не производится, последний кадр останется на экране.*/

my_timer->Enabled=false;

}





Дата публикования: 2015-04-10; Прочитано: 401 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.01 с)...