Построение многоугольников и многогранников, страница 4

Этот класс будет главной частью программы, в которой создается и выводится на экран звездчатый многоугольник. Приведем программную реализацию. Для создания приложения достаточно перенести на главную форму 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                                           // класс окна

{