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.