{ "cells": [ { "cell_type": "markdown", "id": "924a2a50", "metadata": {}, "source": [ "## Question 3 (10 marks)" ] }, { "cell_type": "code", "execution_count": 1, "id": "2b3d1ba2", "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": 2, "id": "478bad7a", "metadata": {}, "outputs": [], "source": [ "points = np.load('data/points.npy').astype(np.uint8)" ] }, { "cell_type": "code", "execution_count": 3, "id": "e07b0285", "metadata": {}, "outputs": [], "source": [ "def compute_rotation_matrix(points, theta):\n", " \"\"\"\n", " Write a function compute_rotation_matrix(points, theta) to compute the rotation matrix in\n", " homogeneous coordinate system to rotate a shape depicted with 2-dimensional (x,y) coordinates\n", " points with an angle 𝜃 (theta in the definition) in the anticlockwise direction about the centre of the shape.\n", "\n", " Parameters:\n", " points: a 2-dimensional numpy array of data type uint8 with shape 𝑘 × 2. Each row\n", " of points is a Cartesian coordinate (x, y).\n", " \n", " theta: a floating-point number denoting the angle of rotation in degree.\n", " \n", " Returns:\n", " The expected output is a 2-dimensional numpy array of data type float64 with shape 3 × 3.\n", " \"\"\"\n", "\n", " # Convert theta from degrees to radians\n", " theta_rad = np.radians(theta)\n", "\n", " # Calculate the centre of the shape\n", " centre = np.mean(points, axis=0)\n", "\n", " # Define the translation matrices to move the centre of the shape to the origin and back\n", " translation_to_origin = np.array([[1, 0, -centre[0]],\n", " [0, 1, -centre[1]],\n", " [0, 0, 1]], dtype=np.float64)\n", "\n", " translation_back = np.array([[1, 0, centre[0]],\n", " [0, 1, centre[1]],\n", " [0, 0, 1]], dtype=np.float64)\n", "\n", " # Define the rotation matrix about the origin\n", " rotation = np.array([[np.cos(theta_rad), -np.sin(theta_rad), 0],\n", " [np.sin(theta_rad), np.cos(theta_rad), 0],\n", " [0, 0, 1]], dtype=np.float64)\n", "\n", " # Combine the translation and rotation into a single transformation matrix\n", " rotation_matrix = np.dot(np.dot(translation_back, rotation), translation_to_origin)\n", " \n", " return rotation_matrix" ] }, { "cell_type": "code", "execution_count": 4, "id": "16ef4247", "metadata": {}, "outputs": [], "source": [ "rotation_matrices = []\n", "\n", "for t in range(0, 365, 5):\n", " rotation_matrices.append( compute_rotation_matrix(points, t) )" ] }, { "cell_type": "markdown", "id": "a130c201", "metadata": {}, "source": [ "## Save Output" ] }, { "cell_type": "code", "execution_count": 5, "id": "23967b5d", "metadata": {}, "outputs": [], "source": [ "np.save('data/question_3_rotation_matrices.npy', rotation_matrices)" ] }, { "cell_type": "markdown", "id": "a808d8a4", "metadata": {}, "source": [ "## Put students' implementations here" ] }, { "cell_type": "code", "execution_count": 6, "id": "b0836f8d", "metadata": {}, "outputs": [], "source": [ "def compute_rotation_matrix(points, theta):\n", " # Convert points to float64\n", " points = points.astype(np.float64)\n", " # Calculate centre\n", " centre = np.mean(points, axis=0)\n", " # Compute rotation matrix\n", " rotation_matrix = np.array([[np.cos(np.radians(theta)), -np.sin(np.radians(theta)), 0],\n", " [np.sin(np.radians(theta)), np.cos(np.radians(theta)), 0],\n", " [0, 0, 1]])\n", " # Translation matrix to origin\n", " translation_to_origin = np.array([[1, 0, -centre[0]],\n", " [0, 1, -centre[1]],\n", " [0, 0, 1]])\n", " # Translation matrix to original position\n", " translation_to_centre = np.array([[1, 0, centre[0]],\n", " [0, 1, centre[1]],\n", " [0, 0, 1]])\n", " # Combine transformations with data type float64 \n", " combined_matrix = np.dot(np.dot(translation_to_centre, rotation_matrix), translation_to_origin).astype(np.float64)\n", " return combined_matrix\n", "\n", " return 0" ] }, { "cell_type": "markdown", "id": "73b68192", "metadata": {}, "source": [ "## Test (Should output ALL PASS)" ] }, { "cell_type": "markdown", "id": "1c0a88a6", "metadata": {}, "source": [ "Restart and Run ALL for each submission" ] }, { "cell_type": "code", "execution_count": 7, "id": "132d734b", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "73 PASS\n", "ALL PASS\n" ] } ], "source": [ "n_pass = 0\n", "for t in range(0, 365, 5):\n", " if np.allclose(compute_rotation_matrix(points, t), rotation_matrices[int(t / 5)]):\n", " n_pass = n_pass + 1\n", "\n", "print(n_pass, \"PASS\")\n", "assert n_pass == len(rotation_matrices)\n", "print(\"ALL PASS\")" ] }, { "cell_type": "code", "execution_count": null, "id": "0fac308a", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "what", "language": "python", "name": "what" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.16" } }, "nbformat": 4, "nbformat_minor": 5 }