Implement simple intersection detection with sphere
This commit is contained in:
37
demo.c
37
demo.c
@@ -18,8 +18,14 @@ typedef struct {
|
|||||||
vec3_t orig, dir;
|
vec3_t orig, dir;
|
||||||
} ray_t;
|
} ray_t;
|
||||||
|
|
||||||
static const vec3_t lightblue = { 0.5, 0.7, 1.0 };
|
typedef struct {
|
||||||
|
vec3_t centre;
|
||||||
|
double rad;
|
||||||
|
} sphere_t;
|
||||||
|
|
||||||
|
static const vec3_t lightblue = { 0.4, 0.6, 1.0 };
|
||||||
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
static const vec3_t white = { 1.0, 1.0, 1.0 };
|
||||||
|
static const vec3_t red = { 1.0, 0.1, 0.2 };
|
||||||
|
|
||||||
static const vec3_t camera = { 0, 0, 0 };
|
static const vec3_t camera = { 0, 0, 0 };
|
||||||
static const vec3_t vp_disp = { 0, 0, FOCLEN };
|
static const vec3_t vp_disp = { 0, 0, FOCLEN };
|
||||||
@@ -28,12 +34,35 @@ static const vec3_t vp_v = { 0, -VP_H, 0 };
|
|||||||
static const vec3_t pix_x_step = { VP_W / W, 0, 0 };
|
static const vec3_t pix_x_step = { VP_W / W, 0, 0 };
|
||||||
static const vec3_t pix_y_step = { 0, -VP_H / H, 0 };
|
static const vec3_t pix_y_step = { 0, -VP_H / H, 0 };
|
||||||
|
|
||||||
|
static const sphere_t obj = {
|
||||||
|
.centre = { 1.0, 0.0, -3.0 },
|
||||||
|
.rad = 1.0,
|
||||||
|
};
|
||||||
|
|
||||||
static pix_t pix[W * H];
|
static pix_t pix[W * H];
|
||||||
|
|
||||||
|
static double intersect(sphere_t sphere, ray_t ray)
|
||||||
|
{
|
||||||
|
const vec3_t disp = vec3_sub(sphere.centre, ray.orig);
|
||||||
|
|
||||||
|
const double a = vec3_dot(ray.dir, ray.dir);
|
||||||
|
const double b = -2.0 * vec3_dot(ray.dir, disp);
|
||||||
|
const double c = vec3_dot(disp, disp) - sphere.rad * sphere.rad;
|
||||||
|
|
||||||
|
const double discriminant = b * b - 4 * a * c;
|
||||||
|
if (discriminant < 0)
|
||||||
|
return -1.0;
|
||||||
|
else
|
||||||
|
return (-b - sqrt(discriminant)) / (2.0 * a);
|
||||||
|
}
|
||||||
|
|
||||||
static vec3_t raycol(ray_t ray)
|
static vec3_t raycol(ray_t ray)
|
||||||
{
|
{
|
||||||
const vec3_t u = vec3_unit(ray.dir);
|
const double t = intersect(obj, ray);
|
||||||
const double a = (u.y + 1.0) / 2.0;
|
if (t > 0.0)
|
||||||
|
return red;
|
||||||
|
|
||||||
|
const double a = (ray.dir.y + 1.0) / 2.0;
|
||||||
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a));
|
return vec3_add(vec3_scale(lightblue, a), vec3_scale(white, 1 - a));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +93,7 @@ int main()
|
|||||||
for (unsigned x = 0; x < W; ++x) {
|
for (unsigned x = 0; x < W; ++x) {
|
||||||
const ray_t ray = {
|
const ray_t ray = {
|
||||||
.orig = camera,
|
.orig = camera,
|
||||||
.dir = vec3_add(row, vec3_scale(pix_x_step, x)),
|
.dir = vec3_unit(vec3_add(row, vec3_scale(pix_x_step, x))),
|
||||||
};
|
};
|
||||||
const vec3_t col = raycol(ray);
|
const vec3_t col = raycol(ray);
|
||||||
setpix(col, pix + (W * y + x));
|
setpix(col, pix + (W * y + x));
|
||||||
|
|||||||
Reference in New Issue
Block a user