Этот класс будет главной частью программы, в которой создается и выводится на экран звездчатый многоугольник. Приведем программную реализацию. Для создания приложения достаточно перенести на главную форму Form1 компонент Image со страницы Additional, а затем набрать следующий текст Unit1.cpp и запустить компиляцию, сборку и выполнение, выбрав пункт меню Run. Текст программы Unit1.cpp:
Листинг 6.1. Построение звездчатого полигона
//---- построение звездчатого полигона ---------------------------#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//--------------------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#include <math.h>
#define PI 3.14159
class Wnd;
struct Pnt // структура точки
{
float x, y; // координаты точки
int code(Pnt q); // код четверти точки q
float operator*(Pnt q); // ориентированная площадь
Pnt operator-(Pnt q); // разность векторов
};
int Pnt::code(Pnt q) // код четверти
{ // начало координат - в точке (x, y)
if(q.x - x >= 0 && q.y - y >= 0) return 0; // первая четверть
if(q.x - x < 0 && q.y - y >= 0) return 1; // вторая четверть
if(q.x - x < 0 && q.y - y < 0) return 2; // третья четверть
return 3; // во всех остальных случаях
}
float Pnt::operator*(Pnt q)
{
return x * q.y - y * q.x; // ориентированная площадь параллелограмма
}
Pnt Pnt::operator-(Pnt q)
{
Pnt t; t.x = x - q.x; t.y = y - q.y; return t;// разность векторов
}
int operator<(Pnt p, Pnt q)
{
Pnt t; // сравнение углов радиус-векторов
t.x = 0; t.y = 0; // точки p и q относительно (0, 0)
if(t.code(p) < t.code(q)) return 1;
if(t.code(p) > t.code(q)) return 0;
if(p * q == 0) return p.x * p.x + p.y * p.y < q.x * q.x + q.y * q.y;
else return p * q > 0;
}
class SPolygon // звездчатый многоугольник
{
TColor color; // цвет точек многоугольника
int n; // количество вершин
Pnt *p; // массив вершин
Pnt pC; // центр тяжести
public:
friend class Wnd;
SPolygon(float *x, float *y, int m, TColor cl);
SPolygon(const SPolygon &ob);
int isin(Pnt t);
~SPolygon()
{
delete []p;
}
};
// Конструктор копирования
SPolygon::SPolygon(const SPolygon &ob) // необходим для передачи объекта
{ // в качестве параметра
int i;
n = ob.n;
p = new Pnt[n]; // выделим память
for(i=0; i < ob.n; i++) p[i]=ob.p[i]; // производим копирование
}
SPolygon::SPolygon(float *x, float *y, int m, TColor cl)
:color(cl) // цвет точек
{
int i, j;
Pnt t;
p=new Pnt[m];
n = m; pC.x = 0.; pC.y = 0.;
for(i = 0; i < m; i++)
{
pC.x += x[i]; pC.y += y[i]; // вычисление координат
p[i].x = x[i]; p[i].y = y[i]; // центра тяжести
}
pC.x=pC.x/m; pC.y=pC.y/m;
for(i = 1; i < m; i++)
{
t = p[i]; // сортировка методом вставок
for(j = i - 1; (j >= 0) && ((t - pC) < (p[j] - pC)); j--)
p[j + 1] = p[j]; // по величине угла
p[j + 1] = t;
}
}
// тест на принадлежность методом углов
int SPolygon::isin(Pnt t)
{
// 0 - если точка t не принадлежит многоугольнику,
// не 0 - в других случаях
int i, ind = 0; // индекс точки
Pnt q = p[n - 1];
for(i = 0; i < n; i++)
{
if(t.code(q) == t.code(p[i])) ; // ничего не делать
else if((t.code(p[i]) - t.code(q) + 3)%4 == 0) ind++;
else if((t.code(p[i]) - t.code(q) + 1)%4 == 0) ind--;
else if((p[i] - q) * (t - q) > 0) ind += 2;
else ind -= 2;
q = p[i];
}
if(ind==0) return 0; else return 1;
}
class Wnd // класс окна
{
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.