CS 417 Homework 6 Solutions ------------------------------------------------------------------------ Problem 1 1.1. It is obvious that the ray hits zero (the sphere center) at t = sqrt(3). Since the radius of the sphere is 1 and the length of the ray direction vector is 1, we have t = sqrt(3) +/- 1 Alternatively you could just substitute the ray equation into the sphere equation and solve for t, yielding the same result. 1.2. // sphere center C = (cx, cy, cz) // radius R A = 1 B = dx*(px-cx) + dy*(py-cy) + dz*(pz-cz) C = (px-cx)^2 + (py-cy)^2 + (pz-cz)^2 - R^2 D = B^2 - C if D >= 0 then line intersects sphere. in that case, compare (d dot p)^2 (already computed -- it is B^2) with D: (d . p)^2 <= D ===> ray intersects. (d . p)^2 > D and (d . p) < 0 ===> ray intersects (d . p)^2 > D and (d . p) > 0 ===> ray does not intersect 8 multiplications. 7 if we precompute R^2. 1.3. A = dx^2 + dy^2 + dz^2 B = dx*(px-cx) + dy*(py-cy) + dz*(pz-cz) C = (px-cx)^2 + (py-cy)^2 + (pz-cz)^2 - R^2 D = B^2 - A*C if D >= 0 then line intersects sphere. in that case, compare (d dot p)^2 (already computed -- it is B^2) with D: (d . p)^2 <= D ===> ray intersects. (d . p)^2 > D and (d . p) < 0 ===> ray intersects (d . p)^2 > D and (d . p) > 0 ===> ray does not intersect 12 multiplications. 11 if we precompute R^2. 1.4. By inspection, it is clear that beta = gamma = 1/3. t = ((a - p) dot n)/(d dot n) = (((1,0,0) - (1,1,1)) dot (1,1,1)) / ((-1,-1,-1)/sqrt(3) dot (1,1,1)) = ((0,-1,-1) dot (1,1,1)) / ((-1,-1,-1)/sqrt(3) dot (1,1,1)) = -2 / (-3/sqrt(3)) = 2/3 * sqrt(3) 1.5. [beta ] [b-a c-a -d] * [gamma] = p-a [ t ] [-1 -1 1/sqrt(3)] [beta ] [0] [ 1 0 1/sqrt(3)] * [gamma] = [1] [ 0 1 1/sqrt(3)] [ t ] [1] beta = gamma = 1/3, t = 2/3 * sqrt(3). 1.6. // intersect the cap // N = (0, -1, 0) // plane equation: y = -1 t_cap = (-1 - py) / dy x = px + dx*t_cap y = py + dy*t_cap if x^2 + y^2 > 1 t_cap = +infinity // intersect the side // cone equation: x^2 + z^2 = ((y+1)/2 - 1)^2 A = dx^2 - (dy/2)^2 + dz^2 B = 2*px*dx - (py-1)*dy/2 + 2*pz*dz C = px^2 - (py-1)^2 / 4 + pz^2 Det = B^2 - 4*A*C if Det >= 0 t_side = (-B - sqrt(Det)) / (2*A) if t_side > 0 y = py + dy*t_side if y < -1 || y > 1 t_side = (-B + sqrt(Det)) / (2*A) if t_side > 0 y = py + dy*t_side if y < -1 || y > 1 t_side = +infinity // find the closest intersection return min(t_cap,t_side) ------------------------------------------------------------------------ Problem 2 2.1.a. // pseudocode to find vertices of the shadow on the plane y = 0 for all v vertex of the rectangular colid p = (20, 20, 20) d = v-p t = -py/dy x = px + dx*t z = pz + dz*t The shadow is a polygon with the following vertices. 2,0,1/2 2,0,-1/2 -12.73, 0, -17.27 (a) -20, 0, -17.27 (b) -20, 0, -15.45 (c) -2, 0, 1/2 2.1.b. // pseudocode to find vertices of the shadow on the plane y = 0 for all v vertex of the rectangular solid d = (1,1,1) p = v-d t = -py/dy x = px + dx*t z = pz + dz*t The shadow is a polygon with the following vertices. 2,0,1/2 2,0,-1/2 -7, 0, -9.5 (a) -11, 0, -9.5 (b) -11, 0, -8.5 (c) -2, 0, 1/2 See the scan for the shape. 2.2. No, because a polished metal surface has no diffuse component. You will see only a reflection of other objects in the surface, and you can't tell where there is light shining on the surface from any directions other than the specular direction. ------------------------------------------------------------------------ Problem 3 3.1. a. to the right. (see diagram) b. in line. c. to the left. 3.2. The distance between the two parts of the pencil is: d * (tan(theta_1) - tan(theta_2)) * cos(theta_1)) In the diagram you can see that this is the distance along the wall, foreshortened by cos theta_1. where theta_2 = asin(sin(theta_1)/1.33) 3.3. Between 0 and 48.75 degrees is bright, getting somewhat dimmer toward the edge. Between 48.75 to 90 degrees it is dark (due to total reflection at the water surface, since Snell's law has no solution for these angles). 3.4. Yes. The diver can see anything above the water, so he can also see the man on the shore. He appears at the very edge of the bright circle. It's true that he will be quite distorted and might be hard to recognize. ------------------------------------------------------------------------ Problem 4 4.1. A has higher luminance. B has higher saturation. 4.2. The chromaticity is just the XYZ values, which are defined by the x_bar, y_bar, z_bar color matching functions, normalized by the sum: X = integral C(lambda)x_bar(lambda) dx Y = integral C(lambda)y_bar(lambda) dy Z = integral C(lambda)z_bar(lambda) dz x = X / (X+Y+Z) y = Y / (X+Y+Z) z = Z / (X+Y+Z) Red emission: x = 0.678, y = 0.321 Green emission: x = 0.207, y = 0.713 Blue emission: x = 0.149, y = 0.077 (traditionally one only reports x and y) Note that this problem is realistic in the sense that these phosphor curves look like real ones and the chromaticites are very close to the standard ones for the good old NTSC television system (which are a bit different from those used by modern systems, of which sRGB is intended to be representative). 4.3. The chromaticities of the monitor, [ x_r x_g x_b ] = [ 0.6779 0.2067 0.1494 ] xyz_m = [ x_r x_g x_b ] = [ 0.3213 0.7125 0.0769 ] [ x_r x_g x_b ] = [ 0.0008 0.0808 0.7737 ] give the mapping from monitor RGB to displayed XYZ, up to a scale factor in each of R, G, and B. That is, each of these columns is scaled by something (a per-channel gain adjustment in the monitor, essentially) to get the white point to be what it's defined to be. We can find the scale factors by solving the system [ x_r x_g x_b ] [ a_r ] [ x_w,m ] [ x_r x_g x_b ] [ a_g ] = [ y_w,m ] [ x_r x_g x_b ] [ a_b ] [ z_w,m ] where the as are the per-channel scale factors and [xyz]_w,m are the monitor's white point chromaticities. Note that there is still an overall scaling of this whole equation allowed because the white point is just a chromaticity, not an absolute color. Often you see this matrix normalized so that Y = 1 or Y = 100 for white, but since we are just transforming right back to RGB it does not matter for this problem. Now the mapping from RGB to XYZ for the monitor is: [ a_r x_r a_g x_g a_b x_b ] [ 0.1861 0.0559 0.0680 ] XYZ_m = [ a_r x_r a_g x_g a_b x_b ] = [ 0.0882 0.1928 0.0350 ] [ a_r x_r a_g x_g a_b x_b ] [ 0.0002 0.0219 0.3519 ] The same argument can be used to compute the matrix XYZ_s, which takes standard RGB to XYZ, from the standard chromaticities and white point: XYZ_s = 0.1361 0.1175 0.0593 0.0702 0.2351 0.0237 0.0064 0.0392 0.3124 If you're using Matlab, these expressions do the trick: XYZ_m = xyz_m * diag(xyz_m \ w_m) XYZ_s = xyz_s * diag(xyz_s \ w_s) The answer, then, is like any other basis conversion: map from sRGB to XYZ using XYZ_s, then map from XYZ to monitor RGB using the inverse of XYZ_m: T = inv(XYZ_m) * XYZ_s T = 0.7158 0.2915 0.0059 0.0339 1.0777 -0.0412 0.0156 0.0442 0.8904 As a sanity check, does white go to the right color? T * [1; 1; 1] gives 1.0132 1.0704 0.9502 and transforming that by XYZ_m gets the correct color. Since the problem doesn't specify anything about scaling, leaving T as is is fine. But a nice thing to do might be to scale to get white into the displayable range, by dividing by the largest element in the vector above (1.0704): T1 = T / max(T * [1;1;1]) T1 = 0.6687 0.2723 0.0055 0.0316 1.0068 -0.0385 0.0145 0.0413 0.8318 Now T1 * [1;1;1] gives 0.9465 1.0000 0.8876 which is a displayable color of the correct chromaticity. The page http://www.sigmadesigns.com/support/chromaticity_correction.htm has a nifty image comparison that illustrates the effect of this color correction.