Skip to content

Commit b09c5a1

Browse files
authored
Merge pull request #1617 from RayTracing/refactor/rotate-y-hit
Small improvement to rotate_y::hit() function
2 parents c6f803f + 07f11f5 commit b09c5a1

File tree

4 files changed

+76
-54
lines changed

4 files changed

+76
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Change Log / Ray Tracing in One Weekend
1111
- Fix -- Big improvement to print version listing font size (#1595) and more compact line
1212
height for code listings in both print and browser.
1313
- Change -- Include hittable.h from material.h; drop `hit_record` forward declaration (#1609)
14+
- Fix -- Slight improvement to `rotate_y::hit()` function (#1484)
1415
- Fix -- Fixed possible bogus values from `random_unit_vector()` due to underflow (#1606)
1516

1617
### In One Weekend

books/RayTracingTheNextWeek.html

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3816,34 +3816,41 @@
38163816
public:
38173817

38183818
bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
3819-
// Change the ray from world space to object space
3820-
auto origin = r.origin();
3821-
auto direction = r.direction();
38223819

3823-
origin[0] = cos_theta*r.origin()[0] - sin_theta*r.origin()[2];
3824-
origin[2] = sin_theta*r.origin()[0] + cos_theta*r.origin()[2];
3820+
// Transform the ray from world space to object space.
38253821

3826-
direction[0] = cos_theta*r.direction()[0] - sin_theta*r.direction()[2];
3827-
direction[2] = sin_theta*r.direction()[0] + cos_theta*r.direction()[2];
3822+
auto origin = point3(
3823+
(cos_theta * r.origin().x()) - (sin_theta * r.origin().z()),
3824+
r.origin().y(),
3825+
(sin_theta * r.origin().x()) + (cos_theta * r.origin().z())
3826+
);
3827+
3828+
auto direction = vec3(
3829+
(cos_theta * r.direction().x()) - (sin_theta * r.direction().z()),
3830+
r.direction().y(),
3831+
(sin_theta * r.direction().x()) + (cos_theta * r.direction().z())
3832+
);
38283833

38293834
ray rotated_r(origin, direction, r.time());
38303835

3831-
// Determine whether an intersection exists in object space (and if so, where)
3836+
// Determine whether an intersection exists in object space (and if so, where).
3837+
38323838
if (!object->hit(rotated_r, ray_t, rec))
38333839
return false;
38343840

3835-
// Change the intersection point from object space to world space
3836-
auto p = rec.p;
3837-
p[0] = cos_theta*rec.p[0] + sin_theta*rec.p[2];
3838-
p[2] = -sin_theta*rec.p[0] + cos_theta*rec.p[2];
3841+
// Transform the intersection from object space back to world space.
38393842

3840-
// Change the normal from object space to world space
3841-
auto normal = rec.normal;
3842-
normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2];
3843-
normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2];
3843+
rec.p = point3(
3844+
(cos_theta * rec.p.x()) + (sin_theta * rec.p.z()),
3845+
rec.p.y(),
3846+
(-sin_theta * rec.p.x()) + (cos_theta * rec.p.z())
3847+
);
38443848

3845-
rec.p = p;
3846-
rec.normal = normal;
3849+
rec.normal = vec3(
3850+
(cos_theta * rec.normal.x()) + (sin_theta * rec.normal.z()),
3851+
rec.normal.y(),
3852+
(-sin_theta * rec.normal.x()) + (cos_theta * rec.normal.z())
3853+
);
38473854

38483855
return true;
38493856
}

src/TheNextWeek/hittable.h

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -115,34 +115,41 @@ class rotate_y : public hittable {
115115
}
116116

117117
bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
118-
// Change the ray from world space to object space
119-
auto origin = r.origin();
120-
auto direction = r.direction();
121118

122-
origin[0] = cos_theta*r.origin()[0] - sin_theta*r.origin()[2];
123-
origin[2] = sin_theta*r.origin()[0] + cos_theta*r.origin()[2];
119+
// Transform the ray from world space to object space.
124120

125-
direction[0] = cos_theta*r.direction()[0] - sin_theta*r.direction()[2];
126-
direction[2] = sin_theta*r.direction()[0] + cos_theta*r.direction()[2];
121+
auto origin = point3(
122+
(cos_theta * r.origin().x()) - (sin_theta * r.origin().z()),
123+
r.origin().y(),
124+
(sin_theta * r.origin().x()) + (cos_theta * r.origin().z())
125+
);
126+
127+
auto direction = vec3(
128+
(cos_theta * r.direction().x()) - (sin_theta * r.direction().z()),
129+
r.direction().y(),
130+
(sin_theta * r.direction().x()) + (cos_theta * r.direction().z())
131+
);
127132

128133
ray rotated_r(origin, direction, r.time());
129134

130-
// Determine whether an intersection exists in object space (and if so, where)
135+
// Determine whether an intersection exists in object space (and if so, where).
136+
131137
if (!object->hit(rotated_r, ray_t, rec))
132138
return false;
133139

134-
// Change the intersection point from object space to world space
135-
auto p = rec.p;
136-
p[0] = cos_theta*rec.p[0] + sin_theta*rec.p[2];
137-
p[2] = -sin_theta*rec.p[0] + cos_theta*rec.p[2];
140+
// Transform the intersection from object space back to world space.
138141

139-
// Change the normal from object space to world space
140-
auto normal = rec.normal;
141-
normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2];
142-
normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2];
142+
rec.p = point3(
143+
(cos_theta * rec.p.x()) + (sin_theta * rec.p.z()),
144+
rec.p.y(),
145+
(-sin_theta * rec.p.x()) + (cos_theta * rec.p.z())
146+
);
143147

