![]() |
Главная Случайная страница Контакты | Мы поможем в написании вашей работы! | |
|
Рассмотрим ещё один пример: по нажатию на кнопку в произвольной точке экрана возникает треугольник; увеличиваясь, фигура трансформируется в звездочку («примеры: простейшая анимация», кнопка «трансформация»). Для рисования используется поверхность компонента 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; Прочитано: 414 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!