Add more to the writeup
This commit is contained in:
parent
00000230ee
commit
000002404e
7 changed files with 128 additions and 25 deletions
|
@ -36,7 +36,7 @@ examples/%.ppm: examples/%.txt
|
||||||
examples/%.png: examples/%.ppm
|
examples/%.png: examples/%.ppm
|
||||||
convert $< $@
|
convert $< $@
|
||||||
|
|
||||||
writeup.pdf: writeup.md
|
writeup.pdf: writeup.md $(EXAMPLES_PNG)
|
||||||
$(PANDOC) -o $@ $<
|
$(PANDOC) -o $@ $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
21
assignment-1/examples/fov-demo-1.txt
Normal file
21
assignment-1/examples/fov-demo-1.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
imsize 640 480
|
||||||
|
eye 0 0 15
|
||||||
|
viewdir 0 0 -1
|
||||||
|
hfov 60
|
||||||
|
updir 0 1 0
|
||||||
|
bkgcolor 0.1 0.1 0.1
|
||||||
|
|
||||||
|
mtlcolor 0 0.5 0.5
|
||||||
|
sphere -1 -2 -5 2
|
||||||
|
sphere 3 -5 -1 0.5
|
||||||
|
|
||||||
|
mtlcolor 0.5 0.5 1
|
||||||
|
sphere 1 2 -3 3
|
||||||
|
sphere -6 3 -4 1
|
||||||
|
|
||||||
|
mtlcolor 0.5 0 0.5
|
||||||
|
sphere 5 5 -1 1
|
||||||
|
sphere -6 -4 -8 7
|
||||||
|
|
||||||
|
mtlcolor 0.5 1 0.5
|
||||||
|
cylinder 5 1 -2 1 -2 1 1 2
|
21
assignment-1/examples/fov-demo-2.txt
Normal file
21
assignment-1/examples/fov-demo-2.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
imsize 640 480
|
||||||
|
eye 0 0 15
|
||||||
|
viewdir 0 0 -1
|
||||||
|
hfov 30
|
||||||
|
updir 0 1 0
|
||||||
|
bkgcolor 0.1 0.1 0.1
|
||||||
|
|
||||||
|
mtlcolor 0 0.5 0.5
|
||||||
|
sphere -1 -2 -5 2
|
||||||
|
sphere 3 -5 -1 0.5
|
||||||
|
|
||||||
|
mtlcolor 0.5 0.5 1
|
||||||
|
sphere 1 2 -3 3
|
||||||
|
sphere -6 3 -4 1
|
||||||
|
|
||||||
|
mtlcolor 0.5 0 0.5
|
||||||
|
sphere 5 5 -1 1
|
||||||
|
sphere -6 -4 -8 7
|
||||||
|
|
||||||
|
mtlcolor 0.5 1 0.5
|
||||||
|
cylinder 5 1 -2 1 -2 1 1 2
|
9
assignment-1/examples/up-dir-demo-1.txt
Normal file
9
assignment-1/examples/up-dir-demo-1.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
imsize 640 480
|
||||||
|
eye 0 0 8
|
||||||
|
viewdir 0 0 -1
|
||||||
|
hfov 60
|
||||||
|
updir 0 1 0
|
||||||
|
bkgcolor 1 1 1
|
||||||
|
|
||||||
|
mtlcolor 0.5 1 0.5
|
||||||
|
cylinder 0 0 -4 1 0 0 1 8
|
9
assignment-1/examples/up-dir-demo-2.txt
Normal file
9
assignment-1/examples/up-dir-demo-2.txt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
imsize 640 480
|
||||||
|
eye 0 0 8
|
||||||
|
viewdir 0 0 -1
|
||||||
|
hfov 60
|
||||||
|
updir 1 1 0
|
||||||
|
bkgcolor 1 1 1
|
||||||
|
|
||||||
|
mtlcolor 0.5 1 0.5
|
||||||
|
cylinder 0 0 -4 1 0 0 1 8
|
|
@ -57,7 +57,7 @@ impl ObjectKind for Cylinder {
|
||||||
|
|
||||||
let discriminant = b * b - 4.0 * a * c;
|
let discriminant = b * b - 4.0 * a * c;
|
||||||
|
|
||||||
let mut solutions = match discriminant {
|
let possible_side_solutions = match discriminant {
|
||||||
// Discriminant < 0, means the equation has no solutions.
|
// Discriminant < 0, means the equation has no solutions.
|
||||||
d if d < 0.0 => vec![],
|
d if d < 0.0 => vec![],
|
||||||
|
|
||||||
|
@ -76,6 +76,16 @@ impl ObjectKind for Cylinder {
|
||||||
_ => unreachable!("Invalid determinant value: {discriminant}"),
|
_ => unreachable!("Invalid determinant value: {discriminant}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Filter out solutions that don't have a valid Z position.
|
||||||
|
let side_solutions = possible_side_solutions.into_iter().filter(|t| {
|
||||||
|
let ray_point = ray.eval(*t);
|
||||||
|
let rotated_ray_point = rotation_matrix * ray_point;
|
||||||
|
let z = rotated_ray_point.z - rotated_cylinder_center.z;
|
||||||
|
|
||||||
|
// Check to see if z is between -len/2 and len/2
|
||||||
|
z.abs() < self.length / 2.0
|
||||||
|
});
|
||||||
|
|
||||||
// We also need to add solutions for the two ends of the cylinder, which
|
// We also need to add solutions for the two ends of the cylinder, which
|
||||||
// uses a similar method except backwards: check intersection points
|
// uses a similar method except backwards: check intersection points
|
||||||
// with the correct z-plane and then see if the points are within the
|
// with the correct z-plane and then see if the points are within the
|
||||||
|
@ -96,26 +106,19 @@ impl ObjectKind for Cylinder {
|
||||||
(o.z + c.z - self.length / 2.0) / r.z,
|
(o.z + c.z - self.length / 2.0) / r.z,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Filter out all the solutions where the z does not lie in the circle
|
// Filter out all the solutions where the z does not lie in the circle
|
||||||
solutions.extend(possible_z_intersections.into_iter().filter(|t| {
|
let end_solutions = possible_z_intersections.into_iter().filter(|t| {
|
||||||
let ray_point = ray.eval(*t);
|
let ray_point = ray.eval(*t);
|
||||||
ray_point.x.powi(2) + ray_point.y.powi(2) <= self.radius.powi(2)
|
ray_point.x.powi(2) + ray_point.y.powi(2) <= self.radius.powi(2)
|
||||||
}));
|
});
|
||||||
|
|
||||||
// Filter out solutions that don't have a valid Z position.
|
let solutions = side_solutions.into_iter().chain(end_solutions.into_iter());
|
||||||
let solutions = solutions
|
|
||||||
.into_iter()
|
|
||||||
.filter(|t| {
|
|
||||||
let ray_point = ray.eval(*t);
|
|
||||||
let rotated_ray_point = rotation_matrix * ray_point;
|
|
||||||
let z = rotated_ray_point.z - rotated_cylinder_center.z;
|
|
||||||
|
|
||||||
// Check to see if z is between -len/2 and len/2
|
|
||||||
z.abs() < self.length / 2.0
|
|
||||||
})
|
|
||||||
.filter_map(|t| NotNan::new(t).ok());
|
|
||||||
|
|
||||||
// Return the minimum solution
|
// Return the minimum solution
|
||||||
solutions.min().map(|t| t.into_inner())
|
solutions
|
||||||
|
.filter_map(|t| NotNan::new(t).ok())
|
||||||
|
.min()
|
||||||
|
.map(|t| t.into_inner())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,10 @@ output: pdf_document
|
||||||
|
|
||||||
# Raycaster
|
# Raycaster
|
||||||
|
|
||||||
|
#### Michael Zhang \<zhan4854@umn.edu\>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
Determining the viewing window for the raycaster for this assignment involved
|
Determining the viewing window for the raycaster for this assignment involved
|
||||||
creating a "virtual" screen in world coordinates, mapping image pixels into that
|
creating a "virtual" screen in world coordinates, mapping image pixels into that
|
||||||
virtual screen, and then casting a ray through each pixel's world coordinate to
|
virtual screen, and then casting a ray through each pixel's world coordinate to
|
||||||
|
@ -22,7 +26,15 @@ how many degrees the screen should take up.
|
||||||
Changing the angle of the field of view would result in a wider or narrower
|
Changing the angle of the field of view would result in a wider or narrower
|
||||||
screen, which when paired with the aspect ratio (width / height), would produce
|
screen, which when paired with the aspect ratio (width / height), would produce
|
||||||
a bigger or smaller viewing screen, like the orange box in the above diagram
|
a bigger or smaller viewing screen, like the orange box in the above diagram
|
||||||
shows. Simply put, FOV affects how _much_ of the frame you're able to see.
|
shows. Simply put, FOV affects how _much_ of the frame you're able to see. An
|
||||||
|
example is shown here:
|
||||||
|
|
||||||
|
![](examples/fov-demo-1.png){width=180px}\ ![](examples/fov-demo-2.png){width=180px}
|
||||||
|
|
||||||
|
The left image uses an FOV of 60, while the right image uses an FOV of 30. As
|
||||||
|
you can see, the left side has a wider range of vision, which allows it to see
|
||||||
|
more of the world. (both images can be found in the `examples` directory of the
|
||||||
|
handin zip)
|
||||||
|
|
||||||
Curiously, distance from the eye actually doesn't really affect the viewing
|
Curiously, distance from the eye actually doesn't really affect the viewing
|
||||||
screen very much. The reason is the screen is only used to determine how to
|
screen very much. The reason is the screen is only used to determine how to
|
||||||
|
@ -34,10 +46,16 @@ dimensions)
|
||||||
|
|
||||||
The up-direction vector controls the rotation of the scene. Without the
|
The up-direction vector controls the rotation of the scene. Without the
|
||||||
up-direction, it would not be possible to tell which rotation the screen should
|
up-direction, it would not be possible to tell which rotation the screen should
|
||||||
be in:
|
be in.
|
||||||
|
|
||||||
![Rotation determined by up direction](doc/rot.jpg){width=240px}
|
![Rotation determined by up direction](doc/rot.jpg){width=240px}
|
||||||
|
|
||||||
|
To see what this looks like, consider the following images, where the left side
|
||||||
|
uses an up direction of $(0, 1, 0)$, while the right side uses $(1, 1, 0)$ (both
|
||||||
|
images can be found in the `examples` directory of the handin zip)
|
||||||
|
|
||||||
|
![](examples/up-dir-demo-1.png){width=180px}\ ![](examples/up-dir-demo-2.png){width=180px}
|
||||||
|
|
||||||
Together, all of these parameters can uniquely determine a virtual screen
|
Together, all of these parameters can uniquely determine a virtual screen
|
||||||
location, that we can use to cast rays through and fill pixels. We can change
|
location, that we can use to cast rays through and fill pixels. We can change
|
||||||
any of these to produce an image with a more exaggerated view of the scene for
|
any of these to produce an image with a more exaggerated view of the scene for
|
||||||
|
@ -76,7 +94,8 @@ $\frac{\Delta x + \Delta y}{2}$ to the point to get that)
|
||||||
|
|
||||||
Because of the way I implemented parallel projection, it's recommended to
|
Because of the way I implemented parallel projection, it's recommended to
|
||||||
either put the eye much farther back, or use `--distance` to force a much bigger
|
either put the eye much farther back, or use `--distance` to force a much bigger
|
||||||
distance from the eye for the raycaster. This is due to the size of the image.
|
distance from the eye for the raycaster. See the `--help` to see how this option
|
||||||
|
is used.
|
||||||
|
|
||||||
### Cylinder Intersection Notes
|
### Cylinder Intersection Notes
|
||||||
|
|
||||||
|
@ -84,9 +103,30 @@ First, we will transform the current point into the vector space of the
|
||||||
cylinder, so that the cylinder location is $(0, 0, 0)$ and the direction vector
|
cylinder, so that the cylinder location is $(0, 0, 0)$ and the direction vector
|
||||||
is normalized into $(0, 0, 1)$.
|
is normalized into $(0, 0, 1)$.
|
||||||
|
|
||||||
Then it's a matter of determining if the $x$ and $y$ coordinates fall into the
|
This can be done by using a rotation matrix (since we are sure this
|
||||||
space constrained by the equation $(ox + t\times rx - cx)^2 + (oy + t\times ty -
|
transformation is just a rotation). This rotation is actually a 2D rotation,
|
||||||
cy)^2 = r^2$ and if $z \le L$.
|
around the normal between the cylinder direction and $(0, 0, 1)$. We then
|
||||||
|
rotate everything we are working with (the cylinder and the ray) into this
|
||||||
|
coordinate system to make calculations easier.
|
||||||
|
|
||||||
See the comments in the code for a more detailed explanation of the equation
|
Then it's a matter of determining if the $x$ and $y$ coordinates fall into the
|
||||||
used.
|
space constrained by the equation $(o_x + t\times r_x - c_x)^2 + (o_y + t\times
|
||||||
|
r_y - c_y)^2 = r^2$ and if $z \le L$. I can solve this using the quadratic
|
||||||
|
formula the same way as the sphere case.
|
||||||
|
|
||||||
|
We want a quadratic equation of the form $At^2 + Bt + C = 0$. The values for
|
||||||
|
$A$, $B$, and $C$ are:
|
||||||
|
|
||||||
|
- $A = r_x^2 + r_y^2$
|
||||||
|
- $B = 2(r_x(o_x - c_x) + r_y(o_y - c_y))$
|
||||||
|
- $C = (c_x - o_x)^2 + (c_y - o_y)^2 - r^2$
|
||||||
|
|
||||||
|
Solving this for $t$ yields 0-2 solutions depending on if the equation was
|
||||||
|
satisfied or not. Then, we can plug any solutions we get back into the ray
|
||||||
|
equation and determine if the $z$-coordinate is in the range of the cylinder
|
||||||
|
that we want.
|
||||||
|
|
||||||
|
We will also have to do this for the ends of the cylinder, but just backwards.
|
||||||
|
So we would start with the $z$-coordinate, solve for $t$s where the ray hits
|
||||||
|
that $z$-plane, and then check the $x$ and $y$ values to see if they satisfy the
|
||||||
|
ray equation as well.
|
||||||
|
|
Loading…
Reference in a new issue