import numpy as np from sympy import * import math unit = lambda v: v/np.linalg.norm(v) def problem_1(): p = np.array([1, 4, 8]) e = np.array([0, 0, 0]) s = np.array([2, 2, 10]) i = p - e print("incoming", i) print("|I| =", np.linalg.norm(i)) n = s - p print("normal", n) n_norm = unit(n) print("normal_norm", n_norm) cos_theta_i = np.dot(-i, n) / (np.linalg.norm(i) * np.linalg.norm(n)) print("part a = cos^{-1} of ", cos_theta_i) print(np.arccos(cos_theta_i)) proj = n_norm * np.linalg.norm(i) * cos_theta_i print("proj", proj) p_ = p + proj print("proj point", p_) v2 = p_ - e print("v2", v2) sin_theta_i = np.sin(np.arccos(cos_theta_i)) print("sin theta_i =", sin_theta_i) theta_t = np.arcsin(1.0 / 1.5 * sin_theta_i) print("approx answer for part d", theta_t) uin = unit(n_norm) print("unit inv normal", uin) uperp = unit(v2) print("uperp", uperp) answer_1e = uin + math.tan(theta_t) * uperp - p print("1e answer", unit(answer_1e)) def problem_4(): print("part 4a.") up = np.array([0, 1, 0]) viewing_dir = np.array([1, -1, -1]) n = unit(viewing_dir) print(f"{n = }") u = unit(np.cross(up, n)) print(f"{u = }") v = np.cross(n, u) print(f"{v = }") print(math.sqrt(1 / 6.0)) print(math.sqrt(2 / 3.0)) def build_translation_matrix(vec): return np.array([ [1, 0, 0, vec[0]], [0, 1, 0, vec[1]], [0, 0, 1, vec[2]], [0, 0, 0, 1], ]) def problem_5(): b1 = build_translation_matrix(np.array([0, 0, 5])) theta = math.radians(-90) sin_theta = round( math.sin(theta), 5) cos_theta = round(math.cos(theta), 5) b2 = np.array([ [cos_theta, 0, sin_theta, 0], [0, 1, 0, 0], [-sin_theta, 0, cos_theta, 0], [0, 0, 0, 1], ]) b3 = build_translation_matrix(np.array([0, 0, -5])) print("b1", b1) print("b2", b2) print("b3", b3) M = b3 @ b2 @ b1 print("M", M) ex1 = np.array([1, 1, -4, 1]) print("ex1", ex1, M @ ex1) up = np.array([0, 1, 0]) n = np.array([1, 0, 0]) u = unit(np.cross(up, n)) v = np.cross(n, u) print(f"{up = }, {n = }, {u = }, {v = }") eye = np.array([5, 0, -5]) dx = -(np.dot(eye, u)) dy = -(np.dot(eye, v)) dz = -(np.dot(eye, n)) print(f"{dx = }, {dy = }, {dz = }") def problem_8(): def P(left, right, bottom, top, near, far): return np.array([ [2.0 * near / (right - left), 0, (right + left) / (right - left), 0], [0, 2.0 * near / (top - bottom), (top + bottom) / (top - bottom), 0], [0, 0, -(far + near) / (far - near), -(2.0 * far * near) / (far - near)], [0, 0, -1, 0], ]) near = 0.5 far = 20 def compute_view(vfov, hfov): left = -math.tan(hfov) * near right = math.tan(hfov) * near bottom = -math.tan(vfov) * near top = math.tan(vfov) * near return left, right, bottom, top print("part 8a") vfov = hfov = math.radians(60) left, right, bottom, top = compute_view(vfov, hfov) print(P(left, right, bottom, top, near, far)) print() print("\nPROBLEM 4 -------------------------"); problem_4() print("\nPROBLEM 8 -------------------------"); problem_8() print("\nPROBLEM 1 -------------------------"); problem_1() print("\nPROBLEM 5 -------------------------"); problem_5()