Files
meowc/examples/raytracer/tests/math_test.c
T
sneeker 1d7ad86fb7 feat(examples): add the C++ benchmark and three test targets
A C++ consumer of the C archives, plus maths, scene and image tests driven by
meowc test.
2022-07-10 04:57:31 +00:00

63 lines
2.0 KiB
C

#include "rt.h"
#include <math.h>
#include <stdio.h>
static int failures = 0;
static void near(const char *what, double got, double want, double tol) {
if (fabs(got - want) > tol) {
fprintf(stderr, " %s: got %.9f, want %.9f\n", what, got, want);
failures++;
}
}
static void check(const char *what, int cond) {
if (!cond) {
fprintf(stderr, " %s: failed\n", what);
failures++;
}
}
int main(void) {
vec3 a = v3(1.0, 2.0, 3.0), b = v3(-4.0, 5.0, -6.0);
near("dot", v3dot(a, b), -4.0 + 10.0 - 18.0, 1e-12);
near("len", v3len(v3(3.0, 4.0, 0.0)), 5.0, 1e-12);
near("norm is unit", v3len(v3norm(b)), 1.0, 1e-12);
vec3 c = v3cross(a, b);
near("cross is perpendicular to a", v3dot(c, a), 0.0, 1e-12);
near("cross is perpendicular to b", v3dot(c, b), 0.0, 1e-12);
/* A ray striking a surface head on comes straight back. */
vec3 r = v3reflect(v3(0.0, -1.0, 0.0), v3(0.0, 1.0, 0.0));
near("reflect x", r.x, 0.0, 1e-12);
near("reflect y", r.y, 1.0, 1e-12);
vec3 mid = v3lerp(v3(0.0, 0.0, 0.0), v3(2.0, 4.0, 6.0), 0.5);
near("lerp midpoint", mid.y, 2.0, 1e-12);
near("zero length normalises to itself", v3len(v3norm(v3(0, 0, 0))), 0.0, 1e-12);
/* The generator must be reproducible from a seed, and stay in range. */
rng x, y;
rng_seed(&x, 12345);
rng_seed(&y, 12345);
double sum = 0.0, lo = 1.0, hi = 0.0;
for (int i = 0; i < 200000; i++) {
double u = rng_unit(&x);
check("same seed gives the same stream", u == rng_unit(&y));
if (u < lo) lo = u;
if (u > hi) hi = u;
sum += u;
}
check("stays inside [0,1)", lo >= 0.0 && hi < 1.0);
near("mean is near one half", sum / 200000.0, 0.5, 0.005);
for (int i = 0; i < 5000; i++) check("unit vector is unit", fabs(v3len(rng_unit_vector(&x)) - 1.0) < 1e-9);
for (int i = 0; i < 5000; i++) check("sample sits inside the sphere", v3len2(rng_in_sphere(&x)) < 1.0);
if (failures == 0) printf(" math: every assertion held\n");
return failures == 0 ? 0 : 1;
}