Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
374.doc
Скачиваний:
11
Добавлен:
30.04.2022
Размер:
3.16 Mб
Скачать

7.3. Рисование геометрических фигур

Пером можно рисовать не только прямые линии, но и фигуры. В табл. 7.1 – 7.3 приведены основные свойства и методы для объекта Pen. Объект позволяет закрашивать замкнутые области.

Пример 3. Нарисуйте и закрасьте программным способом фигуры, приведенные в табл. 7.3.

Для выполнения поставленной задачи, создайте проект и разместите на форме объект Image и девять командных кнопок. Сделайте на них надписи, как показано на рис. 7.2.

Для каждой командной кнопки напишите функцию обработки события Click, как показано на листинге 3. Для построения фигур необходимо определить значения координат основных точек фигур в соответствии с обозначениями, приведенными в табл. 7.3.

Рис. 7.3. Форма с отображением построенных фигур

Листинг программы построения примитивных геометрических фигур приведен в листинге.

Задание. Напишите код программы, приведенный в листинге и напишите комментарии к операторам программы в соответствии с тем, какие фигуры они позволяют строить.

Листинг 7.4

Программа построения геометрических фигур

#include <vcl.h>

#pragma hdrstop

#include "UnRis2.h"

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

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

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

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

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Image1->Canvas->Font->Style<<fsBold;

Image1->Canvas->Arc(10,10,90,90,90,50,10,50);

Image1->Canvas->TextOut(40,60,"Arc");

}

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

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Form1->Close();

}

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

void __fastcall TForm1::Button3Click(TObject *Sender)

{

Image1->Canvas->Brush->Color= clRed;

Image1->Canvas->Chord(110,10,190,90,190,50,110,50);

Image1->Canvas->TextOut(135,60,"Chord");

}

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

void __fastcall TForm1::Button4Click(TObject *Sender)

{

Image1->Canvas->Brush->Color= clBlue;

Image1->Canvas->Ellipse(210,10,290,50);

Image1->Canvas->TextOut(230,60,"Ellipse");

}

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

void __fastcall TForm1::Button5Click(TObject *Sender)

{

Image1->Canvas->Brush->Color= clGreen;

Image1->Canvas->Pie(310,10,390,90,390,30,310,35);

Image1->Canvas->TextOut(340,60,"Pie");

}

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

void __fastcall TForm1::Button6Click(TObject *Sender)

{

Image1->Canvas->Brush->Color=clAqua ;

points[0].x =30; points[0].y =150;

points[1].x =40; points[1].y =130;

points[2].x =40; points[2].y =140;

points[3].x =60; points[3].y =130;

points[4].x =170; points[4].y =150;

Image1->Canvas->Polygon(points,4);

Image1->Canvas->TextOut(30,170,"Polygon");

}

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

void __fastcall TForm1::Button7Click(TObject *Sender)

{

points[0].x = 200; points[0].y = 100;

points[1].x = 220; points[1].y = 150;

points[2].x = 250; points[2].y = 120;

points[3].x = 280; points[3].y = 180;

points[4].x = 300; points[4].y = 150;

Image1->Canvas->Polyline(points,4);

Image1->Canvas->TextOut(250,170,"Polyline");

}

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

void __fastcall TForm1::Button8Click(TObject *Sender)

{

Image1->Canvas->Brush->Color= clLime;

Image1->Canvas->Rectangle(330,170,480,100);

Image1->Canvas->TextOut(340,170,"Rectangle");

}

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

void __fastcall TForm1::Button9Click(TObject *Sender)

{

Image1->Canvas->Brush->Color= clMaroon;

Image1->Canvas->RoundRect(500,170,580,100,20,20);

Image1->Canvas->TextOut(540,170,"RoundRect");

}

При разработке данной программы использовалась переменная points типа TPoint, объявление которой должно быть проведено в заголовочном модуле формы. Для вывода текста на канву используется метод TextOut. Для закрашивания замкнутых областей используется объект Brush и его свойство Color , которому присваивается значение цвета заливки.

Пример 7.4. Создадим программу, рисующую олимпийскую символику.

Целью этого примера является освоение использования функций построения геометрических примитивов для построения более сложного рисунка.

Алгоритм решения данной задачи состоит в следующем:

1 Необходимо рассчитать, на каком расстоянии должны располагаться центры колец и каковы должны быть диаметры колец, чтобы они пересекались.

2. Необходимо определить размеры окна (полотна), на котором будут рисоваться кольца.

3. Определить место и размеры размещения надписи.

Все эти расчеты можно провести с использованием линейки, карандаша и циркуля, нарисовав макет. В качестве единиц измерения используются пиксели. Готовая программа должна выводить на печать олимпийскую символику, показанную на рис. 7.4.

Листинг программы с подробными комментариями приводится ниже.

Рис. 7.4. Интерфейс пользователя программы, рисующей олимпийскую символику

Листинг 7.5

Программа, рисующая олимпийскую символику

#pragma package(smart_init)

