IsLi int classifvFacet (BSPNode * node, Facet& f)
{
int positive = 0; int negative = 0;
for (int i = 0; i < f.count; i++ ) {
float res = f.p [i] & node -> n - node -> d;
10. Удаление невидимых линий и поверхностей
if (res > EPS ) positive++;
else
if (res < -EPS ) negative++;
}
if ( positive > 0 && negative == 0 ) return IN_POSITIVE;
else
if ( positive == 0 && negative > 0 ) return IN_NEGATIVE;
else
if ( positive < 1 && negative < 1 ) return IN_PLANE;
else
return IN_BOTH;
}
При разбиении грани плоскостью производится классификация всех вершин грани относительно этой плоскости и разбиение тех ребер, вершины которых лежат в разных полупространствах; сами точки разбиения считаются принадлежащими каждому из получившихся многоугольников (рис. 10.37).
Ниже приведена процедура разбиения грани плоскостью. Причем считается, что грань действительно разбивается плоскостью на две непустые части, и поэтому случай, когда какое-либо ребро грани лежит в плоскости разбиения, исключается в силу выпуклости граней.
§3 void splitFacet(BSPNode * node, Facet& f, Facet **f1, Facet **f2) {
Vector3D p1 [MAX_POINTS];
Vector3D p2 [MAX_POINTS];
Vector prevP = f.p [f.count - 1];
float prevF = prevP & node -> n - node -> d;
int countl = 0;
int count2 = 0;
for (int i = 0; i < f.count; i++ )
{
Vector curP = f.p [i];
float curF = curP & node -> n - node -> d;
if ( curF >= 0. && prevF <= 0 ) p1 [countl++] = curP;
else
if ( curF < 0 && prevF >= 0 ) p2 [count2++] = curP;
else
if ( curF < 0 && prevF > 0 )
Компьютерная графика. Полигональные модели
{
float t = - curF / ( prevF - curF ); Vector3Q sp = curP'+ t * ( prevP - curP );
p1 [count1++] = sp; p2 [count2++] - sp; p2 [count2++] = curP;
}
else
if ( curF > 0 && prevF < 0 ) {
float t = - curF / ( prevF - curF ); Vector3D sp = curP + t * ( prevP - curP );
p1 [count1++] = sp; p2 [count2++] = sp; p1 [count1++] = curP;