star-2d

Contour structuring for efficient 2D geometric queries
git clone git://git.meso-star.fr/star-2d.git
Log | Files | Refs | README | LICENSE

commit 0ba38f6c41404ef1792c8d5adbf5c7d6d5b2df58
parent f99e90503db6a45a10180c3bcb1b1c987ea657ec
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 29 Jun 2016 14:33:09 +0200

Numerically compute PI*S/P in the advanced session test

Diffstat:
Msrc/test_s2d_session_advanced.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 82 insertions(+), 0 deletions(-)

diff --git a/src/test_s2d_session_advanced.c b/src/test_s2d_session_advanced.c @@ -34,6 +34,45 @@ #include <string.h> +#define NSAMPS 10000 + +static INLINE float* +ran_semi_disk_cos_local(float samp[2]) +{ + samp[0] = rand_canonic() * 2.f - 1.f; + samp[1] = (float)sqrt(1 - samp[0]*samp[0]); + return samp; +} + +static INLINE float* +ran_semi_disk_cos(const float up[2], float samp[2]) +{ + float tmp[2], v[2]; + CHECK(f2_is_normalized(samp), 1); + ran_semi_disk_cos_local(tmp); + v[0] = -up[1] * tmp[0] + up[0]*tmp[1]; + v[1] = up[0] * tmp[0] + up[1]*tmp[1];; + CHECK(f2_is_normalized(v), 1); + return f2_set(samp, v); +} + +static int +discard_self_hit + (const struct s2d_hit* hit, + const float org[2], + const float dir[2], + void* ray_data, + void* filter_data) +{ + struct s2d_primitive* prim_from = ray_data; + NCHECK(hit, NULL); + NCHECK(org, NULL); + NCHECK(dir, NULL); + CHECK((intptr_t)filter_data, (intptr_t)0xDECAFBAD); + if(!ray_data) return 0; + return S2D_PRIMITIVE_EQ(prim_from, &hit->prim); +} + static struct s2d_shape* create_circle_shape (struct s2d_device* dev, @@ -50,6 +89,8 @@ create_circle_shape unsigned i; CHECK(s2d_shape_create_line_segments(dev, &shape), RES_OK); + CHECK(s2d_line_segments_set_hit_filter_function + (shape, discard_self_hit, (void*)0xDECAFBAD), RES_OK); CHECK(nsteps > 4, 1); NCHECK(center, NULL); @@ -102,6 +143,9 @@ main(int argc, char** argv) size_t i; size_t nprims; float tmp[2]; + float sum, sum_sqr; + float E, V, SE; + float area, length; int ishape; (void)argc, (void)argv; @@ -198,6 +242,44 @@ main(int argc, char** argv) FOR_EACH(i, 0, sa_size(shape_prims[2])) CHECK(shape_prims[2][i], 1); FOR_EACH(i, 0, sa_size(scene_prims)) CHECK(scene_prims[i], 1); + /* Check the ray tracing by numerically compute PI*S/P aka 4V/S in 2D */ + sum = sum_sqr = 0; + FOR_EACH(i, 0, NSAMPS) { + const float range[2] = { 0.f, FLT_MAX }; + struct s2d_attrib attr; + struct s2d_hit hit; + float P[2], N[2]; + float s; + + CHECK(s2d_scene_sample(scn, rand_canonic(), rand_canonic(), &prim, &s), RES_OK); + + CHECK(s2d_primitive_get_attrib(&prim, S2D_POSITION, s, &attr), RES_OK); + CHECK(attr.type, S2D_FLOAT2); + f2_set(P, attr.value); + + CHECK(s2d_primitive_get_attrib(&prim, S2D_GEOMETRY_NORMAL, s, &attr), RES_OK); + CHECK(attr.type, S2D_FLOAT2); + NCHECK(f2_normalize(N, attr.value), 0.f); + + f2_normalize(tmp, f2(tmp, 1, 1)); + ran_semi_disk_cos(N, tmp); + + CHECK(s2d_scene_trace_ray(scn, P, tmp, range, &prim, &hit), RES_OK); + CHECK(S2D_HIT_NONE(&hit), 0); + + sum += hit.distance; + sum_sqr += hit.distance*hit.distance; + } + + CHECK(s2d_scene_compute_contour_length(scn, &length), RES_OK); + CHECK(s2d_scene_compute_area(scn, &area), RES_OK); + + E = sum / (float)NSAMPS; + V = sum_sqr / (float)NSAMPS - E*E; + SE = (float)sqrt(V/(float)NSAMPS); + printf("PI*S / P = %g ~ %g +/- %g\n",(float)PI*area / length, E, SE); + CHECK(eq_epsf((float)PI*area / length, E, SE), 1); + CHECK(s2d_scene_end_session(scn), RES_OK); CHECK(s2d_scene_ref_put(scn), RES_OK);