144-
rec.p = p;
145-
rec.normal = normal;
148+
rec.normal = vec3(
149+
(cos_theta * rec.normal.x()) + (sin_theta * rec.normal.z()),
150+
rec.normal.y(),
151+
(-sin_theta * rec.normal.x()) + (cos_theta * rec.normal.z())
152+
);
146153

147154
return true;
148155
}

src/TheRestOfYourLife/hittable.h

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -123,34 +123,41 @@ class rotate_y : public hittable {
123123
}
124124

125125
bool hit(const ray& r, interval ray_t, hit_record& rec) const override {
126-
// Change the ray from world space to object space
127-
auto origin = r.origin();
128-
auto direction = r.direction();
129126

130-
origin[0] = cos_theta*r.origin()[0] - sin_theta*r.origin()[2];
131-
origin[2] = sin_theta*r.origin()[0] + cos_theta*r.origin()[2];
127+
// Transform the ray from world space to object space.
132128

133-
direction[0] = cos_theta*r.direction()[0] - sin_theta*r.direction()[2];
134-
direction[2] = sin_theta*r.direction()[0] + cos_theta*r.direction()[2];
129+
auto origin = point3(
130+
(cos_theta * r.origin().x()) - (sin_theta * r.origin().z()),
131+
r.origin().y(),
132+
(sin_theta * r.origin().x()) + (cos_theta * r.origin().z())
133+
);
134+
135+
auto direction = vec3(
136+
(cos_theta * r.direction().x()) - (sin_theta * r.direction().z()),
137+
r.direction().y(),
138+
(sin_theta * r.direction().x()) + (cos_theta * r.direction().z())
139+
);
135140

136141
ray rotated_r(origin, direction, r.time());
137142

138-
// Determine whether an intersection exists in object space (and if so, where)
143+
// Determine whether an intersection exists in object space (and if so, where).
144+
139145
if (!object->hit(rotated_r, ray_t, rec))
140146
return false;
141147

142-
// Change the intersection point from object space to world space
143-
auto p = rec.p;
144-
p[0] = cos_theta*rec.p[0] + sin_theta*rec.p[2];
145-
p[2] = -sin_theta*rec.p[0] + cos_theta*rec.p[2];
148+
// Transform the intersection from object space back to world space.
146149

147-
// Change the normal from object space to world space
148-
auto normal = rec.normal;
149-
normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2];
150-
normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2];
150+
rec.p = point3(
151+
(cos_theta * rec.p.x()) + (sin_theta * rec.p.z()),
152+
rec.p.y(),
153+
(-sin_theta * rec.p.x()) + (cos_theta * rec.p.z())
154+
);
151155

152-
rec.p = p;
153-
rec.normal = normal;
156+
rec.normal = vec3(
157+
(cos_theta * rec.normal.x()) + (sin_theta * rec.normal.z()),
158+
rec.normal.y(),
159+
(-sin_theta * rec.normal.x()) + (cos_theta * rec.normal.z())
160+
);
154161

155162
return true;
156163
}

0 commit comments

Comments
 (0)