star-sp

Random number generators and distributions
git clone git://git.meso-star.fr/star-sp.git
Log | Files | Refs | README | LICENSE

commit 9a0ea621bfcd545bffc28618e5552fad6a6661a2
parent 0fa37740758f22fe522feb75edaeb9cd3e0e8519
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 13 Jul 2015 11:09:50 +0200

Add and test the uniform sampling of a triangle

Diffstat:
Mcmake/CMakeLists.txt | 3++-
Msrc/ssp.h | 39+++++++++++++++++++++++++++++++++++++++
Asrc/test_ssp_ran_triangle.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -66,7 +66,7 @@ rcmake_append_runtime_dirs(_runtime_dirs RSys ${Boost_LIBRARY_DIRS}) # Configure and define targets ################################################################################ set(VERSION_MAJOR 0) -set(VERSION_MINOR 1) +set(VERSION_MINOR 2) set(VERSION_PATCH 0) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) @@ -141,6 +141,7 @@ if(NOT NO_TEST) endif() new_test(test_ssp_ran_hemisphere ${MATH_LIB}) new_test(test_ssp_ran_sphere ${MATH_LIB}) + new_test(test_ssp_ran_triangle ${MATH_LIB}) new_test(test_ssp_rng_proxy) endif() diff --git a/src/ssp.h b/src/ssp.h @@ -242,6 +242,45 @@ ssp_ran_sphere_pdf(void) } /******************************************************************************* + * Triangle distribution + ******************************************************************************/ +/* Uniform sampling of a triangle */ +static INLINE float* +ssp_ran_triangle_uniform + (struct ssp_rng* rng, + const float v0[3], const float v1[3], const float v2[3],/*triangle vertices*/ + float sample[3]) /* Sampled position */ +{ + double u, v, one_minus_u; + int i; + ASSERT(rng && v0 && v1 && v2 && sample); + + u = ssp_rng_canonical(rng); + v = ssp_rng_canonical(rng); + one_minus_u = 1.0 - u; + + FOR_EACH(i, 0, 3) { + sample[i] = (float) + (v2[i] + one_minus_u * (v0[i] - v2[i]) + (v*u) * (v1[i] - v2[i])); + } + return sample; +} + +static INLINE float +ssp_ran_triangle_uniform_pdf + (const float v0[3], + const float v1[3], + const float v2[3]) +{ + float vec0[3], vec1[3], tmp[3]; + ASSERT(v0 && v1 && v2); + + f3_sub(vec0, v0, v2); + f3_sub(vec1, v1, v2); + return 1.f / (f3_len(f3_cross(tmp, vec0, vec1)) * 0.5f); +} + +/******************************************************************************* * Hemisphere distribution ******************************************************************************/ /* Uniform sampling of an unit hemisphere whose up direction is implicitly the diff --git a/src/test_ssp_ran_triangle.c b/src/test_ssp_ran_triangle.c @@ -0,0 +1,96 @@ +/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com) + * + * This software is governed by the CeCILL license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/or redistribute the software under the terms of the CeCILL + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL license and that you accept its terms. */ + +#include "ssp.h" +#include "test_ssp_utils.h" + +#include <rsys/float4.h> + +#define NSAMPS 128 + +int +main(int argc, char** argv) +{ + struct ssp_rng* rng; + struct mem_allocator allocator; + float samps[NSAMPS][3]; + float A[3], B[3], C[3]; + float v0[3], v1[3], v2[3], v3[3], v4[3], v5[3]; + float plane[4]; + int i; + (void)argc, (void)argv; + + mem_init_proxy_allocator(&allocator, &mem_default_allocator); + + CHECK(ssp_rng_create(&allocator, &ssp_rng_mt19937_64, &rng), RES_OK); + + FOR_EACH(i, 0, 3) { + A[i] = (float)ssp_rng_uniform_double(rng, 0.0, 1.0); + B[i] = (float)ssp_rng_uniform_double(rng, 0.0, 1.0); + C[i] = (float)ssp_rng_uniform_double(rng, 0.0, 1.0); + } + + f3_sub(v0, B, A); + f3_sub(v1, C, A); + f3_sub(v2, C, B); + f3_minus(v3, v0); + f3_minus(v4, v1); + f3_minus(v5, v2); + f3_cross(plane, v0, v1); + plane[3] = -f3_dot(plane, C); + + FOR_EACH(i, 0, NSAMPS) { + float tmp0[3], tmp1[3]; + float dot = 0.f; + float area = 0.f; + + CHECK(ssp_ran_triangle_uniform(rng, A, B, C, samps[i]), samps[i]); + CHECK(eq_epsf(f3_dot(plane, samps[i]), -plane[3], 1.e-6f), 1); + + f3_sub(tmp0, samps[i], A); + dot = f3_dot(f3_cross(tmp0, tmp0, v0), f3_cross(tmp1, v1, v0 )); + CHECK(signf(dot), 1.f ); + f3_sub(tmp0, samps[i], B); + dot = f3_dot(f3_cross(tmp0, tmp0, v2), f3_cross(tmp1, v3, v2)); + CHECK(signf(dot), 1.f); + f3_sub(tmp0, samps[i], C); + dot = f3_dot(f3_cross(tmp0, tmp0, v4), f3_cross(tmp1, v5, v4)); + CHECK(signf(dot), 1.f); + + area = f3_len(tmp1) * 0.5f; + CHECK(eq_epsf(1.f / area, ssp_ran_triangle_uniform_pdf(A, B, C), 1.e-6f), 1); + } + + ssp_rng_ref_put(rng); + check_memory_allocator(&allocator); + mem_shutdown_proxy_allocator(&allocator); + CHECK(mem_allocated_size(), 0); + + return 0; +} +