home *** CD-ROM | disk | FTP | other *** search
- /*
- This file contains intersection of ray with Canonical Cylinder, Cone and Ring.
- 1)
- Intersection of a ray with canonical Cylinder.
- This canonical cylinder has axis coinciding
- with +ve Z axis with one base on origin with
- the Height H and the Radius R.
-
- The equation :
- x^2 + y^2 - R^2 = 0
-
- "ray_cylinder" computes the intersection and
- returns rayparameter t of intesection
- where t > 0 for valid intersection,
- and surface parameter (u,v) of the intersection point
- where v is the height parameter
- and u is along the circle in counterclock direction.
- 2.
- Ray Canonical cone intersection.
- Canonical cone has :
- apex at origin with axis aligned with Z.
- base diameter and height 1.
- So the slant angle is 45 degrees.
- In this Cononical form the surface equation :
- x^2 + y^2 - z^2 = 0
- i.e. the radius of the crosssection circle is equal
- to its z.
- "ray_cone" computes the intersection and returns parameter t of
- intersection
- where t > 0 for valid intersection,
- and surface parameter (u,v) of the intersection point
- where v is the height of the canonical cone withing the
- limit and u is along the crosssectional cirlce in
- counterclockwise direction.
- 3.
- Ray Cononical Ring intersection.
- Canonical ring is defined by the ring with
- center at origin and Z-axis as normal.
- Its further defined by its inner radius(R0), outer radius(R1).
- 0 <= R0 < R1.
- ------
- sumant
- */
- #include <stdio.h>
- #include <math.h>
- #include "GraphicsGems.h"
- #include "data_structure.h"
-
- static int check(t,ray_start,ray_direction,lo,hi)
- double t;
- Point3 *ray_start;
- Vector3 *ray_direction;
- double lo,hi;
- {
- double zposn=ray_start->z + ray_direction->z*t;
- return(zposn >= lo && zposn <= hi);
- }
-
- double ray_cylinder(ray_start,ray_direction,R,H,tubeflag,pu,pv)
- /*
- Tubeflag = 0 for the cylinder whose out surface visible.
- 1 for the cylinder whose inside surface visible.
- The intersection algorithm is same except in the surface
- parameterisation.
- */
- Point3 *ray_start; /* Input */
- Vector3 *ray_direction; /* Input */
- double R,H; /* Input */
- int tubeflag; /* Input */
- double *pu,*pv; /* Output */
- {
- int quadraticRoots();
- int nroots;
- double t = -1.,roots[2];
- double A,B,C;
- C = ray_start->x * ray_start->x + ray_start->y * ray_start->y
- - R * R;
- B = 2.*(ray_start->x * ray_direction->x
- + ray_start->y * ray_direction->y);
- A = ray_direction->x * ray_direction->x
- + ray_direction->y * ray_direction->y;
- if (nroots = quadraticRoots(A,B,C,roots))
- set_t(0.,H);
- if (t > EPSILON){ /* Compute Surface Parameter */
- Point3 p;
- double u;
- point_on_line(*ray_start,*ray_direction,t,p);
- *pv = p.z/H;
- circle_inverse_mapping(R,p.x,p.y,u);
- /*
- *pu = (tubeflag)?(1.-u):u;
- */
- *pu = u;
- return(t);
- }
- return(-1.);
- }
-
- double ray_cone(ray_start,ray_direction,distance,cupflag,pu,pv)
- Point3 *ray_start; /* Input */
- Vector3 *ray_direction; /* Input */
- double distance; /* Input */
- int cupflag; /* Input */
- double *pu,*pv; /* Output */
- {
- int quadraticRoots();
- int nroots;
- double t = -1.,roots[2];
- double A,B,C;
- C = ray_start->x * ray_start->x + ray_start->y * ray_start->y
- - ray_start->z * ray_start->z;
- B = 2.*(ray_start->x * ray_direction->x
- + ray_start->y * ray_direction->y
- - ray_start->z * ray_direction->z);
- A = ray_direction->x * ray_direction->x
- + ray_direction->y * ray_direction->y
- - ray_direction->z * ray_direction->z;
- if (nroots = quadraticRoots(A,B,C,roots))
- set_t(distance,1.);
- if (t > EPSILON){ /* Compute Surface Parameter */
- Point3 p;
- double u;
- point_on_line(*ray_start,*ray_direction,t,p);
- *pv = (p.z-distance)/(1.-distance);
- circle_inverse_mapping(p.z,p.x,p.y,u);
- /*
- *pu = (cupflag)?(1.-u):u;
- */
- *pu = u;
- return(t);
- }
- return(-1.);
- }
-
- double ray_ring(ray_start,ray_direction,R0,R1,pu,pv)
- Point3 *ray_start; /* Input */
- Vector3 *ray_direction; /* Input */
- double R0,R1; /* Input */
- double *pu,*pv; /* Output */
- {
- double t = -1.;
- if (fabs(ray_direction->z) > EPSILON){ /* Possible intersection */
- Point3 p;
- double radius;
- double value = -ray_start->z/ray_direction->z;
- if (value > EPSILON){
- point_on_line(*ray_start,*ray_direction,value,p);
- radius = V3SquaredLength(&p);
- if (radius >= R0*R0 && radius <= R1*R1){
- t = value;
- radius = sqrt(radius);
- *pv = (radius - R0)/(R1-R0);
- circle_inverse_mapping(radius,p.x,p.y,*pu);
- return(t);
- }
- }
- }
- return(-1.);
- }
-