Origin point:
Direction unit vector:
Distance from origin:
Point on the ray:
Origin point:
Sphere radius:
Point on the sphere:
struct Ray {
Vec3f org; // Origin
Vec3f dir; // Direction
double t; // Current/maximum hit distance
} ray;
class rt::CPrimSphere
{
Vec3f m_origin; // Position of the sphere's center
float m_radius; // Radius of the sphere
};
Find closest intersection point
Introduce auxiliary point
Find
1. Only one intersection point
Find closest intersection point
2. No intersection points
Find closest intersection point
3. Ray origin lies in the sphere
Find closest intersection point
Substitute ray equation into the sphere equation and solve it for
Solve it as a quadratic equation
Point on the plane:
Normal to the plane:
Point on the plane:
Substitute ray equation into the plane equation and solve it for
There might be 0 or 1 or infinitely many solutions
In order to represent point p lying on the segment defined by known points b and c we can use the same logic which lies behind the ray definition:
By analogy to represent point q lying on the segment defined by known points a and q we can write:
Thus any point p within a triangle abc may be expressed as a linear combination of its vertices:
where parameters
or
are called barycentric coordinates
Where S designates the signed area of a triangle
Triangle vertices:
Barycentric coordinates:
Substitute ray equation into the triangle equation and solve it for
Point on the triangle:
Using the Cramer’s Rules for Systems of Linear Equations with Three Variables:
determinant:
Using the Cramer’s Rules for Systems of Linear Equations with Three Variables:
bool rt::CPrimTriangle::intersect(Ray& ray) const
{
const Vec3f pvec = ray.dir.cross(m_edge2);
const float det = m_edge1.dot(pvec);
if (fabs(det) < Epsilon)
return false;
const float inv_det = 1.0f / det;
const Vec3f tvec = ray.org - m_a;
float u = tvec.dot(pvec);
u *= inv_det;
if (u < 0.0f || u > 1.0f)
return false;
const Vec3f qvec = tvec.cross(m_edge1);
float v = ray.dir.dot(qvec);
v *= inv_det;
if (v < 0.0f || v + u > 1.0f)
return false;
float t = m_edge2.dot(qvec);
t *= inv_det;
if (ray.t <= t || t < Epsilon)
return false;
ray.t = t;
return true;
}
where
Points bounding the box volume:
Bounded Volume
Bounded Volume
Bounded Volume
Bounded Volume
Bounded Volume
bool intersect(Ray& ray) {
calculate tnear.x , tfar.x , tnear.y , tfar.y , tnear.z , tfar.z on 3 axes;
tnear = max(tnear.x , tnear.y , tnear.z);
tfar = min(tfar.x , tfar.y , tfar.z);
if (tnear < tfar && tnear < ray.t) {
ray.t = tnear; // report intersection at tnear
return true;
}
return false; // no intersection
}