-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsphere.h
50 lines (39 loc) · 1.17 KB
/
sphere.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#ifndef SPHERE_H
#define SPHERE_H
#include "thing.h"
class Sphere : public Thing {
public:
Sphere() {}
Sphere( const P& center, const double radius, std::shared_ptr<Optics> optics ) : radius_( radius ) {
center_ = center ;
optics_ = optics ;
}
bool hit( const Ray& ray, const double tmin, const double tmax, Binding& binding ) const override ;
private:
double radius_ ;
} ;
bool Sphere::hit( const Ray& ray, const double tmin, const double tmax, Binding& binding ) const {
V o = ray.ori()-center_ ;
auto a = ray.dir().dot() ; // simplified quadratic equation (see also sphere() in main.cpp)
auto b = dot( ray.dir(), o ) ;
auto c = o.dot()-radius_*radius_ ;
auto discriminant = b*b-a*c ;
if ( 0>discriminant )
return false ;
auto x = sqrt( discriminant ) ;
// nearest t in range
auto t = ( -b-x )/a ;
if ( tmin>t || t>tmax ) {
t = ( -b+x )/a ;
if ( tmin>t || t>tmax )
return false ;
}
binding.t = t ;
binding.p = ray.at( binding.t ) ;
V outward = ( binding.p-center_ )/radius_ ;
binding.facing = 0>dot( ray.dir(), outward ) ;
binding.normal = binding.facing ? outward : -outward ;
binding.optics = optics_ ;
return true ;
}
#endif // SPHERE_H