Пример #1
0
INT	SphPeIntersect(RAY *pr, ELEMENT *pe, IRECORD *hit)
	{
	INT	nhits;				/* Number of hits.	     */
	REAL	b, disc, t1, t2, vsq;		/* Formula variables.	     */
	SPHERE	*ps;				/* Ptr to sphere data.	     */
	POINT	V;				/* C - P		     */
	IRECORD *sphhit;

	ps  = (SPHERE *)(pe->data);
	sphhit = hit;

	VecSub(V, ps->center, pr->P);		/* Ray from origin to center.*/
	vsq = VecDot(V, V);			/* Length sq of V.	     */
	b   = VecDot(V, pr->D); 		/* Perpendicular scale of V. */

	if (vsq > ps->rad2  &&	b < RAYEPS)	/* Behind ray origin.	     */
		return (0);

	disc = b*b - vsq + ps->rad2;		/* Discriminate.	     */
	if (disc < 0.0) 			/* Misses ray.		     */
		return (0);

	disc = sqrt(disc);			/* Find intersection param.  */
	t2   = b + disc;
	t1   = b - disc;

	if (t2 <= RAYEPS)			/* Behind ray origin.	     */
		return (0);

	nhits = 0;
	if (t1 > RAYEPS)			/* Entering sphere.	     */
		{
		IsectAdd(sphhit, t1, pe);
		sphhit++;
		nhits++;
		}

	IsectAdd(sphhit, t2, pe);		/* Exiting sphere	     */
	nhits++;

	return (nhits);
	}
Пример #2
0
INT	PolyPeIntersect(RAY *pr, ELEMENT *pe, IRECORD *hit)
	{
	INT	i;
	INT	*vindex;		/* Vertex index pointer.	     */
	INT	toright;		/* Counter.			     */
	INT	sh, nsh;		/* Sign holders.		     */
	REAL	Rd_dot_Pn;		/* Polygon normal dot ray direction. */
	REAL	Ro_dot_Pn;		/* Polygon normal dot ray origin.    */
	REAL	tval;			/* Intersection t distance value.    */
	REAL	x[MAX_VERTS + 1];	/* Projection list.		     */
	REAL	y[MAX_VERTS + 1];	/* Projection list.		     */
	REAL	ix, iy; 		/* Intersection projection point.    */
	REAL	dx, dy; 		/* Deltas between 2 vertices.	     */
	REAL	xint;			/* Intersection value.		     */
	VEC3	I;			/* Intersection point.		     */
	VEC3	*vlist, *vpos;		/* Vertex list pointer. 	     */
	POLY	*pp;			/* Ptr to polygon data. 	     */

	pp = (POLY *)pe->data;

	Rd_dot_Pn = VecDot(pp->norm, pr->D);

	if (ABS(Rd_dot_Pn) < RAYEPS)		/* Ray is parallel.	     */
		return (0);

	Ro_dot_Pn = VecDot(pp->norm, pr->P);

	tval = -(pp->d + Ro_dot_Pn)/Rd_dot_Pn;	/* Intersection distance.    */
	if (tval < RAYEPS)			/* Intersects behind ray.    */
		return (0);

	RayPoint(I, pr, tval);


	/* Polygon containment. */

	/* Project onto plane with greatest normal component. */

	vlist  = pp->vptr;
	vindex = pp->vindex;

	switch (pp->axis_proj)
		{
		case X_AXIS:
			for (i = 0; i < pp->nverts; i++)
				{
				vpos = vlist + (*vindex);
				x[i] = (*vpos)[1];
				y[i] = (*vpos)[2];
				vindex++;
				}

			ix = I[1];
			iy = I[2];
			break;

		case Y_AXIS:
			for (i = 0; i < pp->nverts; i++)
				{
				vpos = vlist + (*vindex);
				x[i] = (*vpos)[0];
				y[i] = (*vpos)[2];
				vindex++;
				}

			ix = I[0];
			iy = I[2];
			break;

		case Z_AXIS:
			for (i = 0; i < pp->nverts; i++)
				{
				vpos = vlist + (*vindex);
				x[i] = (*vpos)[0];
				y[i] = (*vpos)[1];
				vindex++;
				}

			ix = I[0];
			iy = I[1];
			break;
		}


	/* Translate to origin. */

	for (i = 0; i < pp->nverts; i++)
		{
		x[i] -= ix;
		y[i] -= iy;

		if (ABS(y[i]) < RAYEPS)
			y[i] = 0.0;
		}

	x[pp->nverts] = x[0];
	y[pp->nverts] = y[0];


	/*
	 *	If intersection point crosses an odd number of line segments,
	 *	the point is inside the polygon
	 */


	if (y[0] < 0.0)
		sh = 0;
	else
		sh = 1;

	toright = 0;

	for (i = 0; i < pp->nverts; i++)
		{
		/* Check if segment crosses in y. */

		if (y[i + 1] < 0.0)
			nsh = 0;
		else
			nsh = 1;

		if (nsh ^ sh)
			{
			dy = y[i + 1] - y[i];

			if (ABS(dy) >= RAYEPS)
				{
				dx   = x[i + 1] - x[i];
				xint = x[i] - y[i]*dx / dy;

				if (xint > 0.0)
					toright++;
				}
			}

		sh = nsh;
		}

	if (toright%2 == 1)
		{
		IsectAdd(hit, tval, pe);
		return (1);
		}
	else
		return (0);
	}