|
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