|
1161 | 1161 | <div class='together'>
|
1162 | 1162 | We need a way to pick a random point in a unit radius sphere. We’ll use what is usually the easiest
|
1163 | 1163 | algorithm: a rejection method. First, pick a random point in the unit cube where x, y, and z all
|
1164 |
| -range from -1 to +1. Reject this point and try again if the point is outside the sphere. A |
1165 |
| -do-while construct is perfect for that: |
| 1164 | +range from -1 to +1. Reject this point and try again if the point is outside the sphere. |
1166 | 1165 |
|
1167 | 1166 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1168 | 1167 | class vec3 {
|
|
1180 | 1179 |
|
1181 | 1180 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1182 | 1181 | vec3 random_in_unit_sphere() {
|
1183 |
| - vec3 p; |
1184 |
| - do { |
1185 |
| - p = vec3::random(-1,1); |
1186 |
| - } while (p.length_squared() >= 1.0); |
1187 |
| - return p; |
| 1182 | + while (true) { |
| 1183 | + auto p = vec3::random(-1,1); |
| 1184 | + if (p.length_squared() >= 1) continue; |
| 1185 | + return p; |
| 1186 | + } |
1188 | 1187 | }
|
1189 | 1188 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1190 | 1189 | [Listing [random-in-unit-sphere]: <kbd>[material.h]</kbd> The random_in_unit_sphere() function]
|
|
1337 | 1336 |
|
1338 | 1337 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1339 | 1338 | vec3 random_unit_vector() {
|
1340 |
| - return unit_vector(random_in_unit_sphere()); |
| 1339 | + auto a = random_double(0, 2*pi); |
| 1340 | + auto z = random_double(-1, 1); |
| 1341 | + auto r = sqrt(1 - z*z); |
| 1342 | + return vec3(r*cos(a), r*sin(a), z); |
1341 | 1343 | }
|
1342 | 1344 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1343 | 1345 | [Listing [random-unit-vector]: <kbd>[vec3.h]</kbd> The random_unit_vector() function]
|
|
1585 | 1587 | it could be a mixture of those strategies. For Lambertian materials we get this simple class:
|
1586 | 1588 |
|
1587 | 1589 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1588 |
| - vec3 random_unit_vector() { |
1589 |
| - auto a = random_double(0, 2*pi); |
1590 |
| - auto z = random_double(-1, 1); |
1591 |
| - auto r = sqrt(1 - z*z); |
1592 |
| - return vec3(r*cos(a), r*sin(a), z); |
1593 |
| - } |
1594 |
| - |
1595 |
| - ... |
1596 |
| - |
1597 | 1590 | class lambertian : public material {
|
1598 | 1591 | public:
|
1599 | 1592 | lambertian(const vec3& a) : albedo(a) {}
|
|
1775 | 1768 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1776 | 1769 | [Listing [metal-fuzz]: <kbd>[material.h]</kbd> Metal spheres with fuzziness]
|
1777 | 1770 |
|
1778 |
| -In order to generate a random point inside a unit sphere (`random_in_unit_sphere()`), we used one of |
1779 |
| -the easiest algorithms: a rejection method. First, pick a random point in the unit cube where x, y, |
1780 |
| -and z all range from -1 to +1. If the generated point is outside the unit sphere, repeat until we |
1781 |
| -get one on the inside. A do/while construct is perfect for that. |
1782 | 1771 | </div>
|
1783 | 1772 |
|
1784 | 1773 | <div class='together'>
|
|
2222 | 2211 |
|
2223 | 2212 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2224 | 2213 | vec3 random_in_unit_disk() {
|
2225 |
| - vec3 p; |
2226 |
| - do { |
2227 |
| - p = vec3(random_double(-1,1), random_double(-1,1), 0); |
2228 |
| - } while (dot(p,p) >= 1.0); |
2229 |
| - return p; |
| 2214 | + while (true) { |
| 2215 | + auto p = vec3(random_double(-1,1), random_double(-1,1), 0); |
| 2216 | + if (p.length_squared() >= 1) continue; |
| 2217 | + return p; |
| 2218 | + } |
2230 | 2219 | }
|
2231 | 2220 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2232 | 2221 | [Listing [rand-in-unit-disk]: <kbd>[vec3.h]</kbd> Generate random point inside unit disk]
|
|
2265 | 2254 |
|
2266 | 2255 | ray get_ray(double s, double t) {
|
2267 | 2256 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
2268 |
| - vec3 rd = lens_radius*random_in_unit_disk(); |
| 2257 | + vec3 rd = lens_radius * random_in_unit_disk(); |
2269 | 2258 | vec3 offset = u * rd.x() + v * rd.y();
|
2270 | 2259 |
|
2271 | 2260 | return ray(
|
|
0 commit comments