cone & disc distributions
[vg.git] / vg_m.h
diff --git a/vg_m.h b/vg_m.h
index abd450960be984ba39ff0f5057bbad4225bd6684..91071ffb163d1b38617679c938bf68a7ba5bc590 100644 (file)
--- a/vg_m.h
+++ b/vg_m.h
@@ -540,6 +540,34 @@ static void v3_tangent_basis( v3f n, v3f tx, v3f ty ){
    v3_cross( n, tx, ty );
 }
 
+/*
+ * Compute yaw and pitch based of a normalized vector representing forward
+ * forward: -z
+ * result -> (YAW,PITCH,0.0)
+ */
+static void v3_angles( v3f v, v3f out_angles ){
+   float yaw = atan2f( v[0], -v[2] ),
+       pitch = atan2f( 
+                   -v[1], 
+                   sqrtf(
+                     v[0]*v[0] + v[2]*v[2]
+                   )
+               );
+
+   out_angles[0] = yaw;
+   out_angles[1] = pitch;
+   out_angles[2] = 0.0f;
+}
+
+/*
+ * Compute the forward vector from (YAW,PITCH,ROLL)
+ * forward: -z
+ */
+static void v3_angles_vector( v3f angles, v3f out_v ){
+   out_v[0] =  sinf( angles[0] ) * cosf( angles[1] );
+   out_v[1] = -sinf( angles[1] );
+   out_v[2] = -cosf( angles[0] ) * cosf( angles[1] );
+}
 
 /*
  * -----------------------------------------------------------------------------
@@ -699,7 +727,7 @@ static void q_mulv( v4f q, v3f v, v3f d )
    v3_add( v1, v2, d );
 }
 
-static f32 q_dist( v4f q0, v3f q1 ){
+static f32 q_dist( v4f q0, v4f q1 ){
    return acosf( 2.0f * v4_dot(q0,q1) -1.0f );
 }
 
@@ -2245,8 +2273,7 @@ struct {
 } 
 static vg_rand;
 
-static void vg_rand_seed( unsigned long seed ) 
-{
+static void vg_rand_seed( unsigned long seed ) {
    /* set initial seeds to mt[STATE_VECTOR_LENGTH] using the generator
     * from Line 25 of Table 1 in: Donald Knuth, "The Art of Computer
     * Programming," Vol. 2 (2nd Ed.) pp.102.
@@ -2261,8 +2288,7 @@ static void vg_rand_seed( unsigned long seed )
 /*
  * Generates a pseudo-randomly generated long.
  */
-static u32 vg_randu32(void) 
-{
+static u32 vg_randu32(void) {
    u32 y;
    /* mag[x] = x * 0x9908b0df for x = 0,1 */
    static u32 mag[2] = {0x0, 0x9908b0df}; 
@@ -2302,32 +2328,47 @@ static u32 vg_randu32(void)
 /*
  * Generates a pseudo-randomly generated f64 in the range [0..1].
  */
-static inline f64 vg_randf64(void)
-{
+static inline f64 vg_randf64(void){
    return (f64)vg_randu32()/(f64)0xffffffff;
 }
 
-static inline f64 vg_randf64_range( f64 min, f64 max )
-{
+static inline f64 vg_randf64_range( f64 min, f64 max ){
    return vg_lerp( min, max, (f64)vg_randf64() );
 }
 
-static inline void vg_rand_dir( v3f dir )
-{
+static inline void vg_rand_dir( v3f dir ){
    dir[0] = vg_randf64();
    dir[1] = vg_randf64();
    dir[2] = vg_randf64();
 
+   /* warning: *could* be 0 length.
+    * very unlikely.. 1 in (2^32)^3. but its mathematically wrong. */
+
    v3_muls( dir, 2.0f, dir );
    v3_sub( dir, (v3f){1.0f,1.0f,1.0f}, dir );
 
    v3_normalize( dir );
 }
 
-static inline void vg_rand_sphere( v3f co )
-{
+static inline void vg_rand_sphere( v3f co ){
    vg_rand_dir(co);
    v3_muls( co, cbrtf( vg_randf64() ), co );
 }
 
+static void vg_rand_disc( v2f co ){
+   f32 a = vg_randf64() * VG_TAUf;
+   co[0] = sinf(a);
+   co[1] = cosf(a); 
+   v2_muls( co, sqrtf( vg_randf64() ), co );
+}
+
+static void vg_rand_cone( v3f out_dir, f32 angle ){
+   f32 r = sqrtf(vg_randf64()) * angle * 0.5f,
+       a = vg_randf64() * VG_TAUf;
+
+   out_dir[0] = sinf(a) * sinf(r);
+   out_dir[1] = cosf(a) * sinf(r);
+   out_dir[2] = cosf(r);
+}
+
 #endif /* VG_M_H */