Incorporating the Sphere Primitive

[ LiB ]

Incorporating the Sphere Primitive

The sphere has been around for a very long time now. The two components that illustrate the definition of the sphere are the radius and center point. The center point can be seen as the position of the sphere in 3D space. The radius defines the size of the sphere along the X, Y, and Z axes. The reason why the sphere has been extensively used throughout the past two decades is because it's very easy to define, is easy to test for intersections, and is fast to render. You'll define a class that includes two attributescenter point and radiusdiscussed next . You should define the class and all its functionality in the file cObject.h .

NOTE

TIP

The radius of a sphere can also be defined in X,Y,and Z terms,whereby you can squash or stretch the sphere along the X,Y,and Z axes.

Designing the Class

The design of the class will include a position vector and a radius scalar. The class will also include an internal Find_Hitpoint(cRay * pRay) method that passes a ray in as a referenced parameter and computes the destination point of the ray. The ray structure will return with the destination point as the exact hit point on the sphere.

The cSphere class consists of two variables, two constructors, and one member method. The two variables consist of a cVector3 structure for the center point and a scalar for the radius. The constructors are used to set up the member variables as well as two member methods . One member function is used to set up the sphere and the other determines the intersection point for an incoming ray.

 class cSphere { public:           // Sphere  Definition           cVector3          vPosition;           float             fRadius;  cSphere ()  {           vPosition              = cVector3::vZero;           fRadius                = 0.0f;  };     cSphere (float x,float y, float z, float radius, bool left_handed = true)     {              if( left_handed == true )              {                 vPosition.Assign(-x,-y,z);              }              else              {                 vPosition.Assign(x,y,z);              }              fRadius = radius;     };      void Setup_Sphere (float x,float y, float z,                  float radius, bool left_handed = true)      {              if( left_handed == true )              {                vPosition.Assign(-x,-y,z);              }              else              {                 vPosition.Assign(x,y,z);              }              fRadius = radius;      };      // find hit point      bool Find_Hitpoint(cRay * pRay); }; 

Intersection

To intersect a ray with a sphere, you determine whether the line intersects the sphere and then actually find the intersection points. Now keep in mind that when intersecting a line with a 3D primitive, such as a sphere, the line may hit the sphere on two sidesone to enter and the other to exit the sphere. Before you go any further, you need to answer two questions:

  • Does the ray intersect the sphere?

  • At exactly what point(s) does the ray intersect the sphere?

The reason you need to answer the first question is that most rays that leave the image plane don't intersect the sphere if it's small enough. Therefore, finding the actual intersection for every incoming ray is a waste of processing cycles. Before you can actually find the intersection point on a sphere, you must first determine whether the ray even intersects the sphere. From there, you can find the actual intersection points. Finding the actual point of intersection involves solving a quadratic equation, as follows .

 AT ^ 2 + BT + C = 0 

Before using the quadratic equation, you must determine whether an intersection has occurred. To find this information, you simply determine whether the distance from the sphere's center to the ray is less than the radius of the sphere. See Figure 7.1 for the process of finding this information.

Figure 7.1. The distance from the ray to the sphere must be less than the radius.

graphic/07fig01.gif


So now if the procedures of testing a ray intersection with the sphere are true then you must find the actual intersection points. You do this by plugging in the parametric quadratic equation of the line into the sphere equation. See Figure 7.2.

Figure 7.2. The equation for calculating whether the line segment has intersected a point on the sphere.

graphic/07fig02.gif


The sphere equation is as follows:

 (a  q) _ = r _ a = sphere's center point q = point on sphere 

The final solution, when using the two equations together, contains values of t.

Here is the code:

 bool cSphere::Find_Hitpoint(cRay * pRay) {     // declare variables       float A, B, C;       float Delta,           Distance_To_SideA,           Distance_To_SideB,           SquareRoot;       cVector3 From_Origin_To_Sphere;       // compute distance from ray origin to sphere's position       From_Origin_To_Sphere = pRay->origin - this->vPosition;       // find angular difference between the ray direction       // and the line from the ray origin to the  sphere       B = ( pRay->direction * From_Origin_To_Sphere );       // B * 2       B *= 2.0f;       // find squared distance between these two vectors       C = ( From_Origin_To_Sphere * From_Origin_To_Sphere )         - (this->fRadius * this->fRadius) ;       A = 1.0f;       // the formula ( b * b - 4 * a * c )       Delta = ( B * B ) - 4.0f * A * C;       if( Delta < 0.0f )          return 0;       if( Delta >= 0.0f )       {           SquareRoot = (float)sqrt( Delta );           // find distance to one or two intersections           Distance_To_SideA = ( -B - SquareRoot ) * ( 0.5f * A );           Distance_To_SideB = ( -B + SquareRoot ) * ( 0.5f * A );        // check which distance if it hits one or two points      if( (Distance_To_SideA > 1.0f )  (Distance_To_SideB > 1.0f ))      {         if( Distance_To_SideA > 1.0f )            // set ray distance            pRay->distance =  Distance_To_SideA;         if( ( Distance_To_SideB < Distance_To_SideA )         && ( Distance_To_SideB > 1.0f ))            // set ray distance            pRay->distance = Distance_To_SideB;         // compute hit destination         pRay->Find_Destination();         return true;      }    }    return false; } 

The function passes a pointer to a ray structure. The intersection code is executed using the quadratic equation for the line-to-sphere intersection, as previously discussed. After the distance to the intersected side of the sphere is found, the ray's destination/hit point is computed by calling Find_Destination().

[ LiB ]


Focus On Photon Mapping
Focus On Photon Mapping (Premier Press Game Development)
ISBN: 1592000088
EAN: 2147483647
Year: 2005
Pages: 128
Authors: Marlon John

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net