if(((s[a] - s[k]) * (s[i] - s[k]) > 0.0) ||
((s[a] - s[k]) * (s[i] - s[k]) == 0.0 && fabs(s[a] - s[k])
< fabs(s[i] - s[k]))) a = i;
}
if(a == m) break;
}
n = j; p = new Pnt [n];
for(i = 0; i < n; i++) p[i] = pp[i];
delete []s; delete []pp;
}
int CPolygon::isin(Pnt t)
{
int i,j, parity = 0;
for(i = 0, j=n-1; i < n; j=i++)
{
if (( ( (p[i].y<=t.y)&&(t.y<p[j].y) )||
((p[j].y<=t.y)&&(t.y<p[i].y)))&&
(t.x<(p[j].x-p[i].x)*(t.y-p[i].y)/
(p[j].y-p[i].y)+p[i].x))
parity=1-parity;
}
return parity;
}
//--------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
randomize();
maxX= Form1->Image1->Width;
maxY= Form1->Image1->Height;
}
//--------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender)
{
float rad = 150, *x, *y; // радиус окружности и
// вершины 2mm-угольника
int i;
int mm = random(10)+2;
x = new float[2 * mm]; y = new float [2 * mm];
for(i = 0; i < mm; i++)
{
// вершины большого 2mm-угольника
x[i] = rad * cos(2. * PI * i / mm);
y[i] = rad * sin(2. * PI * i / mm);
// вершины маленького 2mm-угольника
x[i + mm] = rad * cos(2. * PI * i / mm + PI / mm) / 2;
y[i + mm] = rad * sin(2. * PI * i / mm + PI / mm) / 2;
}
for(i = 0; i < 2 * mm; i++) x[i] += random(100) - 50;
Form1->Image1->Canvas->FillRect(TRect(0,0,maxX,maxY));
CPolygon cpoly(x, y, 10, clLtGray); // построение выпуклой оболочки
cpoly.show(-300, -300, 300, 300); // вывод выпуклой оболочки
Form1->Image1->Canvas->Brush->Color = (TColor)clWhite;//восстановление кисти
Pnt f = {0., 0.};
for(i = 0; i < 2 * mm; i++)
{
f.x = x[i]; f.y = y[i];
if(cpoly.isin(f))
Form1->Image1->Canvas->Rectangle((int)(x[i] + 300.) * maxX / 600 - 1,
(int)((300. - y[i]) * maxY / 600 - 1),
(int)((x[i] + 300.) * maxX / 600) + 1,
(int)((300. - y[i]) * maxY / 600) + 1);
}
delete []x; delete []y;
}
//--------------------------------------------------------------------------Результат работы программыприведен на рис. 6.12.
Рис. 6.12. Выпуклая оболочка, построенная методом заворачивания подарка
Оценим сложность алгоритма построения выпуклой оболочки методом заворачивания подарка.
Так как все m точек множества M могут быть вершинами его выпуклой оболочки, а рассматриваемый алгоритм затрачивает на нахождение каждой точки оболочки линейное время, то время выполнения в худшем случае равно O (m2). Если в действительности число вершин выпуклой оболочки равно h, то время выполнения алгоритма Джарвиса будет равно O (hm). Поэтому этот алгоритм особенно эффективен в тех случаях, когда заранее известно, что число сторон выпуклой оболочки ограничено некоторой константой h.
![]() |
Рис. 6.13. Метод обхода Грэхема
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.