#include #include #include typedef struct point { double x,y,z; } POINT; typedef struct ray { POINT p,v; } RAY; typedef struct polygon { int n; POINT *v; } POLYGON; RAY *make_ray(POINT eye, int n, int x, int y); POINT *ray_poly_intersect(RAY *ray, POLYGON *polygon); main () { RAY *ray; POLYGON poly; POINT eye,*hitpoint; int i,x,y; int n; scanf("%lf%lf%lf",&eye.x,&eye.y,&eye.z); scanf("%d",&n); scanf("%d%d",&x,&y); scanf("%d",&poly.n); poly.v = (POINT *)malloc(poly.n*sizeof(POINT)); for (i=0; ix,hitpoint->y,hitpoint->z); } RAY *make_ray(POINT eye, int n, int x, int y) { RAY *ray = (RAY *)malloc(sizeof(RAY)); /* * These are arbitrary values. * You'll have to set all of them correctly yourself. */ ray->p.x = -1.0 + 2.0/(double)n * (x + 0.5); ray->p.y = -1.0 + 2.0/(double)n * (y + 0.5); ray->p.z = -1.0; ray->v.x = ray->p.x - eye.x; ray->v.y = ray->p.y - eye.y; ray->v.z = ray->p.z - eye.z; return ray; } POINT *ray_poly_intersect(RAY *ray, POLYGON *polygon) { double Nx,Ny,Nz,D; /* polygon plane equation */ double NdotP,NdotV,t,aNx,aNy,aNz; int i,j,n; POINT *pi, *pj, *v2d; /* temp variables, and 2d projected polygon */ POINT *hitPoint, *hit2d; int inside = 0; /* * Get polygon normal */ Nx = Ny = Nz = 0.0; n = polygon->n; for (i=0; iv[i]; pj = &polygon->v[j]; Nx += (pi->y-pj->y) * (pi->z+pj->z); Ny += (pi->z-pj->z) * (pi->x+pj->x); Nz += (pi->x-pj->x) * (pi->y+pj->y); } D = -(pi->x*Nx + pi->y*Ny + pi->z*Nz); NdotP = Nx*ray->p.x + Ny*ray->p.y + Nz*ray->p.z; NdotV = Nx*ray->v.x + Ny*ray->v.y + Nz*ray->v.z; /* * Check if ray and plane are parallel */ if (fabs(NdotV) < 0.000001) { return NULL; } t = (-D - NdotP) / NdotV; /* * Check if hitpoint behind image plane. */ if (t < 0.0) { return NULL; } hitPoint = (POINT *)malloc(sizeof(POINT)); hit2d = (POINT *)malloc(sizeof(POINT)); hitPoint->x = ray->p.x + t * ray->v.x; hitPoint->y = ray->p.y + t * ray->v.y; hitPoint->z = ray->p.z + t * ray->v.z; /* * Set up array for projected polygon */ v2d = (POINT *)malloc(n*sizeof(POINT)); aNx = fabs(Nx); aNy = fabs(Ny); aNz = fabs(Nz); if (aNx > aNy) { if (aNx > aNz) { /* * Nx is biggest, project on yz plane. */ hit2d->x = hitPoint->y; hit2d->y = hitPoint->z; for (i=0; iv[i]; v2d[i].x = pi->y; v2d[i].y = pi->z; } } else { /* * Nz is biggest, project on xy plane. */ hit2d->x = hitPoint->x; hit2d->y = hitPoint->y; for (i=0; iv[i]; v2d[i].x = pi->x; v2d[i].y = pi->y; } } } else if (aNy > aNz) { /* * Ny is biggest, project on xz plane. */ hit2d->x = hitPoint->x; hit2d->y = hitPoint->z; for (i=0; iv[i]; v2d[i].x = pi->x; v2d[i].y = pi->z; } } else { /* * Nz is biggest, project on xy plane. */ hit2d->x = hitPoint->x; hit2d->y = hitPoint->y; for (i=0; iv[i]; v2d[i].x = pi->x; v2d[i].y = pi->y; } } for (i = 0, j = n-1; i < n; j = i++) { /* * Flip a bit for each edge that: * straddles the x-axis (going up or going down), and * intersects the x-axis at a positive value of x. */ if ((((v2d[i].y <= hit2d->y) && (hit2d->y < v2d[j].y)) || ((v2d[j].y <= hit2d->y) && (hit2d->y < v2d[i].y))) && (hit2d->x < (v2d[j].x - v2d[i].x) * (hit2d->y - v2d[i].y) / (v2d[j].y - v2d[i].y) + v2d[i].x)) inside = !inside; } if (inside) return hitPoint; else return NULL; }