Vec3d Particle_source_cylinder::uniform_position_in_cylinder( std::default_random_engine &rnd_gen ) { // random point in cylinder along z Vec3d cyl_axis = vec3d_init( ( axis_end_x - axis_start_x ), ( axis_end_y - axis_start_y ), ( axis_end_z - axis_start_z ) ); double cyl_axis_length = vec3d_length( cyl_axis ); double x, y, z; double r, phi; r = sqrt( random_in_range( 0.0, 1.0, rnd_gen ) ) * radius; phi = random_in_range( 0.0, 2.0 * M_PI, rnd_gen ); z = random_in_range( 0.0, cyl_axis_length, rnd_gen ); // x = r * cos( phi ); y = r * sin( phi ); z = z; Vec3d random_pnt_in_cyl_along_z = vec3d_init( x, y, z ); // rotate: // see https://en.wikipedia.org/wiki/Rodrigues'_rotation_formula // todo: Too complicated. Try rejection sampling. Vec3d random_pnt_in_rotated_cyl; Vec3d unit_cyl_axis = vec3d_normalized( cyl_axis ); Vec3d unit_along_z = vec3d_init( 0, 0, 1.0 ); Vec3d rotation_axis = vec3d_cross_product( unit_along_z, unit_cyl_axis ); double rotation_axis_length = vec3d_length( rotation_axis ); if ( rotation_axis_length == 0 ) { if ( copysign( 1.0, vec3d_z( unit_cyl_axis ) ) >= 0 ){ random_pnt_in_rotated_cyl = random_pnt_in_cyl_along_z; } else { random_pnt_in_rotated_cyl = vec3d_negate( random_pnt_in_cyl_along_z ); } } else { Vec3d unit_rotation_axis = vec3d_normalized( rotation_axis ); double rot_cos = vec3d_dot_product( unit_cyl_axis, unit_along_z ); double rot_sin = rotation_axis_length; random_pnt_in_rotated_cyl = vec3d_add( vec3d_times_scalar( random_pnt_in_cyl_along_z, rot_cos ), vec3d_add( vec3d_times_scalar( vec3d_cross_product( unit_rotation_axis, random_pnt_in_cyl_along_z ), rot_sin ), vec3d_times_scalar( unit_rotation_axis, ( 1 - rot_cos ) * vec3d_dot_product( unit_rotation_axis, random_pnt_in_cyl_along_z ) ) ) ); } // shift: Vec3d shifted = vec3d_add( random_pnt_in_rotated_cyl, vec3d_init( axis_start_x, axis_start_y, axis_start_z ) ); return shifted; }
static void space_body_update(Space *space,Body *body) { GList *it; Cube a,b; Body *other; Vec3D stepVector; Vec3D stepOffVector; if ((!body) || (body->_done))return; vec3d_scale(stepVector,body->velocity,space->stepFactor); vec3d_negate(stepOffVector,stepVector); vec3d_add(body->position,body->position,stepVector); a.x = body->position.x + body->bounds.x; a.y = body->position.y + body->bounds.y; a.z = body->position.z + body->bounds.z; a.w = body->bounds.w; a.h = body->bounds.h; a.d = body->bounds.d; for (it = space->bodylist;it != NULL;it = g_list_next(it)) { if (!it->data)continue; if (it->data == body)continue; /*check for collision*/ other = (Body *)it->data; vec3d_cpy(b,other->position); b.w = other->bounds.w; b.h = other->bounds.h; b.d = other->bounds.d; vec3d_add(b,b,other->bounds); if (cube_cube_intersection(a,b)) { /*call touch functions*/ /*back the f**k off*/ //vec3d_cpy(body->_stepOffVector,stepOffVector); //body->_done = 1; // body->_needsBackoff = 1; if (body->touch.function) { body->touch.function(body->touch.data,other); } } } }