|
1278 | 1278 |
|
1279 | 1279 | </div>
|
1280 | 1280 |
|
| 1281 | +An Interval Class |
| 1282 | +------------------ |
| 1283 | +Before we continue, we'll implement an interval class to manage real-valued intervals with a minimum |
| 1284 | +and a maximum. We'll end up using this class quite often as we proceed. |
| 1285 | + |
| 1286 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1287 | + #ifndef INTERVAL_H |
| 1288 | + #define INTERVAL_H |
| 1289 | + |
| 1290 | + class interval { |
| 1291 | + public: |
| 1292 | + double min, max; |
| 1293 | + |
| 1294 | + interval(double _min, double _max) : min(_min), max(_max) {} |
| 1295 | + interval() : min(+infinity), max(-infinity) {} // Default interval is empty |
| 1296 | + |
| 1297 | + bool contains(double x) const { |
| 1298 | + return min <= x && x <= max; |
| 1299 | + } |
| 1300 | + }; |
| 1301 | + |
| 1302 | + const static interval empty (+infinity, -infinity); |
| 1303 | + const static interval universe(-infinity, +infinity); |
| 1304 | + |
| 1305 | + |
| 1306 | + #endif |
| 1307 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1308 | + [Listing [interval-initial]: <kbd>[interval.h]</kbd> Introducing the new interval class] |
| 1309 | + |
| 1310 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1311 | + class hittable { |
| 1312 | + public: |
| 1313 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1314 | + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const = 0; |
| 1315 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1316 | + }; |
| 1317 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1318 | + [Listing [hittable-with-interval]: <kbd>[hittable.h]</kbd> hittable::hit() using interval] |
| 1319 | + |
| 1320 | + |
| 1321 | + |
| 1322 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1323 | + class hittable_list : public hittable { |
| 1324 | + ... |
| 1325 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1326 | + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
| 1327 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1328 | + ... |
| 1329 | + }; |
| 1330 | + |
| 1331 | + |
| 1332 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1333 | + bool hittable_list::hit(const ray& r, interval ray_t, hit_record& rec) const { |
| 1334 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1335 | + hit_record temp_rec; |
| 1336 | + bool hit_anything = false; |
| 1337 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1338 | + auto closest_so_far = ray_t.max; |
| 1339 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1340 | + |
| 1341 | + for (const auto& object : objects) { |
| 1342 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1343 | + if (object->hit(r, interval(ray_t.min, closest_so_far), temp_rec)) { |
| 1344 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1345 | + hit_anything = true; |
| 1346 | + closest_so_far = temp_rec.t; |
| 1347 | + rec = temp_rec; |
| 1348 | + } |
| 1349 | + } |
| 1350 | + |
| 1351 | + return hit_anything; |
| 1352 | + } |
| 1353 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1354 | + [Listing [hittable-list-with-interval]: <kbd>[hittable.h]</kbd> |
| 1355 | + hittable_list::hit() using interval] |
| 1356 | + |
| 1357 | + |
| 1358 | + |
| 1359 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1360 | + class sphere : public hittable { |
| 1361 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1362 | + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
| 1363 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1364 | + ... |
| 1365 | + }; |
| 1366 | + |
| 1367 | + |
| 1368 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1369 | + bool sphere::hit(const ray& r, interval ray_t, hit_record& rec) const { |
| 1370 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1371 | + ... |
| 1372 | + |
| 1373 | + // Find the nearest root that lies in the acceptable range. |
| 1374 | + auto root = (-half_b - sqrtd) / a; |
| 1375 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1376 | + if (!ray_t.contains(root)) { |
| 1377 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1378 | + root = (-half_b + sqrtd) / a; |
| 1379 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1380 | + if (!ray_t.contains(root)) |
| 1381 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1382 | + return false; |
| 1383 | + } |
| 1384 | + ... |
| 1385 | + } |
| 1386 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1387 | + [Listing [sphere-with-interval]: <kbd>[sphere.h]</kbd> sphere using interval] |
| 1388 | + |
| 1389 | + |
| 1390 | + |
| 1391 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1392 | + ... |
| 1393 | + color ray_color(const ray& r, const hittable& world) { |
| 1394 | + hit_record rec; |
| 1395 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1396 | + if (world.hit(r, interval(0, infinity), rec)) { |
| 1397 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1398 | + return 0.5 * (rec.normal + color(1,1,1)); |
| 1399 | + } |
| 1400 | + ... |
| 1401 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1402 | + [Listing [main-with-interval]: <kbd>[main.cc]</kbd> The new main using interval] |
1281 | 1403 |
|
1282 | 1404 |
|
1283 | 1405 | Antialiasing
|
|
1570 | 1692 | color ray_color(const ray& r, const hittable& world) {
|
1571 | 1693 | hit_record rec;
|
1572 | 1694 |
|
1573 |
| - if (world.hit(r, 0, infinity, rec)) { |
| 1695 | + if (world.hit(r, interval(0, infinity), rec)) { |
1574 | 1696 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1575 | 1697 | point3 target = rec.p + rec.normal + random_in_unit_sphere();
|
1576 | 1698 | return 0.5 * ray_color(ray(rec.p, target - rec.p), world);
|
|
1606 | 1728 | return color(0,0,0);
|
1607 | 1729 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1608 | 1730 |
|
1609 |
| - if (world.hit(r, 0, infinity, rec)) { |
| 1731 | + if (world.hit(r, interval(0, infinity), rec)) { |
1610 | 1732 | point3 target = rec.p + rec.normal + random_in_unit_sphere();
|
1611 | 1733 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1612 | 1734 | return 0.5 * ray_color(ray(rec.p, target - rec.p), world, depth-1);
|
|
1721 | 1843 | point approximation the sphere intersector gives us. So we need to ignore hits very near zero:
|
1722 | 1844 |
|
1723 | 1845 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1724 |
| - if (world.hit(r, 0.001, infinity, rec)) { |
| 1846 | + if (world.hit(r, interval(0.001, infinity), rec)) { |
1725 | 1847 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1726 | 1848 | [Listing [reflect-tolerance]: <kbd>[main.cc]</kbd> Calculating reflected ray origins with tolerance]
|
1727 | 1849 |
|
|
1772 | 1894 | if (depth <= 0)
|
1773 | 1895 | return color(0,0,0);
|
1774 | 1896 |
|
1775 |
| - if (world.hit(r, 0.001, infinity, rec)) { |
| 1897 | + if (world.hit(r, interval(0.001, infinity), rec)) { |
1776 | 1898 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1777 | 1899 | point3 target = rec.p + rec.normal + random_unit_vector();
|
1778 | 1900 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
1854 | 1976 | if (depth <= 0)
|
1855 | 1977 | return color(0,0,0);
|
1856 | 1978 |
|
1857 |
| - if (world.hit(r, 0.001, infinity, rec)) { |
| 1979 | + if (world.hit(r, interval(0.001, infinity), rec)) { |
1858 | 1980 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1859 | 1981 | point3 target = rec.p + random_in_hemisphere(rec.normal);
|
1860 | 1982 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
1976 | 2098 | : center(ctr), radius(r), mat_ptr(m) {};
|
1977 | 2099 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1978 | 2100 |
|
1979 |
| - virtual bool hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) |
1980 |
| - const override; |
| 2101 | + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const override; |
1981 | 2102 |
|
1982 | 2103 | public:
|
1983 | 2104 | point3 center;
|
|
1987 | 2108 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1988 | 2109 | };
|
1989 | 2110 |
|
1990 |
| - bool sphere::hit(const ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const { |
| 2111 | + bool sphere::hit(const ray& r, interval ray_t, hit_record& rec) const { |
1991 | 2112 | ...
|
1992 | 2113 |
|
1993 | 2114 | rec.t = root;
|
|
2146 | 2267 | if (depth <= 0)
|
2147 | 2268 | return color(0,0,0);
|
2148 | 2269 |
|
2149 |
| - if (world.hit(r, 0.001, infinity, rec)) { |
| 2270 | + if (world.hit(r, interval(0.001, infinity), rec)) { |
2150 | 2271 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
2151 | 2272 | ray scattered;
|
2152 | 2273 | color attenuation;
|
|
0 commit comments