- Timestamp:
- 08/12/14 20:34:31 (11 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/random.hh
r228 r308 64 64 } 65 65 66 vec3 unit_vec3( bool = false ) 67 { 68 return precise_unit_vec3(); 69 // return precise ? precise_unit_vec3() : fast_unit_vec3(); 70 } 71 vec2 unit_vec2( bool = false ) 72 { 73 return precise_unit_vec2(); 74 // return precise ? precise_unit_vec2() : fast_unit_vec2(); 75 } 76 77 vec2 disk_point( bool precise = false ) 78 { 79 return precise ? precise_disk_point() : fast_disk_point(); 80 } 81 82 vec3 sphere_point( bool precise = false ) 83 { 84 return precise ? precise_sphere_point() : fast_sphere_point(); 85 } 86 87 vec2 ellipse_point( const vec2& radii, bool precise = false ) 88 { 89 return precise ? precise_ellipse_point( radii ) : fast_ellipse_point( radii ); 90 } 91 92 vec3 ellipsoid_point( const vec3& radii, bool precise = false ) 93 { 94 return precise ? precise_ellipsoid_point( radii ) : fast_ellipsoid_point( radii ); 95 } 96 97 vec2 ellipse_edge( const vec2& radii, bool = false ) 98 { 99 return unit_vec2() * radii; 100 } 101 102 vec3 ellipsoid_edge( const vec3& radii, bool = false ) 103 { 104 return unit_vec3() * radii; 105 } 106 107 vec2 hollow_disk_point( float iradius, float oradius, bool precise = false ) 108 { 109 return precise ? precise_hollow_disk_point( iradius, oradius ) : fast_hollow_disk_point( iradius, oradius ); 110 } 111 112 vec3 hollow_sphere_point( float iradius, float oradius, bool precise = false ) 113 { 114 return precise ? precise_hollow_sphere_point( iradius, oradius ) : fast_hollow_sphere_point( iradius, oradius ); 115 } 116 117 vec2 hollow_ellipse_point( const vec2& iradii, const vec2& oradii, bool precise = false ) 118 { 119 return precise ? precise_hollow_ellipse_point( iradii, oradii ) : fast_hollow_ellipse_point( iradii, oradii ); 120 } 121 122 vec3 hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii, bool precise = false ) 123 { 124 return precise ? precise_hollow_ellipsoid_point( iradii, oradii ) : fast_hollow_ellipsoid_point( iradii, oradii ); 125 } 126 127 //vec2 fast_unit_vec2(); 128 vec2 precise_unit_vec2(); 129 //vec3 fast_unit_vec3(); 130 vec3 precise_unit_vec3(); 131 132 vec2 fast_disk_point(); 133 vec2 precise_disk_point(); 134 vec3 fast_sphere_point(); 135 vec3 precise_sphere_point(); 136 137 vec2 fast_ellipse_point( const vec2& radii ) 138 { 139 return fast_disk_point() * radii; 140 } 141 vec2 precise_ellipse_point( const vec2& radii ); 142 143 vec3 fast_ellipsoid_point( const vec3& radii ) 144 { 145 return fast_sphere_point() * radii; 146 } 147 148 vec3 precise_ellipsoid_point( const vec3& radii ); 149 150 vec2 fast_hollow_disk_point( float iradius, float oradius ); 151 vec2 precise_hollow_disk_point( float iradius, float oradius ); 152 vec3 fast_hollow_sphere_point( float iradius, float oradius ); 153 vec3 precise_hollow_sphere_point( float iradius, float oradius ); 154 155 vec2 fast_hollow_ellipse_point( const vec2& iradii, const vec2& oradii ); 156 vec2 precise_hollow_ellipse_point( const vec2& iradii, const vec2& oradii ); 157 vec3 fast_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii ); 158 vec3 precise_hollow_ellipsoid_point( const vec3& iradii, const vec3& oradii ); 159 160 66 161 private: 67 162 static seed_type randomized_seed(); -
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.