|
902 | 902 | auto a = r.direction().length_squared();
|
903 | 903 | auto half_b = dot(oc, r.direction());
|
904 | 904 | auto c = oc.length_squared() - radius*radius;
|
905 |
| - auto discriminant = half_b*half_b - a*c; |
906 |
| - |
907 |
| - if (discriminant > 0) { |
908 |
| - auto root = sqrt(discriminant); |
909 |
| - |
910 |
| - auto temp = (-half_b - root) / a; |
911 |
| - if (temp < t_max && temp > t_min) { |
912 |
| - rec.t = temp; |
913 |
| - rec.p = r.at(rec.t); |
914 |
| - rec.normal = (rec.p - center) / radius; |
915 |
| - return true; |
916 |
| - } |
917 | 905 |
|
918 |
| - temp = (-half_b + root) / a; |
919 |
| - if (temp < t_max && temp > t_min) { |
920 |
| - rec.t = temp; |
921 |
| - rec.p = r.at(rec.t); |
922 |
| - rec.normal = (rec.p - center) / radius; |
923 |
| - return true; |
924 |
| - } |
| 906 | + auto discriminant = half_b*half_b - a*c; |
| 907 | + if (discriminant < 0) return false; |
| 908 | + auto sqrtd = sqrt(discriminant); |
| 909 | + |
| 910 | + // Find the nearest root that lies in the acceptable range. |
| 911 | + auto root = (-half_b - sqrtd) / a; |
| 912 | + if (root < t_min || t_max < root) { |
| 913 | + root = (-half_b + sqrtd) / a; |
| 914 | + if (root < t_min || t_max < root) |
| 915 | + return false; |
925 | 916 | }
|
926 | 917 |
|
927 |
| - return false; |
928 |
| - } |
| 918 | + rec.t = root; |
| 919 | + rec.p = r.at(rec.t); |
| 920 | + rec.normal = (rec.p - center) / radius; |
929 | 921 |
|
| 922 | + return true; |
| 923 | + } |
930 | 924 |
|
931 | 925 | #endif
|
932 | 926 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1026 | 1020 |
|
1027 | 1021 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1028 | 1022 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
|
1029 |
| - vec3 oc = r.origin() - center; |
1030 |
| - auto a = r.direction().length_squared(); |
1031 |
| - auto half_b = dot(oc, r.direction()); |
1032 |
| - auto c = oc.length_squared() - radius*radius; |
1033 |
| - auto discriminant = half_b*half_b - a*c; |
| 1023 | + ... |
1034 | 1024 |
|
1035 |
| - if (discriminant > 0) { |
1036 |
| - auto root = sqrt(discriminant); |
1037 |
| - auto temp = (-half_b - root) / a; |
1038 |
| - if (temp < t_max && temp > t_min) { |
1039 |
| - rec.t = temp; |
1040 |
| - rec.p = r.at(rec.t); |
1041 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1042 |
| - vec3 outward_normal = (rec.p - center) / radius; |
1043 |
| - rec.set_face_normal(r, outward_normal); |
1044 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1045 |
| - return true; |
1046 |
| - } |
1047 |
| - temp = (-half_b + root) / a; |
1048 |
| - if (temp < t_max && temp > t_min) { |
1049 |
| - rec.t = temp; |
1050 |
| - rec.p = r.at(rec.t); |
| 1025 | + rec.t = root; |
| 1026 | + rec.p = r.at(rec.t); |
1051 | 1027 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1052 |
| - vec3 outward_normal = (rec.p - center) / radius; |
1053 |
| - rec.set_face_normal(r, outward_normal); |
| 1028 | + vec3 outward_normal = (rec.p - center) / radius; |
| 1029 | + rec.set_face_normal(r, outward_normal); |
1054 | 1030 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1055 |
| - return true; |
1056 |
| - } |
1057 |
| - } |
1058 |
| - return false; |
| 1031 | + |
| 1032 | + return true; |
1059 | 1033 | }
|
1060 | 1034 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1061 | 1035 | [Listing [sphere-final]: <kbd>[sphere.h]</kbd> The sphere class with normal determination]
|
|
2013 | 1987 | };
|
2014 | 1988 |
|
2015 | 1989 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
|
2016 |
| - vec3 oc = r.origin() - center; |
2017 |
| - auto a = r.direction().length_squared(); |
2018 |
| - auto half_b = dot(oc, r.direction()); |
2019 |
| - auto c = oc.length_squared() - radius*radius; |
2020 |
| - auto discriminant = half_b*half_b - a*c; |
| 1990 | + ... |
2021 | 1991 |
|
2022 |
| - if (discriminant > 0) { |
2023 |
| - auto root = sqrt(discriminant); |
2024 |
| - auto temp = (-half_b - root) / a; |
2025 |
| - if (temp < t_max && temp > t_min) { |
2026 |
| - rec.t = temp; |
2027 |
| - rec.p = r.at(rec.t); |
2028 |
| - vec3 outward_normal = (rec.p - center) / radius; |
2029 |
| - rec.set_face_normal(r, outward_normal); |
2030 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2031 |
| - rec.mat_ptr = mat_ptr; |
2032 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2033 |
| - return true; |
2034 |
| - } |
2035 |
| - temp = (-half_b + root) / a; |
2036 |
| - if (temp < t_max && temp > t_min) { |
2037 |
| - rec.t = temp; |
2038 |
| - rec.p = r.at(rec.t); |
2039 |
| - vec3 outward_normal = (rec.p - center) / radius; |
2040 |
| - rec.set_face_normal(r, outward_normal); |
| 1992 | + rec.t = root; |
| 1993 | + rec.p = r.at(rec.t); |
| 1994 | + vec3 outward_normal = (rec.p - center) / radius; |
| 1995 | + rec.set_face_normal(r, outward_normal); |
2041 | 1996 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
2042 |
| - rec.mat_ptr = mat_ptr; |
| 1997 | + rec.mat_ptr = mat_ptr; |
2043 | 1998 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2044 |
| - return true; |
2045 |
| - } |
2046 |
| - } |
2047 |
| - return false; |
| 1999 | + |
| 2000 | + return true; |
2048 | 2001 | }
|
2049 | 2002 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2050 | 2003 | [Listing [sphere-material]: <kbd>[sphere.h]</kbd> Ray-sphere intersection with added material information]
|
|
0 commit comments