Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабы / Roma / PLANE

.CPP
Скачиваний:
20
Добавлен:
16.04.2013
Размер:
5.46 Кб
Скачать
#include "vector.cpp"
class PLANE {
public :
enum { LINEINPLANE, PARALLEL, INTERSECTION };
VECTOR Normal;
POINT Point;

/* The `d' value from ax+bx+cx+d=0 */
REAL d;

/* Operation to create
a null plane. */
PLANE ( void );

PLANE ( VECTOR& n, POINT& Point );
void Set ( VECTOR& n, POINT& Point );
int Intersection ( POINT *p1, POINT *p2, POINT *Result );
BOOL IsInside ( POINT *p );

/* Clip a polygon
to the plane. */
int Intersection ( POINT *p1, POINT *p2, POINT *Result, INTPOINT *t1, INTPOINT *t2, INTPOINT *tResult );

/* Clip a textured
polygon to a plane. */
BOOL Clip ( int *nVerts, POINT *In, POINT *Out, INTPOINT *InTex, INTPOINT *OutTex );

/* Project a polygon onto a plane
( shadow attenuation ). */
// void Project ( POINT *Light, int nVerts, POINT *In, POINT *Out );

};

// Create a plane object with undefined location and normal. //

PLANE :: PLANE ( void ){
}

// Create a plane using a point on the plane and the normal to the plane. //

PLANE :: PLANE ( VECTOR& n, POINT& Point ){
Set ( n, Point );
}

// Assign a plane using a point on the plane and the normal to the plane. //

void PLANE :: Set ( VECTOR& n, POINT& p ){
Point = p;
Normal = n;
d = -Normal.Dot ( ( VECTOR& ) Point );
}

// Calculates the intersection of a line and a plane. //

int PLANE :: Intersection ( POINT *p1, POINT *p2, POINT *Result, INTPOINT *t1, INTPOINT *t2, INTPOINT *tResult ){
REAL t, p, q;
VECTOR r ( *p2 );

r -= *p1;
p = Normal.Dot ( ( VECTOR& ) *p1 ) + d;
q = Normal.Dot ( ( VECTOR& ) r );
if ( q == 0 ) {
if ( p == 0 ) {

// The line was in the plane.
return ( LINEINPLANE );
} else {

// Does not intersect at all.
return ( PARALLEL );
}
}

// From x = x1 + ( x2 - x1 ) find the t value.
t = - ( p / q );
r *= t;

// Store back into result.
*Result = *p1;
*Result += r;

// Find out how much the line changed by.
VECTOR Old ( p1, p2 ), New ( p1, Result );
REAL Scale, lOld, lNew;

// Get the lengths of the lines.
lOld = Old.Length ();
lNew = New.Length ();

// Find the scale value.
Scale = ( lNew / lOld );

// Alter the texture co-ordinates.
tResult->x = t1->x + ( ( REAL ) ( t2->x - t1->x ) * Scale );
tResult->y = t1->y + ( ( REAL ) ( t2->y - t1->y ) * Scale );

// Intersection is in `Result'.
return ( INTERSECTION );
}

// Calculates the intersection of a line and a plane. //

int PLANE :: Intersection ( POINT *p1, POINT *p2, POINT *Result ){
REAL t, p, q;
VECTOR r ( *p2 );

r -= *p1;
p = Normal.Dot ( ( VECTOR& ) *p1 ) + d;
q = Normal.Dot ( ( VECTOR& ) r );
if ( q == 0 ) {
if ( p == 0 ) {

// The line was in the plane.
return ( LINEINPLANE );
} else {

// Does not intersect at all.
return ( PARALLEL );
}
}

// From x = x1 + ( x2 - x1 ) * t find the t value.
t = - ( p / q );
r *= t;

// Store back into result.
*Result = *p1;
*Result += r;

return ( INTERSECTION );
}

// Determine which side of a plane a point lies on. //

BOOL PLANE :: IsInside ( POINT *p ){
REAL Result;
VECTOR Temp ( Point, *p );
Result = Normal.Dot ( Temp );
return ( ( Result < 0 ) );
}

// Clips a polygon to this plane. //

BOOL PLANE :: Clip ( int *nVerts, POINT *In, POINT *Out, INTPOINT *InTex, INTPOINT *OutTex ){
int i, Next;
BOOL cIsIn, nIsIn;
POINT *cIn = In, *cOut = Out;
INTPOINT *tIn = InTex, *tOut = OutTex;

// If x < z, then point is outside plane.
cIsIn = IsInside ( &cIn [0] );
if ( ( InTex != NULL ) && ( OutTex != NULL ) ) {
for ( i = 0; i < *nVerts; i++ ) {
// Keep first vertex if it's inside plane.
if ( cIsIn == TRUE ) {
*cOut++ = *cIn;
*tOut++ = *tIn;
}
// Get the next vertex.
Next = ( i + 1 ) % *nVerts;
// Classify with respect to the plane.
nIsIn = IsInside ( &In [Next] );
// If either is outside the plane, add clipped vertex.
if ( nIsIn != cIsIn ) {
Intersection ( cIn, &In [Next], cOut++, tIn, &InTex [Next], tOut++ );
}
// Make the next result the current result.
cIsIn = nIsIn;
// And go to the next input vertex.
cIn++;
tIn++;
}
} else {
// Clipping without texture clipping.
for ( i = 0; i < *nVerts; i++ ) {
// Keep first vertex if it's inside plane.
if ( cIsIn == TRUE ) {
*cOut++ = *cIn;
}
// Get the next vertex.
Next = ( i + 1 ) % *nVerts;
// Classify with respect to the plane.
nIsIn = IsInside ( &In [Next] );
// If either is outside the plane, add clipped vertex.
if ( nIsIn != cIsIn ) {
Intersection ( cIn, &In [Next], cOut++ );
}
// Make the next result the current result.
cIsIn = nIsIn;
// And go to the next input vertex.
cIn++;
}
}

// Find the total number of emitted vertices.
*nVerts = ( int) ( cOut - Out );
// And return the result of clipping.
if ( *nVerts < 3 ) {
return ( FALSE );
} else {
return ( TRUE );
}
}

// Projects a polygon from a light source onto a plane. //

/*void PLANE :: Project ( POINT *Light, int nVerts, POINT *In, POINT *Out ){
int i;

for ( i = 0; i < nVerts; i++ ) {
Intersection ( Light, &In [i], &Out [i], NULL, NULL, NULL );
}
} */

Соседние файлы в папке Roma