ECMM426-Template/Question 3.ipynb

306 lines
8.5 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"id": "924a2a50",
"metadata": {},
"source": [
"## Question 3 (10 marks)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "2b3d1ba2",
"metadata": {},
"outputs": [],
"source": [
"import math\n",
"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": "markdown",
"id": "c1e442a7",
"metadata": {},
"source": [
"## Method 1"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "e07b0285",
"metadata": {},
"outputs": [],
"source": [
"def m1_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 = translation_back @ rotation @ translation_to_origin\n",
" \n",
" return rotation_matrix"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "16ef4247",
"metadata": {},
"outputs": [],
"source": [
"m1_rotation_matrices = []\n",
"\n",
"for t in range(0, 365, 5):\n",
" m1_rotation_matrices.append( m1_compute_rotation_matrix(points, t) )"
]
},
{
"cell_type": "markdown",
"id": "5554bde0",
"metadata": {},
"source": [
"## Method 2"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "087b6ac9",
"metadata": {},
"outputs": [],
"source": [
"def m2_compute_rotation_matrix(points, theta):\n",
"\n",
" # Convert angle to radians\n",
" theta_rad = np.deg2rad(theta)\n",
" \n",
" cos_theta = np.cos(theta_rad)\n",
" sin_theta = np.sin(theta_rad)\n",
"\n",
" # Compute center of the shape\n",
" center = np.mean(points, axis=0)\n",
" \n",
" # Construct rotation matrix\n",
" rotation_matrix = np.array([\n",
" [ cos_theta, -sin_theta, -center[0] * cos_theta + center[1] * sin_theta + center[0] ],\n",
" [ sin_theta, cos_theta, -center[0] * sin_theta - center[1] * cos_theta + center[1] ],\n",
" [0, 0, 1]\n",
" ])\n",
" \n",
" return rotation_matrix"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "02ec3b60",
"metadata": {},
"outputs": [],
"source": [
"m2_rotation_matrices = []\n",
"\n",
"for t in range(0, 365, 5):\n",
" m2_rotation_matrices.append( m2_compute_rotation_matrix(points, t) )"
]
},
{
"cell_type": "markdown",
"id": "a130c201",
"metadata": {},
"source": [
"## Save Output"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "23967b5d",
"metadata": {},
"outputs": [],
"source": [
"np.save('data/question_3_rotation_matrices.npy', m1_rotation_matrices)"
]
},
{
"cell_type": "markdown",
"id": "a808d8a4",
"metadata": {},
"source": [
"## Put students' implementations here"
]
},
{
"cell_type": "markdown",
"id": "06417b95",
"metadata": {},
"source": [
"This is one common **mistake**."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "b0836f8d",
"metadata": {},
"outputs": [],
"source": [
"def compute_rotation_matrix(points, theta):\n",
"\n",
" # Convert angle to radians\n",
" theta_rad = np.deg2rad(theta)\n",
" \n",
" # Calculate sine and cosine of the angle\n",
" cos_theta = np.cos(theta_rad)\n",
" sin_theta = np.sin(theta_rad)\n",
" \n",
" # Compute center of the shape\n",
" center = np.mean(points, axis=0)\n",
" \n",
" # Translate points to origin\n",
" translated_points = points - center\n",
" \n",
" # Wrong: Construct rotation matrix\n",
" rotation_matrix = np.array([[cos_theta, -sin_theta, center[0]],\n",
" [sin_theta, cos_theta, center[1]],\n",
" [0, 0, 1]])\n",
" \n",
" return rotation_matrix"
]
},
{
"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": 9,
"id": "132d734b",
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 PASS\n",
"Failed\n"
]
},
{
"ename": "AssertionError",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)",
"Cell \u001b[1;32mIn[9], line 9\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[38;5;28mprint\u001b[39m(n_pass, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPASS\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 8\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m----> 9\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m n_pass \u001b[38;5;241m==\u001b[39m \u001b[38;5;28mlen\u001b[39m(m1_rotation_matrices)\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mALL PASS\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 11\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mAssertionError\u001b[39;00m:\n",
"\u001b[1;31mAssertionError\u001b[0m: "
]
}
],
"source": [
"n_pass = 0\n",
"for t in range(0, 365, 5):\n",
" if np.allclose(compute_rotation_matrix(points, t), m1_rotation_matrices[int(t / 5)]):\n",
" n_pass = n_pass + 1\n",
"\n",
"print(n_pass, \"PASS\")\n",
"\n",
"try:\n",
" assert n_pass == len(m1_rotation_matrices)\n",
" print(\"ALL PASS\")\n",
"except AssertionError:\n",
" print(\"Failed\")\n",
" raise"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "03e9c423",
"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
}