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

length (v)/length((p1-p0)&(p2-p0));

xp[0]= ex(p0); yp[0]= ey(p0);

xp[1]= ex(p1); yp[1]= ey(p1);

xp[2]= ex(p2); yp[2]= ey(p2);

if (cosg<0) cosg=0;

cosg=(1.+2*cosg)/3;

fillpoly(xp, yp, 3, (TColor)RGB(255*cosg,255*cosg,255*cosg),

(TColor)RGB(255*cosg,255*cosg,255*cosg));

}

struct face

{

Pnt3 p0, p1, p2;

struct face *prev, *next;

};

struct edge

{

Pnt3 p0, p1; // вершины ребра

struct edge *prev, *next;

};

edge *append(edge *first, Pnt3 q0, Pnt3 q1)

{

edge *e = new edge, *cur =first;

e->p0 =q0; e->p1 = q1;

e ->prev = e ->next = NULL;

if (cur==NULL) return e;

while(cur->next) cur = cur->next;

cur->next=e;

e->prev=cur;

return first;

}

edge *deledge(edge *first, edge *e)

{

if (e==first)

{

first= first->next; delete e;

if (first) first->prev=NULL; return first;

} else

if (e->next==NULL)

{

(e->prev)->next = NULL; delete e; return first;

} else

{

(e->prev)->next=e->next;

(e->next)->prev=e->prev; delete e; return first;

}

}

edge *xoredge(edge *first, Pnt3 q0, Pnt3 q1)

{

edge *cur = first; int i=0;

if (first==NULL)          // если список пуст

{

first = append(first, q0, q1); return first;

}

while (cur)

{

if (((cur->p0)==q1)&&((cur->p1)==q0))

{

first = deledge(first, cur); return first;

} else cur = cur -> next;

}

first = append(first, q0, q1); return first;

}

class convex

{

face *ff;

public:

void append(Pnt3 pt0, Pnt3 pt1, Pnt3 pt2);

void delface(face *cur);

int addpnt(Pnt3 v);

void display();

convex operator=(convex c);

convex(){ff=NULL;};

convex(Pnt3 pt0, Pnt3 pt1, Pnt3 pt2, Pnt3 pt3);

convex(Pnt3 *pt, int n);

} ;

void convex::append(Pnt3 pt0, Pnt3 pt1, Pnt3 pt2)

{

face *ft= new face, *fcur=ff;

ft->p0=pt0; ft->p1=pt1; ft->p2=pt2;

ft->prev=NULL; ft->next=NULL;

if (ff==NULL) ff=ft;

else

{

while(fcur->next) fcur=fcur->next;

fcur->next= ft;

ft->prev=fcur;

}

}

void convex::delface(face *cur)

{

if (cur==NULL) return;

if (cur==ff)

{

ff=ff->next;

delete cur; ff->prev=NULL; return;

}

if (cur->next==NULL)

{

(cur->prev)->next=NULL;

delete cur; return;

}

(cur->prev)->next=cur->next;

(cur->next)->prev=cur->prev; delete cur;

}

int convex::addpnt(Pnt3 v)

{

face *cur =ff;

while (cur)

{

if (vol(cur->p0,cur->p1,cur->p2,v)>0) break;

cur = cur->next;

}

if(!cur) return 0;

face *curnext; cur = ff;

while(cur)

{

curnext = cur ->next;

if (vol(cur->p0,cur->p1,cur->p2,v)>0) delface(cur);

cur = curnext;

}

edge *fe=NULL; cur =ff;

while (cur)

{

fe=xoredge(fe,cur->p1,cur->p0);

fe=xoredge(fe,cur->p2,cur->p1);

fe=xoredge(fe,cur->p0,cur->p2);

cur = cur->next;

}

while(fe)

{

append(fe->p0,fe->p1,v);

fe=fe->next;

}

}

void convex::display()

{

face *fcur=ff;

Pnt3 v(xv,yv,zv);

Bitmap->Canvas->FillRect(Rect(0,0,maxX,maxY));

for(;fcur;fcur=fcur->next)

if (vol(fcur->p0,fcur->p1,fcur->p2,v)>0) // выводим, если грань видима

filltriangle(fcur->p0, fcur->p1, fcur->p2);

Form1->Image1->Canvas->CopyRect(Rect(0,0,maxX,maxY),Bitmap->Canvas,

Rect(0,0,maxX,maxY));

}

convex convex::operator=(convex c)

{

face *fcur=ff;

while(ff)

{

delete fcur; ff=ff->next; fcur=ff;

}

fcur=c.ff;

while (fcur)

{

append (fcur->p0, fcur->p1, fcur->p2);

fcur=fcur->next;

}

}

convex::convex(Pnt3 pt0, Pnt3 pt1, Pnt3 pt2, Pnt3 pt3)

{

float volume;

Pnt3 p[4];

ff=NULL;

volume=vol(pt0, pt1, pt2, pt3);

if (fabs(volume)<0.00001)

{

Form1->Image1->Canvas->TextOut(10,10,"Complanar Points");

return;

} else

{

if (volume<0)

{

p[0]=pt0; p[1]=pt1; p[2]=pt2; p[3]=pt3;

} else

{

p[3]=pt0; p[2]=pt1; p[1]=pt2; p[0]=pt3;

}

append(p[1],p[2],p[3]);

append(p[0],p[3],p[2]);

append(p[0],p[1],p[3]);

append(p[0],p[2],p[1]);

}

}

convex::convex(Pnt3 *pt, int n)