#pragma resource "*.dfm"

TFOLIMP *FOLIMP;

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

__fastcall TFOLIMP::TFOLIMP(TComponent* Owner)

: TForm(Owner)

{

Canvas->Font->Name="Tahoma";

FOLIMP->Canvas->Font->Size=25;

}

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

void __fastcall TFOLIMP::Button1Click(TObject *Sender)

{

FOLIMP->Close();

}

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

void __fastcall TFOLIMP::FormPaint(TObject *Sender)

{

#define WB 140 //ширина полотнища

#define HB 160 //высота полотнища

#define D 100 //диаметр колец

int x,y;

AnsiString st ="Быстрее, выше, сильнее!";

// определим координаты левого верхнего угла флага

x =(ClientWidth-WB)/2;

y = (ClientHeight- HB)/2 - Canvas->Font->Size;

// полотнище

// выбираем цвет полотнища – белый

Canvas ->Brush->Color = (TColor)RGB(255,255,255);

//Рисуем прямоугольник полотнища

Canvas -> Rectangle(x-WB,y-HB/2,x+1.8*WB,y+HB);

int x1 = (ClientWidth- Canvas -> TextWidth(st))/2;

/*Чтобы область вывода текста не была закрашена цветом

фона, а также чтобы метод Ellipse рисовал окружность,

а не круг, значение свойства Brush-> Syle

должно быть равно bsClear */

Canvas -> Brush->Style= clWhite;

//bsClear;

//вывод девиза

Canvas -> TextOutA(x1,y+HB+6,st);

// ширина колец – 2 пикселя

Canvas -> Pen->Width=5;

//первый ряд колец

//*3,2*D – ширина области, занимаемая кольцами

первого ряда*/

x = x + (WB-3.2*D)/2;

y =y +(HB-1.8*D)/2;

Canvas -> Pen->Color= (TColor)RGB(0,0,225); //синий

Canvas -> Ellipse(x,y,x+D,y+D);

x= x +1.1*D;

Canvas -> Pen->Color= clBlack; //черный

Canvas -> Ellipse(x,y,x+D,y+D);

x= x +1.1*D;

Canvas -> Pen->Color= (TColor)RGB(225,0,0); //красный

Canvas -> Ellipse(x,y,x+D,y+D);

// рисуем второй ряд колец

x= x - D*0.55;

y = y + 0.6*D;

Canvas -> Pen->Color= (TColor)RGB(0,128,0); //зеленый

Canvas -> Ellipse(x,y,x+D,y+D);

x= x-D*1.1;

Canvas -> Pen->Color= (TColor)RGB(250,217,25);//желтый

Canvas -> Ellipse(x,y,x+D,y+D);

}

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

void __fastcall TFOLIMP::FormResize(TObject *Sender)

{

FOLIMP->Refresh();

}

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

Пример 7.5. Разработаем программу, рисующую на форме часы, показывающие текущее время с точностью до секунд.

Алгоритм разработки программы включает следующие частные задачи:

  1. Нарисовать на форме циферблат часов с разметкой делений часов, минут и секунд.

  2. Рассматривая часовую, минутную и секундную стрелки как вектора, определить функции изменения углового положения векторов в зависимости от текущего времени.

  3. Определить функцию, рисующую положение стрелок на циферблате через каждую секунду, отсчитываемую таймером, в зависимости от текущего времени.

  4. Определить функцию, стирающую стрелки в предшествующие моменты времени. Вид формы с часами приведен на рис. 7.5.

Рис. 7.5. Интерфейс пользователя программы «Часы»

При написании кода программы для получения значений текущего времени использовалось системное время компьютера, а для перевода значений времени в формат часов, минут и секундную – функции класса TDateTime. Функции рисования циферблата и стрелок для текущего времени – функция void DrawClock() создавались с использованием метода рисования пером. Функция определения углового положения концов векторов стрелок для текущего времени используют стандартные математические функции, поэтому в заголовочный файл формы должен быть включен файл math.h.

Для отсчета секундных интервалов времени применялся объект Timer, который включался при загрузке программы и через каждую секунду вызывал функцию рисования стрелок. Для контроля правильности хода часов используется объект Edit.

Листинг 7.7

Программа часы

include <vcl.h>

#pragma hdrstop

#include "UOclok.h"

#include <DateUtils.hpp>

#include <math.h>

#include <Math.hpp>

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

#pragma package(smart_init)

#pragma resource "*.dfm"

TFOclok *FOclok;

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

int x0,y0; //центр циферблата

int x,y; //текущие координаты конца стрелок

TDateTime t;

int l,a;

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

//в конструкторе формы записывается все то, что должно быть создано на форме при ее загрузке

__fastcall TFOclok::TFOclok(TComponent* Owner)

: TForm(Owner)

