- Timestamp:
- 08/12/14 20:34:31 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/random.cc
r199 r308 90 90 return narrow_cast< seed_type >( get_ticks() ); 91 91 } 92 93 nv::vec2 nv::random::precise_unit_vec2() 94 { 95 std::uniform_real_distribution<f32> dist( 0, glm::pi<float>() * 2.f ); 96 float angle = dist( rng ); 97 return vec2( glm::cos( angle ), glm::sin( angle ) ); 98 } 99 100 nv::vec3 nv::random::precise_unit_vec3() 101 { 102 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); 103 std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() ); 104 float cos_theta = dist11( rng ); 105 float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta ); 106 float phi = dist02pi( rng ); 107 return vec3( 108 sin_theta * glm::sin(phi), 109 sin_theta * glm::cos(phi), 110 cos_theta 111 ); 112 } 113 114 nv::vec2 nv::random::fast_disk_point() 115 { 116 std::uniform_real_distribution<f32> dist( 0.0f, 1.0f ); 117 float r1 = dist( rng ); 118 float r2 = dist( rng ); 119 if ( r1 > r2 ) std::swap( r1, r2 ); 120 float rf = 2*glm::pi<float>()*(r1/r2); 121 return vec2( r2*glm::cos( rf ), r2*glm::sin( rf ) ); 122 } 123 124 nv::vec2 nv::random::precise_disk_point() 125 { 126 std::uniform_real_distribution<f32> unit( 0.0f, 1.0f ); 127 std::uniform_real_distribution<f32> angle( 0.0f, glm::pi<float>() ); 128 float r = glm::sqrt( unit( rng ) ); 129 float rangle = angle( rng ); 130 return vec2( r*glm::cos( rangle ), r*glm::sin( rangle ) ); 131 } 132 133 nv::vec3 nv::random::fast_sphere_point() 134 { 135 std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f ); 136 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); 137 std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() ); 138 float rad = dist01( rng ); 139 float pi = glm::pi<float>(); 140 float phi = glm::asin( dist11( rng ) ) + pi*.5f; 141 float theta = dist02pi( rng ); 142 float sin_phi = glm::sin( phi ); 143 return vec3( 144 rad * glm::cos(theta) * sin_phi, 145 rad * glm::sin(theta) * sin_phi, 146 rad * glm::cos(phi) 147 ); 148 } 149 150 nv::vec3 nv::random::precise_sphere_point() 151 { 152 std::uniform_real_distribution<f32> dist01( 0.0f, 1.0f ); 153 std::uniform_real_distribution<f32> dist11( -1.0f, 1.0f ); 154 std::uniform_real_distribution<f32> dist02pi( 0.0f, 2*glm::pi<float>() ); 155 float radius = std::pow( dist01( rng ), 1.f/3.f ); 156 float cos_theta = dist11( rng ); 157 float sin_theta = glm::sqrt( 1.0f - cos_theta * cos_theta ); 158 float phi = dist02pi( rng ); 159 return vec3( 160 radius * sin_theta * glm::sin(phi), 161 radius * sin_theta * glm::cos(phi), 162 radius * cos_theta 163 ); 164 } 165 166 nv::vec2 nv::random::precise_ellipse_point( const vec2& radii ) 167 { 168 std::uniform_real_distribution<f32> distx( -radii.x, radii.x ); 169 std::uniform_real_distribution<f32> disty( -radii.y, radii.y ); 170 vec2 inv_radii = 1.f / radii; 171 vec2 inv_radii2 = inv_radii * inv_radii; 172 for ( uint32 i = 0; i < 12; ++i ) 173 { 174 float x = distx( rng ); 175 float y = disty( rng ); 176 if ( x * x * inv_radii2.x + y * y * inv_radii2.y <= 1.f ) 177 { 178 return vec2( x, y ); 179 } 180 } 181 return fast_disk_point() * radii; 182 } 183 184 nv::vec3 nv::random::precise_ellipsoid_point( const vec3& radii ) 185 { 186 std::uniform_real_distribution<f32> distx( -radii.x, radii.x ); 187 std::uniform_real_distribution<f32> disty( -radii.y, radii.y ); 188 std::uniform_real_distribution<f32> distz( -radii.z, radii.z ); 189 vec3 inv_radii = 1.f / radii; 190 vec3 inv_radii2 = inv_radii * inv_radii; 191 for ( uint32 i = 0; i < 12; ++i ) 192 { 193 float x = distx( rng ); 194 float y = disty( rng ); 195 float z = distz( rng ); 196 if ( x * x * inv_radii2.x + y * y * inv_radii2.y + z * z * inv_radii2.z <= 1.f ) 197 { 198 return vec3( x, y, z ); 199 } 200 } 201 return fast_sphere_point() * radii; 202 } 203 204 nv::vec2 nv::random::fast_hollow_disk_point( float iradius, float oradius ) 205 { 206 float idist2 = iradius * iradius; 207 float odist2 = oradius * oradius; 208 float rdist = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) ); 209 return rdist * precise_unit_vec2(); 210 } 211 212 nv::vec2 nv::random::precise_hollow_disk_point( float iradius, float oradius ) 213 { 214 return fast_hollow_disk_point( iradius, oradius ); 215 } 216 217 nv::vec3 nv::random::fast_hollow_sphere_point( float iradius, float oradius ) 218 { 219 float idist3 = iradius * iradius * iradius; 220 float odist3 = oradius * oradius * oradius; 221 float rdist = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f ); 222 return rdist * precise_unit_vec3(); 223 } 224 225 nv::vec3 nv::random::precise_hollow_sphere_point( float iradius, float oradius ) 226 { 227 return fast_hollow_sphere_point( iradius, oradius ); 228 } 229 230 231 nv::vec2 nv::random::fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii ) 232 { 233 vec2 iradii2 = iradii * iradii; 234 vec2 opoint = ellipse_edge( oradii ); 235 vec2 opoint2 = opoint * opoint; 236 vec2 odir = glm::normalize( opoint ); 237 float odist2 = opoint2.x + opoint2.y; 238 239 float low = iradii2.y * opoint2.x + iradii2.x * opoint2.y; 240 float idist2 = ((iradii2.x * iradii2.y) / low ) * odist2; 241 242 float rdist = glm::sqrt( std::uniform_real_distribution<f32>( idist2, odist2 )( rng ) ); 243 return odir * rdist; 244 } 245 246 nv::vec2 nv::random::precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii ) 247 { 248 return fast_hollow_ellipse_point( iradii, oradii ); 249 } 250 251 nv::vec3 nv::random::fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii ) 252 { 253 vec3 iradii2 = iradii * iradii; 254 vec3 opoint = ellipsoid_edge( oradii ); 255 vec3 opoint2 = opoint * opoint; 256 vec3 odir = glm::normalize( opoint ); 257 float odist2 = opoint2.x + opoint2.y + opoint2.z; 258 259 float low = 260 iradii2.y * iradii2.z * opoint2.x + 261 iradii2.x * iradii2.z * opoint2.y + 262 iradii2.x * iradii2.y * opoint2.z; 263 float idist2 = ((iradii2.x * iradii2.y * iradii2.z) / low ) * odist2; 264 265 float odist3 = odist2 * glm::sqrt( odist2 ); 266 float idist3 = idist2 * glm::sqrt( idist2 ); 267 268 float rdist = std::pow( std::uniform_real_distribution<f32>( idist3, odist3 )( rng ), 1.f/3.f ); 269 return odir * rdist; 270 } 271 272 nv::vec3 nv::random::precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii ) 273 { 274 return fast_hollow_ellipsoid_point( iradii, oradii ); 275 } 276
Note: See TracChangeset
for help on using the changeset viewer.