#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#include <sys/stat.h>
#define X 0
#define Y 1
//typedef enum { FALSE, TRUE } bool;
#define DIM 2 /* Dimension of points */
typedef int tPointi[DIM]; /* type integer point */
typedef double tPointd[DIM]; /* type double point */
#define PMAX 10000 /* Max # of pts in polygon */
typedef tPointi tPolygoni[PMAX];/* type integer polygon */
char InPoly( tPointi q, tPolygoni P, int n );
void PrintPoly( int n, tPolygoni P );
void PrintPoint( tPointi p );
void Copy ( tPolygoni a, tPolygoni b , int n );
int ReadPoly( tPolygoni P ) ;
main()
{
int n;
tPolygoni P, Porig;
tPointi q;
n = ReadPoly( P );
Copy( P, Porig, n );
while( scanf( "%d %d", &q[X], &q[Y]) != EOF ) {
printf( "InPoly = %c/n", InPoly( q, P, n ) );
/* Refill the destroyed polygon with original. */
Copy( Porig, P, n );
}
}
/*
InPoly returns a char in {i,o,v,e}. See above for definitions.
*/
char InPoly( tPointi q, tPolygoni P, int n )
{
int i, i1; /* point index; i1 = i-1 mod n */
int d; /* dimension index */
double x; /* x intersection of e with ray */
int Rcross = 0; /* number of right edge/ray crossings */
int Lcross = 0; /* number of left edge/ray crossings */
printf("/n==>InPoly: q = "); PrintPoint(q); putchar('/n');
/* Shift so that q is the origin. Note this destroys the polygon.
This is done for pedogical clarity. */
for( i = 0; i < n; i++ ) {
for( d = 0; d < DIM; d++ )
P[i][d] = P[i][d] - q[d];
}
/* For each edge e=(i-1,i), see if crosses ray. */
for( i = 0; i < n; i++ ) {
/* First see if q=(0,0) is a vertex. */
if ( P[i][X]==0 && P[i][Y]==0 ) return 'v';
i1 = ( i + n - 1 ) % n;
/* printf("e=(%d,%d)/t", i1, i); */
/* if e "straddles" the x-axis... */
/* The commented-out statement is logically equivalent to the one
following. */
/* if( ( ( P[i][Y] > 0 ) && ( P[i1][Y] <= 0 ) ) ||
( ( P[i1][Y] > 0 ) && ( P[i] [Y] <= 0 ) ) ) { */
if( ( P[i][Y] > 0 ) != ( P[i1][Y] > 0 ) ) {
/* e straddles ray, so compute intersection with ray. */
x = (P[i][X] * (double)P[i1][Y] - P[i1][X] * (double)P[i][Y])/(double)(P[i1][Y] - P[i][Y]);
/* printf("straddles: x = %g/t", x); */
/* crosses ray if strictly positive intersection. */
if (x > 0) Rcross++;
}
/* printf("Right cross=%d/t", Rcross); */
/* if e straddles the x-axis when reversed... */
/* if( ( ( P[i] [Y] < 0 ) && ( P[i1][Y] >= 0 ) ) ||
( ( P[i1][Y] < 0 ) && ( P[i] [Y] >= 0 ) ) ) { */
if ( ( P[i][Y] < 0 ) != ( P[i1][Y] < 0 ) ) {
/* e straddles ray, so compute intersection with ray. */
x = (P[i][X] * P[i1][Y] - P[i1][X] * P[i][Y])
/ (double)(P[i1][Y] - P[i][Y]);
/* printf("straddles: x = %g/t", x); */
/* crosses ray if strictly positive intersection. */
if (x < 0) Lcross++;
}
/* printf("Left cross=%d/n", Lcross); */
}
/* q on the edge if left and right cross are not the same parity. */
if( ( Rcross % 2 ) != (Lcross % 2 ) )
return 'e';
/* q inside iff an odd number of crossings. */
if( (Rcross % 2) == 1 )
return 'i';
else return 'o';
}
void PrintPoint( tPointi p )
{
int i;
putchar('(');
for ( i = 0; i < DIM; i++ ) {
printf("%d", p[i]);
if ( i != DIM-1 ) putchar(',');
}
putchar(')');
}
/*
Reads in the coordinates of the vertices of a polygon from stdin,
puts them into P, and returns n, the number of vertices.
Formatting conventions: etc.
*/
int ReadPoly( tPolygoni P )
{
int i, n;
do {
printf( "Input the number of vertices:/n");
scanf( "%d", &n );
if ( n <= PMAX )
break;
printf("Error in read_poly: too many points; max is %d/n", PMAX);
}
while ( 1 );
printf( "Polygon:/n" );
printf( " i x y/n");
for ( i = 0; i < n; i++ ) {
scanf( "%d %d", &P[i][0], &P[i][1] );
printf("%3d%4d%4d/n", i, P[i][0], P[i][1]);
}
printf("n = %3d vertices read/n",n);
putchar('/n');
return n;
}
void PrintPoly( int n, tPolygoni P )
{
int i;
printf("Polygon:/n");
printf(" i x y/n");
for( i = 0; i < n; i++ )
printf("%3d%4d%4d/n", i, P[i][0], P[i][1]);
}
/* Copy polygon a to b (overwriting b). */
void Copy( tPolygoni a, tPolygoni b, int n )
{
int i, j;
for ( i=0; i < n; i++)
for ( j = 0; j < DIM; j++ )
b[i][j] = a[i][j];
}
/*
bool EqPoint( tPointi a, tPointi b )
{
int i;
for ( i = 0; i < DIM; i++ )
if ( a[i] != b[i])
return FALSE;
return TRUE;
} */
/*
gcc -lstdc++ testpoint.cpp
6
45 20
35 10
10 15
30 25
20 35
40 30
25 15
25 25
25 20
*/