{

int ahr,amin,asec; //положение стрелок (угол)

TDateTime t;

//зададим размер формы

//в соответствии с размерами циферблата

ClientHeight =(R+80)*2;

ClientWidth=(R+80)*2;

x0=R+80;

y0=R+80;

t=Time();

// пуск таймера

Timer1->Interval=1000; // период сигнала от таймера – 1 сек

Timer1->Enabled = true;

}

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

//Функция определения координат векторов стрелок часов

void Vector(int X0,int Y0, int A,int l1)

{

//x0 – начало вектора

//a – угол между осью х и вектором

// l – длина вектора

int x,y; //координаты конца вектора

double const TORAD = 0.01745532; //коэффициент

//пересчета угла

// из градусов в радианы

FOclok -> Canvas->MoveTo(X0,Y0);

x = X0 + l1*cos(A*TORAD);

y = Y0 - l1*sin(A*TORAD);

FOclok ->Canvas ->LineTo (x,y);

}

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

// Функция рисования стрелок

void DrawClock()

{

int ahr,amin,asec; //положение стрелок (угол)

TDateTime t;

t =Time();//текущее время

//стирание стрелок в предыдущий момент времени

// определение углового положения стрелок

// в предыдущий момент времени

ahr =90 -HourOfTheDay(t)*30-((MinuteOfTheHour(t)/12)*6+6);

amin =90-MinuteOfTheHour(t)*6+6;

asec =90-SecondOfTheMinute(t)*6+6;

//стирание часовой стрелки

FOclok ->Canvas->Pen->Color= clWhite;

FOclok ->Canvas ->Pen->Width = 3;

Vector(x0,y0,ahr,(R-30));

// стирание минутной стрелки

FOclok ->Canvas->Pen->Color=clWhite;

FOclok ->Canvas ->Pen->Width = 5;

Vector(x0,y0,(amin-1),(R-15));

//стирание секундной стрелки

FOclok ->Canvas-> Pen->Color=clWhite;

FOclok ->Canvas ->Pen->Width = 1;

Vector(x0,y0, asec,(R-7));

// новое положение стрелок

/* определить положение стрелок

Угол между метками (цифрами0 часов, например, 2 и 3 составляет 30 градусов, угол между метками минут – 6 градусов. Угол отсчитываем от метки 12 часов*/

ahr =90 -HourOfTheDay(t)*30-(MinuteOfTheHour(t)/12)*6;

amin =90-MinuteOfTheHour(t)*6;

asec =90-SecondOfTheMinute(t)*6;

//нарисовать стрелки

// часовую стрелку

FOclok ->Canvas ->Pen->Width = 3;

FOclok->Canvas->Pen->Color=clBlack;

Vector(x0,y0,ahr,R-30);

//минутную стрелку

FOclok ->Canvas ->Pen->Width=2;

FOclok-> Canvas->Pen-> Color = clRed;

Vector(x0,y0,amin,R-15);

//секундную стрелку

FOclok ->Canvas ->Pen->Width=1;

FOclok ->Canvas->Pen-> Color=clBlue;

Vector(x0,y0,asec,R-7);

}

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

// функция обработки выдачи интервалов отсчета таймера

void __fastcall TFOclok::Timer1Timer(TObject *Sender)

{

DrawClock(); // обращение к функции рисования стрелок

Edit1->Text= "";

t= Time();

Edit1->Text= t; // вывод текущего времени в текстовое окно

}

// функция обработки события командной кнопки «Exit»

void __fastcall TFOclok::Button1Click(TObject *Sender)

{

FOclok->Close();

}

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

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

//на форме циферблата часов

void __fastcall TFOclok::FormPaint(TObject *Sender)

{

double TORAD = 0.01745532; //коэффициент пересчета угла

//из градусов в радианы

int x,y;

int a;

int h;

TBrushStyle bs;

TColor pc;

char pw;

bs = Canvas->Brush->Style;

pc= Canvas->Pen->Color;

Canvas->Pen->Width=2;

pw =Canvas->Pen->Width;

Canvas -> Brush->Style = bsClear;

Canvas -> Pen->Width ;

Canvas->Pen->Color = clBlack;

a = 0;

h = 3;

while (a<360)

{

x=x0 +R*cos(a*TORAD);

y=y0 -R*sin(a*TORAD);

FOclok->Canvas->MoveTo(x,y);

if ((a%30)==0)

{

Canvas->Ellipse(x-2,y-2,x+3,y+3); //рисование меток

//на циферблате

x = x0+(R+15)*cos(a*TORAD);

y = y0-(R+15)*sin(a*TORAD);

Canvas->TextOut(x-5,y-7,IntToStr(h)); //оцифровка

h--;

if(h==0)h=12;

}

else

Canvas->Ellipse(x-1,y-1,x+1,y+1);

a=a+6;

Canvas -> Brush->Style = bs;

Canvas -> Pen->Width =pw;

Canvas->Pen->Color = pc;

}

}

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

При аккуратном и внимательном наборе кода программы, она будет работать и отображать текущее время. Код программы с подробнейшими комментариями, позволяющими уяснить основы создания движущихся объектов, приведен в листинге 7.6.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]