Computer Graphics Homework 1v2 CS417/CS418 Fall 1998 Due Wednesday, February 10, 1999 * Make sure you've turned in the waiver and its requested e-mail.* Hand in each part (CS417, CS418, administrative) SEPARATELY.* Make sure your names are legible and easily spotted on the front page of each part.* As always in this class, you are graded on correctness and also clarity and conciseness.* Write legibly & sign & date the following (fill blanks appropriately): "I, , CUID# , wrote up this assignment; my partner is , CUID# ."* E-mail how many total hours this homework takes you by midnight, Friday, February 12. 0. Follow the instructions above. Failure to do so will be penalized. Feedback is always welcome. CS417 Part 1. Let us look at two derivations of the distance between a point w = (w1, w2) and the line defined by the origin and a point v = (v1, v2) 6= (0, 0). Show all your work. (a) Compute the projection u of w onto v and then compute the distance between u and w. Stick with vector notation (no vector components). Answer: rw * w - (w * v) 2 v * v . HW#0 tells us projection of w onto v is gives u = (w*v) v*v v.The distance squared between u and w is |u - w|2 = (u - w) * (u - w) = u * u - 2u * w + w * w = i w * vv * v vj * i w * vv * v vj - 2 i w * vv * v vj * w + w * w = i w * vv * v j 2 v * v - 2 w * v v * v w * v + w * w = w * w - (w * v) 2 v * v . (b) Compute a (non-zero) vector u that is perpendicular to v (solve for u * v = 0 or rotate v by +-90 degrees). Compute the length of the projection of w onto u. For this part, expand your answer in terms of vector components. Answer: |v2w1 - v1w2|pv2 1 + v22 . Vector u = (v2, -v1) satisfies u * v = 0, as does unit vector u| u| = up v21 + v22 . The length of the projection of w onto u| u| is simply the absolute value of their dot product w * u|u|. 2. Suppose we rotate, scale (uniformly in all directions), and translate the plane so that the the origin ends up at a = (xa, ya), and the point (1, 0) ends up at b = (xb, yb). NOTE: No flipping/reflection (e.g. (x, y) 7! (x, -y)) is done. Express this sequence of transformations as a single 3-by-3 matrix (that is applied to homogenous coordinates). Show your work. Your final answer should not involve any angles or trig functions. Answer: We scale, then rotate, then translate. Since the scaling is uniform, it commutes with the rotation. The general forms of the rotation matrix R, scale matrix S, and translation matrix T are R = 0@ cos ` sin ` 0- sin ` cos ` 0 0 0 1 1A S = 0@ sx 0 0 0 sy 0 0 0 1 1A T = 0@ 1 0 tx 0 1 ty 0 0 1 1A Let w = b - a = (w1, w2). The scale factor sx = sy = |w| is the distance from b to a. We can compute sin ` and cos ` from w = |w| (cos `, sin `), i.e. cos ` = w1/|w|, sin ` = w2/|w|. The translation is simply (tx, ty) = a. This gives us the final transformation T RS:0@ 1 0 xa 0 1 ya 0 0 1 1A 0@ w1/|w| w2/|w| 0- w2/|w| w1/|w| 0 0 0 1 1A 0@ |w| 0 0 0 |w| 0 0 0 1 1A = 0@ 1 0 xa 0 1 ya 0 0 1 1A 0@ w1 w2 0- w2 w1 0 0 0 1 1A = 0@ w1 w2 xa- w2 w1 ya 0 0 1 1A = 0@ xb - xa yb - ya xa ya - yb xb - xa ya 0 0 1 1A 3. (Moved into CS418 part) 4. Write a Matlab function so that [x,y,z]=torus(m,n,r,R); surf(x,y,z) plots a torus obtained as follows. Place a circle in the xz-plane with center x = R, z = 0 and radius r; sample the circle at m points. Revolve the circle around the z-axis; sample at n points, i.e. create n such circles. Don't worry about accuracy (the original (my)sphere code worries that cos(pi/2) does not yield 0). Avoid loops. Demonstrate with m = 11, n = 40, r = 1, R = 2; use axis equal to fix the aspect ratio. Turn in your code and a printout of the plot. HINT: modify mypshere, which does the following. Place half a unit circle in the xz-plane centered at the origin, sampled at m points. Revolve the half circle around the z-axis, sampled at n points. Answer: (See Watt page 53 Figure 2.27 for the parametric representation of a torus.) function [x,y,z] = torus(m,n,r,R) %TORUS Generate torus. % [X,Y,Z] = TORUS(M,N,r,R) generates three (m+1)-by-(n+1) % matrices so that SURF(X,Y,Z) produces a % with m latitude and n longitude lines. % Modified from sphere.m code by Clay M. Thompson 4-24-91, CBM 8-21-92. theta = (0:n)/n*2*pi; % 0 <= theta <= 2pi is a row vector -- "longitude" phi = (0:m)'/m*2*pi; % 0 <= phi <= 2pi is a column vector -- "latitude" % compute cross section x = R+r*cos(phi); z = r*sin(phi); % rotate cross section y = x*sin(theta); x = x*cos(theta); z = z*ones(1,n+1); -3 -2 -1 0 1 2 3 -3 -2 -1 0 1 2 3 -0.5 0 0.5 CS418 Part 5. (Moved out of HW#1) 3. Write a Matlab function so that dst=rotatesuper(src,angle,n) returns the source image src rotated by angle radians. For better accuracy than our code from lecture/newsgroup, divide each source pixel into n * n subpixels, map them to destination pixels, and average appropriately. Avoid loops. Turn in your code and a printout of the image from durer rotated by ss/6 radians. Answer: function [dst] = rotatesuper(src,angle,n) % function [DST] = ROTATESUPER(SRC,ANGLE,N) % compute destination image DST = source image SRC rotated by ANGLE radians. % For better accuracy, divide each source pixel into nxn subpixels, map them % to destination pixels, and average appropriately. sz = prod(size(src)); % total # of pixels of source image % use (1:n*S)'/n to construct a row vector of n*S evenly spaced points % between 1/n to S (inclusive) % In effect, expand each source pixel to nxn subpixels in the rotating % algorithm given in class % create parallel arrays i, j, src that list % all the coordinates and values of the sub-pixels (same as enclosing pixel) i = (1:n*size(src,1))/n; j = (1:n*size(src,2))/n; src2 = reshape(src(ceil(i), ceil(j)), 1, sz*n*n); % we approximate the color of subpixel (x,y) as the color of the pixel % (ceil(x), ceil(y)) i = reshape(i' * ones(1,n*size(src,2)), 1, sz*n*n); j = reshape(ones(n*size(src,1),1) * j, 1, sz*n*n); % rotate all the subpixels; store coordinates in parallel arrays ii, jj ii = ceil(cos(angle) * i - sin(angle) * j); jj = ceil(cos(angle) * j + sin(angle) * i); % Each rotated subpixel (xx,yy) contributes to color of (ceil(xx),ceil(yy)) % Consistent with the rule for source subpixels for better approximation. % build dst image by adding the contributions of all the sub-pixels: % each sub-pixel contributes 1/(n*n) of the original pixel's value dst = full(sparse(ii+1-min(ii), jj+1-min(jj), src2))/(n*n); It should be noted that in the last step, we assume that each sub-pixel contributes 1n2 of the destination pixel's value, and average the value of each destination pixel by dividing it by n2. This is what was expected. However, this is only one way of approximation. It turns out that averaging by the actual number of subpixels mapped to the same destination pixel looks better: dst = full(sparse(ii+1-min(ii), jj+1-min(jj), src2)); dst = dst ./max(1, full(sparse(ii+1-min(ii), jj+1-min(jj), 1))); The denominator simply counts (by adding 1 for each hit) the number of source subpixels landing in each destination pixel, and the max(1, ...) is to avoid dividing by zero. This looks better because if the our original code has gaps, then supersampling puts only a few sub-pixels into the gaps, so dividing by n2 makes the "gaps" too dark. 100 200 300 400 500 600 700 100 200 300 400 500 600 700 800