

In this section, vectors are expressed in bold while points are not.
A line is defined by two points; it is infinite in length passing through the points and extending forever in both directions.
A line segment ( segment for short ) is defined by two endpoints.
A ray is semiinfinite; it is specified by a point and a direction.
So, a line, a segment, and a ray all consist of points; in our notation, they should not be bold. ( Recall the homogeneous coordinate representation and affine combination of points. ) We use a parameter t to describe them ( parametric representation ).
Suppose P_{1} and P_{2} are two points defining a line L(t). Let b = P_{2}  P_{1}. Then
segment:  0 ≤ t ≤ 1  
ray:  0 ≤ t ≤ ∞  
line:  ∞ < t < ∞ 
class Ray { private: Point3 origin; //starting point Vector3 direction; //vector public: Ray() : origin( Point3( 0, 0, 0 ) ), direction( Vector3( 0, 1, 0 ) ) {}; Ray( Point3& an_origin, Vector3& a_direction ); .... }; 
As mentioned above, a ray is specified by its starting position O and a unit vector D and can be ragarded as a set of points given by
L = O + tD 0 ≤ t < ∞ 
A plane is specified by a normal vector N perpendicular to the plane:
( P  P' ) ⋅ N = 0
implies that (x  x')N_{x} + (y  y')N_{y} + (z  z')N_{z} = 0 or ax + by + cz + d = 0 
Suppose P is the intersection of the line and the plane. Then
Solving for t, we have
( P'  O )⋅N t =  D⋅N 
( P_{1}'  O)⋅N t_{1} =  D⋅N 
( P_{2}'  O )⋅N t_{2} =  D⋅N 
n = N / N d = n ⋅(v_{0}  O) is the distance from the origin to the plane if n is normalized 
Barycentric Coordinates
S_{i}, i = 1, 2, 3 are proportional to the areas of the corresponding subtriangles and If the area of the triangle is normalized to 1, so that S_{i} becomes the area of the actual subtriangle, we have homogeneous Barycentric coordinates ( S_{1}, S_{2}, S_{3} ) are referred to as Barycentric coordinates of P Criteria for inside triangle:
So, if we know the barycentric coordinates of the hit point, we can accept or reject the ray with very simple tests: Point P is outside the triangle if one of the barycentric coordinates S_{i} is smaller than zero 
Area of a polygon is
_{n1}  
A = ½  x_{i} y_{i+1}  x_{i+1} y_{i}  
^{i=0} 
Suppose vertices P_{1}, P_{2} and P_{3} form the triangle and ( α, β, γ ) are barycentric coordinates of point P:
Substituting with α = 1  β  γ, we have
It is easier to solve if we project this in a 2D plane. ( Projecting both the triangle and the hitpoint P onto another plane does not change the barycentric coordinates of P. After projection, all computations can be performed more efficiently in 2D. For example, we can project them into the XY plane. If we let c = (P_{2}  P_{1}) , b = (P_{3}  P_{1}), and h = P  P_{1}. , we can rewrite (1) as
When projected onto the XY plane, we obtain the equations,
βc_{y} + γb_{y} = h_{y}
b_{x}h_{y}  b_{y}h_{x} β =  b_{x}c_{y}  b_{y}c_{x} 
h_{x}c_{y}  h_{y}c_{x} γ =  b_{x}c_{y}  b_{y}c_{x} 
bool intersect_ray_triangle ( const Triangle triangle, Ray &ray, double &t ) { Vec3 v01 = triangle.p1  triangle.p0; Vec3 v02 = triangle.p2  triangle.p0; Vec3 normal = v01 ^ v02; //normal to triangle Plane plane ( triangle.p0, normal ); //plane containing triangle bool hit_plane = intersect_ray_plane ( plane, ray, t ); if ( !hit_plane ) return false; Point3 q = ray.getPoint( t ); //check if q is inside triangle double bx, by, cx, cy, hx, hy; double beta, gamma; Vec3 b, c, h; c = v01; b = v02; h = q  triangle.p0; //find the dominant axis char axis; if ( fabs ( normal.x ) > fabs ( normal.y ) ) if ( fabs ( normal.x ) > fabs ( normal.z ) ) axis = 'x'; else axis = 'z'; else if ( fabs ( normal.y ) > fabs ( normal.z ) ) axis = 'y'; else axis = 'z'; switch ( axis ) { case 'x': //project on YZ plane bx = b.y; by = b.z; cx = c.y; cy = c.z; hx = h.y; hy = h.z; break; case 'y': //project on ZX plane bx = b.z; by = b.x; cx = c.z; cy = c.x; hx = h.z; hy = h.x; break; case 'z': //project on XY plane bx = b.x; by = b.y; cx = c.x; cy = c.y; hx = h.x; hy = h.y; break; } double denominator = bx * cy  by * cx; beta = ( bx * hy  by * hx ) / denominator; gamma = ( hx * cy  hy * cx ) / denominator; if ( beta < 0 ) return false; if ( gamma < 0 ) return false; if ( beta + gamma > 1 ) return false; return true; } 
We may preprocess some values to speed up the process.


Example:
If s = 1, it becomes the generic cylinder; if s = 0, it becomes the generic cone.
e.g. spheres, cylinders, ellipsoids, paraboloids, hyperboloids, cones
void buildkdtree( Node* node ) { if (stopcriterionmet()) return splitpos = findoptimalsplitposition() leftnode = new Node() rightnode = new Node() for (all primitives in node) { if (node>intersectleftnode()) leftnode>addprimitive( primitive ) if (node>intersectrightnode()) rightnode>addprimitive( primitive ) } buildkdtree( leftnode ) buildkdtree( rightnode ) } 
G becomes a leaf as it is convex