Disabled external gits
This commit is contained in:
749
cs457-gc/assignment_3_1/notebook/smooth_surfaces.ipynb
Normal file
749
cs457-gc/assignment_3_1/notebook/smooth_surfaces.ipynb
Normal file
@@ -0,0 +1,749 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "ac87e6fb-030a-4c57-8cdc-20a9450c0a4f",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"# Assignment 3.1: Differential Geometry of smooth surfaces"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "eb14a5c8-13ce-4d21-8167-ddbb674225e2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/opt/conda/bin/python\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import sys\n",
|
||||
"print(sys.executable)\n",
|
||||
"import meshplot as mp\n",
|
||||
"sys.path.append('../src/')\n",
|
||||
"from smooth_surfaces import *\n",
|
||||
"from utils import *"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4949242e-7532-4744-836c-3da903f42ea9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Paraboloid surface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5290233d-e1c7-464f-b116-63917aaa8df3",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To evaluate the paraboloid surface, we first sample the domain $\\Omega$ with a regular grid. For that, we specify the $u$ and $v$ intervals, and the sampling in the two directions:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "b06d705d-1164-496f-9f58-00267da59e81",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"u_interval = [-1, 1]\n",
|
||||
"v_interval = [-1, 1]\n",
|
||||
"u_sampling = 21\n",
|
||||
"v_sampling = 21"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "23442be0-a0bc-42ea-83bd-23693de97a49",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We use now the following provided function that creates the points $p\\in\\Omega\\subseteq\\mathbb R^2$, collected in the array `P`, and a triangulation `F` for visualization:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "ae541330-6a57-46d4-a8cd-7005fe8cd70e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"P, F = uv_grid(u_interval, v_interval, u_sampling, v_sampling)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "600fbd25-4295-4074-a979-9d2a7aac8b45",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can now choose the parameters of the paraboloid:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 164,
|
||||
"id": "a0169d4c-ae67-4e23-92ec-798a7012e649",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"a = 0.2\n",
|
||||
"b = 0.2\n",
|
||||
"c = -0.2\n",
|
||||
"d = -0.2\n",
|
||||
"e = 0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "35a40d7a-2ac8-4248-b497-39dafac57078",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Try to change the parameters to get and then compute the corresponding paraboloid points $\\mathbf x(p)\\in\\mathbb R^3$ and the derivatives of the parametrization at that points:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 165,
|
||||
"id": "75d4933e-2a64-4c01-91d7-3c9c47ace5a1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = compute_paraboloid_points(P, a, b, c, d, e)\n",
|
||||
"\n",
|
||||
"x_u, x_v = compute_paraboloid_first_derivatives(P, a, b, c, d, e)\n",
|
||||
"\n",
|
||||
"x_uu, x_uv, x_vv = compute_paraboloid_second_derivatives(P, a, b, c, d, e)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e41fefc0-dbd9-4fb7-bf4a-ae0e034bfb9b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Principal curvatures"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bc4a49ce-a517-4a5b-a6bb-18aad4be33fc",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We define now a function that computes the principal curvatures of the surface at the points by using your functions:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 166,
|
||||
"id": "0577a574-95c2-4d0b-97a2-b5ca04235552",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def principal_curvatures(x_u, x_v, x_uu, x_uv, x_vv):\n",
|
||||
"\n",
|
||||
" n = compute_surface_normal(x_u, x_v)\n",
|
||||
"\n",
|
||||
" I = compute_first_fundamental_form(x_u, x_v)\n",
|
||||
"\n",
|
||||
" II = compute_second_fundamental_form(x_uu, x_uv, x_vv, n)\n",
|
||||
"\n",
|
||||
" S = compute_shape_operator(I, II)\n",
|
||||
"\n",
|
||||
" return compute_principal_curvatures(S, x_u, x_v)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "064c8eba-7b20-4b30-8064-40db7a2e3e4d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and use it to evaluate the principal curvatures $\\kappa_1$ and $\\kappa_2$ with the corresponding principal directions $\\mathbf e_1$ and $\\mathbf e_2$ at each surface point:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 167,
|
||||
"id": "26483943-2117-4b33-b13f-54351ea4ee1e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"k_1, k_2, e_1, e_2 = principal_curvatures(x_u, x_v, x_uu, x_uv, x_vv)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "0ae42813-cd7f-4b27-b9c4-9407a5a79e44",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can compute now the Gaussian curvature $K$ and the mean curvature $H$ as"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 168,
|
||||
"id": "d365f3c0-c069-4645-a360-ba4f2219f3c3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"K = k_1 * k_2\n",
|
||||
"\n",
|
||||
"H = (k_1 + k_2)/2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "34710736-2847-42e3-9468-3d620bb82d4b",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"To display the surface and the curvature, we define a plot function that colors points according to the curvature values with a blue-green-red color scale, with blue for negative values, green for zero, and red for positive values."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 169,
|
||||
"id": "4ac8a92c-ded6-485b-b0d0-9d692fc96a73",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def plot_curvature(x, F, values):\n",
|
||||
" color = bgr_color(values)\n",
|
||||
" shading_options = {\n",
|
||||
" \"flat\":False,\n",
|
||||
" \"wireframe\":False,\n",
|
||||
" \"metalness\": 0,\n",
|
||||
" }\n",
|
||||
" mp.plot(x, F, c=color, shading=shading_options)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "97dfabad-89d6-4d16-a028-5809aa4d3d22",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and use it to visualize the Gaussian curvature of the surface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 170,
|
||||
"id": "ccb2dde3-cf23-4c0f-81bc-1de8f0910eb3",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "fd0f312ceca0422583d581083529866e",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(3.1415927…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_curvature(x, F, K)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "1d166a4e-04dd-4d0d-a248-b5baf5e7dcf8",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and the mean curvature"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 171,
|
||||
"id": "400c14b0-e551-4363-ac36-a71d8bd74fb8",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "b0f1ccdc2b3c43dcb18857be4c6d7083",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(3.1415927…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_curvature(x, F, H)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "afcb4e17-7677-4bb5-acc4-2548e77cd8f9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We want now to visualize directions on the surface. For that define the plot function"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 172,
|
||||
"id": "75c72db5-cd8a-4a73-9c4b-ed17f6a870a2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def plot_directions(x, F, d_1, d_2, scale=0.1):\n",
|
||||
" color = np.ones((len(x), 3))\n",
|
||||
" shading_options = {\n",
|
||||
" \"flat\": False,\n",
|
||||
" \"wireframe\":False,\n",
|
||||
" \"metalness\": 0.05,\n",
|
||||
" }\n",
|
||||
" p = mp.plot(x, F, c=color, shading=shading_options)\n",
|
||||
" p.add_lines(x+d_1*scale, x-d_1*scale, shading={\"line_color\": \"red\"})\n",
|
||||
" p.add_lines(x+d_2*scale, x-d_2*scale, shading={\"line_color\": \"blue\"})\n",
|
||||
" p.update_object()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "94fc28d4-795d-440a-9c86-373186989d81",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can now display the principal curvature directions."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 173,
|
||||
"id": "8435ea44-6114-4d96-9483-9b4d6ea1c36f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "851bbfdf30f44a228f72b790a8fb6a88",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(3.1415927…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_directions(x, F, e_1, e_2, scale=0.08)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "efc58d26-2eae-490c-b8f0-a0226c63b978",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Asymptotic directions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "22d70cd0-c1c1-496d-8513-e6f35a715be5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We estimate now the asymptotic directions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 174,
|
||||
"id": "9f872d92-2dea-41fc-a273-f3e65d4e5086",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"a_1, a_2 = compute_asymptotic_directions(k_1, k_2, e_1, e_2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "dd7f02ac-825c-4ed4-bc88-8569cd7696e2",
|
||||
"metadata": {
|
||||
"tags": []
|
||||
},
|
||||
"source": [
|
||||
"and display them"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 175,
|
||||
"id": "98b09cbb-b742-4457-99d2-8c59b9ec40c5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "8091f6dfb14e4c2398bb2d503c8c12a3",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(3.1415927…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_directions(x, F, a_1, a_2, scale=0.08)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "cd635566-05e4-48fc-93ec-0cee724e7751",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Torus surface"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "238ae4db-5c65-41fc-b5f5-cbea30683c9c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We display now the same quantities for thr torus surface, and start defining the domain interval and sampling"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "4e1aa125-23ca-42f8-b846-7c9d8f7444bb",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"u_interval = [0, 2*np.pi]\n",
|
||||
"v_interval = [0, 2*np.pi]\n",
|
||||
"u_sampling = 33\n",
|
||||
"v_sampling = 33"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4fd11272-b041-4880-88f0-398987b360da",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We now create an $u$-$v$ grid"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"id": "d298045e-3294-4ec4-ab22-28a9670c2ce2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"P, F = uv_grid(u_interval, v_interval, u_sampling, v_sampling)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "da8fb757-e162-463b-9226-46ff6c6ab90c",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and choose the torus radii"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 18,
|
||||
"id": "aa3a5ac0-06ea-446a-ab6c-917265487c29",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"R = 2\n",
|
||||
"\n",
|
||||
"r = 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "40dda590-2553-4a8a-a2f7-e0242eb5fec7",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We can now proceed as for the paraboloid:"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"id": "870c5ee0-dd7e-4a87-9a64-2820513ff38e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"x = compute_torus_points(P, R, r)\n",
|
||||
"\n",
|
||||
"x_u, x_v = compute_torus_first_derivatives(P, R, r)\n",
|
||||
"\n",
|
||||
"x_uu, x_uv, x_vv = compute_torus_second_derivatives(P, R, r)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "63c523f3-7db0-4bd1-8b04-8d7ddc66cfa9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Principal curvatures"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"id": "f8da5db4-74c3-4c68-ac58-f123ce75c446",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"k_1, k_2, e_1, e_2 = principal_curvatures(x_u, x_v, x_uu, x_uv, x_vv)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"id": "d0a4bab6-d7e8-46ee-a0e3-fbf32a4c12c5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"K = k_1 * k_2\n",
|
||||
"\n",
|
||||
"H = (k_1 + k_2)/2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "bc627815-58fd-40a7-afe8-a68adc8bac04",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"We plot now the Gaussian curvature $K$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"id": "2cea4c46-a698-4a3e-91ad-a86cd2484b54",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "cccde70c2ddb4a7896fe694fdd3f4f9a",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.0, 0.0,…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_curvature(x, F, K)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e05c34b0-770f-42fb-abd9-c8e790c2033a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"the mean curvature $H$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"id": "727be3f1-02b1-4db1-842d-c2ca5f619694",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "5cfec29c275e4ad09fd9ed50ca3e1048",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.0, 0.0,…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_curvature(x, F, H)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "4e2e4c3f-1a8c-4120-befc-1f7a3ea377b0",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"and the principal curvature directions $\\mathbf e_1$ and $\\mathbf e_2$"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 24,
|
||||
"id": "6255e260-df73-4d4a-b8ec-2cd922d9942f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "ef10f31b1d7d41c4a45129198f1a5ba4",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.0, 0.0,…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_directions(x, F, e_1, e_2, scale=0.12)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "5be26065-90f5-4fba-9dc4-80e283117dc9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Asymptotic directions\n",
|
||||
"\n",
|
||||
"Finally, we can plot the asymptotic directions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"id": "7c9161e6-7ef0-42ea-b1ec-fc9dd49533e0",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"../src/smooth_surfaces.py:418: RuntimeWarning: invalid value encountered in sqrt\n",
|
||||
" sinT = np.sqrt(f)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"a_1, a_2 = compute_asymptotic_directions(k_1, k_2, e_1, e_2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 26,
|
||||
"id": "ac71ac02-d0c0-4dd1-94af-227b3636ed9f",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"application/vnd.jupyter.widget-view+json": {
|
||||
"model_id": "3f3da2e0f0474e4aaac9e29e11068f4f",
|
||||
"version_major": 2,
|
||||
"version_minor": 0
|
||||
},
|
||||
"text/plain": [
|
||||
"Renderer(camera=PerspectiveCamera(children=(DirectionalLight(color='white', intensity=0.6, position=(0.0, 0.0,…"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"plot_directions(x, F, a_1, a_2, scale=0.12)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "a64403c3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "87a49e59",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "6f639996",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "483b637b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "99069ff6",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "gc_course_env",
|
||||
"language": "python",
|
||||
"name": "gc_course_env"
|
||||
},
|
||||
"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.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
423
cs457-gc/assignment_3_1/src/smooth_surfaces.py
Normal file
423
cs457-gc/assignment_3_1/src/smooth_surfaces.py
Normal file
@@ -0,0 +1,423 @@
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# DERIVATIVES OF PARABOLOID
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def compute_paraboloid_points(P, a, b, c, d, e):
|
||||
"""Computes the points of the paraboloid x(u,v) = (u, v, z(u,v)) with
|
||||
z(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- a, b, c, d, e : float
|
||||
The parameters of the paraboloid.
|
||||
|
||||
Returns:
|
||||
- x : np.array (n, 3)
|
||||
The points x(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the point x(p_i)
|
||||
"""
|
||||
n = a*P[:,0]**2 + \
|
||||
b*P[:,1]**2 + \
|
||||
c*P[:,0]*P[:,1] + \
|
||||
d*P[:,0] + \
|
||||
e*P[:,1]
|
||||
|
||||
x = np.dstack((P[:,0],P[:,1],n))[0]
|
||||
return x
|
||||
|
||||
|
||||
def compute_paraboloid_first_derivatives(P, a, b, c, d, e):
|
||||
"""Computes the first derivatives of the paraboloid x(u,v) = (u, v, z(u,v))
|
||||
with z(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- a, b, c, d, e : float
|
||||
The parameters of the paraboloid.
|
||||
|
||||
Returns:
|
||||
- x_u : np.array (n, 3)
|
||||
The vectors x_u(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_u(p_i).
|
||||
- x_v : np.array (n, 3)
|
||||
The vectors x_v(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_v(p_i).
|
||||
"""
|
||||
nu = 2*a*P[:,0] + \
|
||||
c*P[:,1] + \
|
||||
d
|
||||
nv = 2*b*P[:,1] + \
|
||||
c*P[:,0] + \
|
||||
e
|
||||
|
||||
z = np.zeros(P.shape[0])
|
||||
o = np.ones(P.shape[0])
|
||||
|
||||
x_u = np.dstack((o,z,nu))[0]
|
||||
x_v = np.dstack((z,o,nv))[0]
|
||||
return x_u, x_v
|
||||
|
||||
|
||||
def compute_paraboloid_second_derivatives(P, a, b, c, d, e):
|
||||
"""Computes the second derivatives of the paraboloid x(u,v) = (u, v, z(u,v))
|
||||
with z(u,v) = a*u^2 + b*v^2 + c*u*v + d*u + e*v.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- a, b, c, d, e : float
|
||||
The parameters of the paraboloid.
|
||||
|
||||
Returns:
|
||||
- x_uu : np.array (n, 3)
|
||||
The vectors x_uu(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_uu(p_i).
|
||||
- x_uv : np.array (n, 3)
|
||||
The vectors x_uv(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_uv(p_i).
|
||||
- x_vv : np.array (n, 3)
|
||||
The vectors x_vv(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_vv(p_i).
|
||||
"""
|
||||
nuu = np.repeat(2*a, P.shape[0])
|
||||
nuv = np.repeat( c, P.shape[0])
|
||||
nvv = np.repeat(2*b, P.shape[0])
|
||||
|
||||
z = np.zeros(P.shape[0])
|
||||
|
||||
x_uu = np.dstack((z,z,nuu))[0]
|
||||
x_uv = np.dstack((z,z,nuv))[0]
|
||||
x_vv = np.dstack((z,z,nvv))[0]
|
||||
|
||||
return x_uu, x_uv, x_vv
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# DERIVATIVES OF TORUS
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def compute_torus_points(P, R, r):
|
||||
"""Computes the second derivatives of a torus.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- R : float
|
||||
The radius of revolution.
|
||||
- r : float
|
||||
The radius of the cross section.
|
||||
Returns:
|
||||
- x : np.array (n, 3)
|
||||
The points x(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the point x(p_i)
|
||||
"""
|
||||
cosu = np.cos(P[:,0])
|
||||
sinu = np.sin(P[:,0])
|
||||
cosv = np.cos(P[:,1])
|
||||
sinv = np.sin(P[:,1])
|
||||
fx = (r * cosu+ R) * cosv
|
||||
fy = (r * cosu+ R) * sinv
|
||||
fz = r * sinu
|
||||
|
||||
x = np.dstack((fx, fy, fz))[0]
|
||||
return x
|
||||
|
||||
|
||||
def compute_torus_first_derivatives(P, R, r):
|
||||
"""Computes the second derivatives of a torus.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- R : float
|
||||
The radius of revolution.
|
||||
- r : float
|
||||
The radius of the cross section.
|
||||
Returns:
|
||||
- x_u : np.array (n, 3)
|
||||
The vectors x_u(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_u(p_i).
|
||||
- x_v : np.array (n, 3)
|
||||
The vectors x_v(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_v(p_i).
|
||||
"""
|
||||
cosu = np.cos(P[:,0])
|
||||
sinu = np.sin(P[:,0])
|
||||
cosv = np.cos(P[:,1])
|
||||
sinv = np.sin(P[:,1])
|
||||
|
||||
z = np.zeros(P.shape[0])
|
||||
|
||||
fx_u = - r * sinu * cosv
|
||||
fy_u = - r * sinu * sinv
|
||||
fz_u = r * cosu
|
||||
|
||||
fx_v = -(r * cosu+ R) * sinv
|
||||
fy_v = (r * cosu+ R) * cosv
|
||||
fz_v = z
|
||||
|
||||
x_u = np.dstack((fx_u, fy_u, fz_u))[0]
|
||||
x_v = np.dstack((fx_v, fy_v, fz_v))[0]
|
||||
return x_u, x_v
|
||||
|
||||
|
||||
def compute_torus_second_derivatives(P, R, r):
|
||||
"""Computes the second derivatives of a torus.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- P : np.array (n, 2)
|
||||
Contains in i-th row the (u, v) coordinates of the i-th parameter point p_i.
|
||||
- R : float
|
||||
The radius of revolution.
|
||||
- r : float
|
||||
The radius of the cross section.
|
||||
|
||||
Returns:
|
||||
- x_uu : np.array (n, 3)
|
||||
The vectors x_uu(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_uu(p_i).
|
||||
- x_uv : np.array (n, 3)
|
||||
The vectors x_uv(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_uv(p_i).
|
||||
- x_vv : np.array (n, 3)
|
||||
The vectors x_vv(P), where the i-th row contains the (x,y,z) coordinates
|
||||
of the vector x_vv(p_i).
|
||||
"""
|
||||
cosu = np.cos(P[:,0])
|
||||
sinu = np.sin(P[:,0])
|
||||
cosv = np.cos(P[:,1])
|
||||
sinv = np.sin(P[:,1])
|
||||
|
||||
z = np.zeros(P.shape[0])
|
||||
|
||||
fx_uu = - r * cosu * cosv
|
||||
fy_uu = - r * cosu * sinv
|
||||
fz_uu = - r * sinu
|
||||
|
||||
fx_uv = (r * sinu) * sinv
|
||||
fy_uv = -(r * sinu) * cosv
|
||||
fz_uv = z
|
||||
|
||||
fx_vv = -(r * cosu+ R) * cosv
|
||||
fy_vv = -(r * cosu+ R) * sinv
|
||||
fz_vv = z
|
||||
|
||||
x_uu = np.dstack((fx_uu, fy_uu, fz_uu))[0]
|
||||
x_uv = np.dstack((fx_uv, fy_uv, fz_uv))[0]
|
||||
x_vv = np.dstack((fx_vv, fy_vv, fz_vv))[0]
|
||||
return x_uu, x_uv, x_vv
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# SHAPE OPERATOR
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def compute_first_fundamental_form(x_u, x_v):
|
||||
"""Computes the first fundamental form I.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- x_u : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_u(p_i).
|
||||
- x_v : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_v(p_i).
|
||||
|
||||
Returns:
|
||||
- I : np.array (n, 2, 2)
|
||||
The first fundamental forms.
|
||||
The (i, j, k) position contains the (j, k) element of the first
|
||||
fundamental form I(p_i).
|
||||
"""
|
||||
e00 = np.einsum('lm,ml->m',x_u.T,x_u)
|
||||
e01 = np.einsum('lm,ml->m',x_u.T,x_v)
|
||||
e10 = np.einsum('lm,ml->m',x_v.T,x_u)
|
||||
e11 = np.einsum('lm,ml->m',x_v.T,x_v)
|
||||
I = np.dstack((e00,e01,e10,e11))[0].reshape((x_u.shape[0],2,2))
|
||||
return I
|
||||
|
||||
|
||||
def compute_surface_normal(x_u, x_v):
|
||||
"""Computes the surface normal n.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- x_u : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_u(p_i).
|
||||
- x_v : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_v(p_i).
|
||||
|
||||
Returns:
|
||||
- n : np.array (n, 3)
|
||||
The surface normals.
|
||||
The i-th row contains the (x,y,z) coordinates of the vector n(p_i).
|
||||
"""
|
||||
exp = np.cross(x_u, x_v)
|
||||
div = np.linalg.norm(exp, axis=1)
|
||||
n = exp/div[:,None]
|
||||
return n
|
||||
|
||||
|
||||
def compute_second_fundamental_form(x_uu, x_uv, x_vv, n):
|
||||
"""Computes the second fundamental form II.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- x_uu : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_uu(p_i).
|
||||
- x_uv : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_uv(p_i).
|
||||
- x_vv : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_vv(p_i).
|
||||
- n : np.array (n, 3)
|
||||
The surface normals.
|
||||
The i-th row contains the (x,y,z) coordinates of the vector n(p_i).
|
||||
|
||||
Returns:
|
||||
- II : np.array (n, 2, 2)
|
||||
The second fundamental forms.
|
||||
The (i, j, k) position contains the (j, k) element of the second
|
||||
fundamental form II(p_i).
|
||||
"""
|
||||
e00 = np.einsum('lm,ml->m',n.T, x_uu)
|
||||
e01 = np.einsum('lm,ml->m',n.T, x_uv)
|
||||
e10 = np.einsum('lm,ml->m',n.T, x_uv)
|
||||
e11 = np.einsum('lm,ml->m',n.T, x_vv)
|
||||
II = np.dstack((e00,e01,e10,e11))[0].reshape((n.shape[0],2,2))
|
||||
return II
|
||||
|
||||
|
||||
def compute_shape_operator(I, II):
|
||||
"""Computes the shape operator S.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- I : np.array (n, 2, 2)
|
||||
The first fundamental forms.
|
||||
The (i, j, k) position contains the (j, k) element of the first
|
||||
fundamental form I(p_i).
|
||||
- II : np.array (n, 2, 2)
|
||||
The second fundamental forms.
|
||||
The (i, j, k) position contains the (j, k) element of the second
|
||||
fundamental form II(p_i).
|
||||
|
||||
Returns:
|
||||
- S : np.array (n, 2, 2)
|
||||
The shape operators.
|
||||
The (i, j, k) position contains the (j, k) element of the shape
|
||||
operator S(p_i).
|
||||
"""
|
||||
Iinv = np.linalg.inv(I)
|
||||
S = Iinv @ II
|
||||
return S
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# PRINCIPAL CURVATURES
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def compute_principal_curvatures(S, x_u, x_v):
|
||||
"""Computes principal curvatures and corresponding principal directions.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- S : np.array (n, 2, 2)
|
||||
The shape operators.
|
||||
The (i, j, k) position contains the (j, k) element of the shape
|
||||
operator S(p_i).
|
||||
- x_u : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_u(p_i).
|
||||
- x_v : np.array (n, 3)
|
||||
The i-th row contains the (x,y,z) coordinates of the vector x_v(p_i).
|
||||
|
||||
Returns:
|
||||
- k_1 : np.array (n)
|
||||
The min principal curvature. i-th element contains the curvature k_1(p_i).
|
||||
- k_2 : np.array (n)
|
||||
The max principal curvature. i-th element contains the curvature k_2(p_i).
|
||||
- e_1 : np.array (n, 3)
|
||||
The unitized principal curvature direction corresponding to k_1.
|
||||
The i-th row contains the (x,y,z) coordinates of e_1(p_i).
|
||||
- e_2 : np.array (n, 3)
|
||||
The unitized principal curvature direction corresponding to k_2.
|
||||
The i-th row contains the (x,y,z) coordinates of e_2(p_i).
|
||||
"""
|
||||
# this section computes the ordered eigenvalues and eigenvectors of S where
|
||||
# k_1[i] = min eigenvalue at p_i, k_2[i] = max eigenvalue at p_i,
|
||||
# bar_e_1[i] = [u, v] components of the eigenvector of k_1,
|
||||
# bar_e_2[i] = [u, v] components of the eigenvector of k_2
|
||||
eig = np.linalg.eig(S)
|
||||
index = np.argsort(eig[0], axis=1)
|
||||
k_1 = eig[0][np.arange(len(S)), index[:, 0]]
|
||||
k_2 = eig[0][np.arange(len(S)), index[:, 1]]
|
||||
bar_e_1 = eig[1][np.arange(len(S)), :, index[:, 0]]
|
||||
bar_e_2 = eig[1][np.arange(len(S)), :, index[:, 1]]
|
||||
|
||||
# Compute the normalized 3D vectors e_1, e_2
|
||||
J = np.concatenate((x_u,x_v), axis=1).reshape((S.shape[0],2,3))
|
||||
Je1 = np.einsum('lnm,ln->lm',J, bar_e_1)
|
||||
Je2 = np.einsum('lnm,ln->lm',J, bar_e_2)
|
||||
e_1 = Je1/np.linalg.norm(Je1, axis=1)[:,None]
|
||||
e_2 = Je2/np.linalg.norm(Je2, axis=1)[:,None]
|
||||
return k_1, k_2, e_1, e_2
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# ASYMPTOTIC DIRECTIONS
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def compute_asymptotic_directions(k_1, k_2, e_1, e_2):
|
||||
"""Computes principal curvatures and corresponding principal directions.
|
||||
Try to vectorize this function.
|
||||
|
||||
Parameters:
|
||||
- k_1 : np.array (n)
|
||||
The min principal curvature. i-th element contains the curvature k_1(p_i).
|
||||
- k_2 : np.array (n)
|
||||
The max principal curvature. i-th element contains the curvature k_2(p_i).
|
||||
- e_1 : np.array (n, 3)
|
||||
The unitized principal curvature direction corresponding to k_1.
|
||||
The i-th row contains the (x,y,z) coordinates of e_1(p_i).
|
||||
- e_2 : np.array (n, 3)
|
||||
The unitized principal curvature direction corresponding to k_2.
|
||||
The i-th row contains the (x,y,z) coordinates of e_2(p_i).
|
||||
|
||||
Returns:
|
||||
- a_1 : np.array (n, 3)
|
||||
The first unitized asymptotic direction. The i-th row contains the
|
||||
(x,y,z) coordinates of a_2(p_i) if it exists, (0, 0, 0) otherwise.
|
||||
- a_2 : np.array (n, 3)
|
||||
The second unitized asymptotic direction. The i-th row contains the
|
||||
(x,y,z) coordinates of a_2(p_i) if it exists, (0, 0, 0) otherwise.
|
||||
"""
|
||||
a_1 = np.zeros((k_1.shape[0],3))
|
||||
a_2 = np.zeros((k_1.shape[0],3))
|
||||
k1k2 = k_1*k_2
|
||||
v1 = np.where(k1k2<=0)
|
||||
v2 = np.where(k1k2<0)
|
||||
|
||||
f = np.zeros((k_1.shape[0]))
|
||||
ff = np.zeros((k_1.shape[0]))
|
||||
v3 = np.where((k_1-k_2)!=0)
|
||||
|
||||
f[v3] = (k_1[v3]/((k_1 - k_2)[v3]))
|
||||
ff[v1] = f[v1]
|
||||
|
||||
cosT = np.sqrt(1-f)
|
||||
sinT = np.sqrt(f)
|
||||
|
||||
a_1[v1] =(e_1*cosT[:,None] + e_2*sinT[:,None])[v1]
|
||||
a_2[v2] =(e_1*cosT[:,None] - e_2*sinT[:,None])[v2]
|
||||
return a_1, a_2
|
||||
|
72
cs457-gc/assignment_3_1/src/utils.py
Normal file
72
cs457-gc/assignment_3_1/src/utils.py
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# UTILITIES
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def uv_grid(u_domain, v_domain, n_u, n_v):
|
||||
"""Computes a triangulation of a u-v patch.
|
||||
|
||||
Parameters:
|
||||
- u_domain : list of floats [u_min, u_max]
|
||||
The u domain.
|
||||
- v_domain : list of floats [v_min, v_max]
|
||||
The v domain.
|
||||
- n_u : int
|
||||
The number of samplings in u direction.
|
||||
- n_v : int
|
||||
The number of samplings in v direction.
|
||||
|
||||
Returns:
|
||||
- P : np.array (n_u * n_v, 2)
|
||||
The sample points. The i-th row contains the (u, v) coordinates of
|
||||
point p_i.
|
||||
- F : np.array (2 * (n_u - 1) * (n_v - 1), 3)
|
||||
Triangular mesh faces of the points P. This can be used for
|
||||
visualization.
|
||||
"""
|
||||
G = np.arange(n_u * n_v).reshape(n_v, n_u)
|
||||
v1 = G[:-1, :-1].flatten()
|
||||
v2 = G[:-1, 1:].flatten()
|
||||
v3 = G[1:, 1:].flatten()
|
||||
v4 = G[1:, :-1].flatten()
|
||||
F1 = np.column_stack((v1, v3, v4))
|
||||
F2 = np.column_stack((v1, v2, v3))
|
||||
F = np.vstack((F1, F2))
|
||||
u, v = np.meshgrid(np.linspace(u_domain[0], u_domain[1], n_u),
|
||||
np.linspace(v_domain[0], v_domain[1], n_v))
|
||||
P = np.column_stack((u.flatten(), v.flatten()))
|
||||
return P, F
|
||||
|
||||
|
||||
def bgr_color(values):
|
||||
"""Computes bgr colors of some values.
|
||||
|
||||
Parameters:
|
||||
- values * np.array (#values, )
|
||||
|
||||
Returns:
|
||||
- rgb : np.array(#values, 3)
|
||||
"""
|
||||
val = np.array(values)
|
||||
expansion = .5
|
||||
X = np.linspace(0, 1, 64)
|
||||
increase = 255 * (X ** expansion)
|
||||
decrease = increase[::-1]
|
||||
one = 255 * np.ones(64)
|
||||
zero = np.zeros(64)
|
||||
lut = np.ones((256, 3)).astype(float)
|
||||
B = np.hstack((one, decrease, zero, zero))
|
||||
G = np.hstack((increase, one, one, decrease))
|
||||
R = np.hstack((zero, zero, increase, one))
|
||||
lut[:, 0] = R / 255
|
||||
lut[:, 1] = G / 255
|
||||
lut[:, 2] = B / 255
|
||||
lut[-1, :] = [255, 0, 255]
|
||||
max_val = np.max(np.abs(values))
|
||||
if max_val == 0:
|
||||
max_val = 1
|
||||
val = np.round(val / max_val * 127).astype('i') + 127
|
||||
return lut[val]
|
281
cs457-gc/assignment_3_1/test/test.py
Normal file
281
cs457-gc/assignment_3_1/test/test.py
Normal file
@@ -0,0 +1,281 @@
|
||||
import time
|
||||
import pytest
|
||||
import json
|
||||
import sys
|
||||
import igl
|
||||
import numpy as np
|
||||
sys.path.append('../')
|
||||
sys.path.append('../src')
|
||||
from smooth_surfaces import *
|
||||
|
||||
eps = 1E-6
|
||||
|
||||
with open('test_data.json', 'r') as infile:
|
||||
homework_datas = json.load(infile)
|
||||
|
||||
# Derivatives of a paraboloid
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[0])
|
||||
def test_paraboloid_points(data):
|
||||
P, a, b, c, d, e, x = data
|
||||
P = np.array(P, dtype=float)
|
||||
x = np.array(x, dtype=float)
|
||||
|
||||
x_student = compute_paraboloid_points(P, a, b, c, d, e)
|
||||
assert np.linalg.norm(x_student - x) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[1])
|
||||
def test_paraboloid_first_derivatives(data):
|
||||
P, a, b, c, d, e, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
|
||||
x_u_student, x_v_student = compute_paraboloid_first_derivatives(P, a, b, c, d, e)
|
||||
|
||||
assert np.linalg.norm(x_u_student - x_u) < eps
|
||||
assert np.linalg.norm(x_v_student - x_v) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[2])
|
||||
def test_paraboloid_second_derivatives(data):
|
||||
P, a, b, c, d, e, x_uu, x_uv, x_vv = data
|
||||
P = np.array(P, dtype=float)
|
||||
x_uu = np.array(x_uu, dtype=float)
|
||||
x_uv = np.array(x_uv, dtype=float)
|
||||
x_vv = np.array(x_vv, dtype=float)
|
||||
|
||||
student_x_uu, student_x_uv, student_x_vv = compute_paraboloid_second_derivatives(P, a, b, c, d, e)
|
||||
|
||||
assert np.linalg.norm(student_x_uu - x_uu) < eps
|
||||
assert np.linalg.norm(student_x_uv - x_uv) < eps
|
||||
assert np.linalg.norm(student_x_vv - x_vv) < eps
|
||||
|
||||
##############################
|
||||
|
||||
# Derivatives of a torus
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[3])
|
||||
def test_torus_points(data):
|
||||
P, R, r, x = data
|
||||
P = np.array(P, dtype=float)
|
||||
x = np.array(x, dtype=float)
|
||||
|
||||
x_student = compute_torus_points(P, R, r)
|
||||
assert np.linalg.norm(x_student - x) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[4])
|
||||
def test_torus_first_derivatives(data):
|
||||
P, R, r, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
|
||||
x_u_student, x_v_student = compute_torus_first_derivatives(P, R, r)
|
||||
|
||||
assert np.linalg.norm(x_u_student - x_u) < eps
|
||||
assert np.linalg.norm(x_v_student - x_v) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[5])
|
||||
def test_torus_second_derivatives(data):
|
||||
P, R, r, x_uu, x_uv, x_vv = data
|
||||
P = np.array(P, dtype=float)
|
||||
x_uu = np.array(x_uu, dtype=float)
|
||||
x_uv = np.array(x_uv, dtype=float)
|
||||
x_vv = np.array(x_vv, dtype=float)
|
||||
|
||||
student_x_uu, student_x_uv, student_x_vv = compute_torus_second_derivatives(P, R, r)
|
||||
|
||||
assert np.linalg.norm(student_x_uu - x_uu) < eps
|
||||
assert np.linalg.norm(student_x_uv - x_uv) < eps
|
||||
assert np.linalg.norm(student_x_vv - x_vv) < eps
|
||||
|
||||
##############################
|
||||
|
||||
# Shape Operator
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[6])
|
||||
def test_paraboloid_first_fundamental_form(data):
|
||||
P, a, b, c, d, e, I, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
I = np.array(I, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
I_student = compute_first_fundamental_form(x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(I_student - I) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[7])
|
||||
def test_torus_first_fundamental_form(data):
|
||||
P, R, r, I, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
I = np.array(I, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
I_student = compute_first_fundamental_form(x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(I_student - I) < eps
|
||||
|
||||
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[8])
|
||||
def test_paraboloid_surface_normal(data):
|
||||
P, a, b, c, d, e, n, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
n = np.array(n, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
n_student = compute_surface_normal(x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(n_student - n) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[9])
|
||||
def test_torus_surface_normal(data):
|
||||
P, R, r, n, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
n = np.array(n, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
n_student = compute_surface_normal( x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(n_student - n) < eps
|
||||
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[10])
|
||||
def test_paraboloid_second_fundamental_form(data):
|
||||
P, a, b, c, d, e, II, x_uu, x_uv, x_vv, n = data
|
||||
P = np.array(P, dtype=float)
|
||||
II = np.array(II, dtype=float)
|
||||
x_uu = np.array(x_uu, dtype=float)
|
||||
x_uv = np.array(x_uv, dtype=float)
|
||||
x_vv = np.array(x_vv, dtype=float)
|
||||
n = np.array(n, dtype=float)
|
||||
|
||||
II_student = compute_second_fundamental_form(x_uu, x_uv, x_vv, n )
|
||||
assert np.linalg.norm(II_student - II) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[11])
|
||||
def test_torus_second_fundamental_form(data):
|
||||
P, R, r, II, x_uu, x_uv, x_vv, n = data
|
||||
P = np.array(P, dtype=float)
|
||||
II = np.array(II, dtype=float)
|
||||
x_uu = np.array(x_uu, dtype=float)
|
||||
x_uv = np.array(x_uv, dtype=float)
|
||||
x_vv = np.array(x_vv, dtype=float)
|
||||
n = np.array(n, dtype=float)
|
||||
|
||||
II_student = compute_second_fundamental_form(x_uu, x_uv, x_vv, n)
|
||||
assert np.linalg.norm(II_student - II) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[12])
|
||||
def test_paraboloid_shape_operator(data):
|
||||
P, a, b, c, d, e, S, I, II = data
|
||||
P = np.array(P, dtype=float)
|
||||
S = np.array(S, dtype=float)
|
||||
I = np.array(I, dtype=float)
|
||||
II = np.array(II, dtype=float)
|
||||
|
||||
S_student = compute_shape_operator(I, II)
|
||||
assert np.linalg.norm(S_student - S) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[13])
|
||||
def test_torus_shape_operator(data):
|
||||
P, R, r, S, I, II = data
|
||||
P = np.array(P, dtype=float)
|
||||
S = np.array(S, dtype=float)
|
||||
I = np.array(I, dtype=float)
|
||||
II = np.array(II, dtype=float)
|
||||
|
||||
S_student = compute_shape_operator(I, II)
|
||||
assert np.linalg.norm(S_student - S) < eps
|
||||
|
||||
##############################
|
||||
|
||||
# Principal Curvatures
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[14])
|
||||
def test_paraboloid_principal_curvatures(data):
|
||||
P, a, b, c, d, e, k1, k2, e1, e2, S, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
k1 = np.array(k1, dtype=float)
|
||||
k2 = np.array(k2, dtype=float)
|
||||
e1 = np.array(e1, dtype=float)
|
||||
e2 = np.array(e2, dtype=float)
|
||||
S = np.array(S, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
k_1_student, k_2_student, e_1_student, e_2_student = compute_principal_curvatures(S, x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(k_1_student - k1) < eps
|
||||
assert np.linalg.norm(k_2_student - k2) < eps
|
||||
assert np.linalg.norm(e_1_student - e1) < eps
|
||||
assert np.linalg.norm(e_2_student - e2) < eps
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[15])
|
||||
def test_torus_principal_curvatures(data):
|
||||
P, R, r, k1, k2, e1, e2, S, x_u, x_v = data
|
||||
P = np.array(P, dtype=float)
|
||||
k1 = np.array(k1, dtype=float)
|
||||
k2 = np.array(k2, dtype=float)
|
||||
e1 = np.array(e1, dtype=float)
|
||||
e2 = np.array(e2, dtype=float)
|
||||
S = np.array(S, dtype=float)
|
||||
x_u = np.array(x_u, dtype=float)
|
||||
x_v = np.array(x_v, dtype=float)
|
||||
k_1_student, k_2_student, e_1_student, e_2_student = compute_principal_curvatures(S, x_u, x_v)
|
||||
|
||||
assert np.linalg.norm(k_1_student - k1) < eps
|
||||
assert np.linalg.norm(k_2_student - k2) < eps
|
||||
assert np.linalg.norm(e_1_student - e1) < eps
|
||||
assert np.linalg.norm(e_2_student - e2) < eps
|
||||
|
||||
##############################
|
||||
|
||||
# Asymptotic Directions
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[16])
|
||||
def test_paraboloid_asymptotic_direction(data):
|
||||
P, a, b, c, d, e, a1, a2, k1, k2, e1, e2 = data
|
||||
P = np.array(P, dtype=float)
|
||||
a1 = np.array(a1, dtype=float)
|
||||
a2 = np.array(a2, dtype=float)
|
||||
k1 = np.array(k1, dtype=float)
|
||||
k2 = np.array(k2, dtype=float)
|
||||
e1 = np.array(e1, dtype=float)
|
||||
e2 = np.array(e2, dtype=float)
|
||||
a_1_student, a_2_student = compute_asymptotic_directions(k1, k2, e1, e2)
|
||||
|
||||
assert (np.linalg.norm(a_1_student - a1) < eps and np.linalg.norm(a_2_student - a2) < eps) or (np.linalg.norm(a_1_student - a2) < eps and np.linalg.norm(a_2_student - a1) < eps)
|
||||
|
||||
@pytest.mark.timeout(0.5)
|
||||
@pytest.mark.parametrize("data", homework_datas[17])
|
||||
def test_torus_asymptotic_direction(data):
|
||||
P, R, r, a1, a2, k1, k2, e1, e2 = data
|
||||
P = np.array(P, dtype=float)
|
||||
a1 = np.array(a1, dtype=float)
|
||||
a2 = np.array(a2, dtype=float)
|
||||
k1 = np.array(k1, dtype=float)
|
||||
k2 = np.array(k2, dtype=float)
|
||||
e1 = np.array(e1, dtype=float)
|
||||
e2 = np.array(e2, dtype=float)
|
||||
|
||||
a_1_student, a_2_student = compute_asymptotic_directions(k1, k2, e1, e2)
|
||||
|
||||
assert (np.linalg.norm(a_1_student - a1) < eps and np.linalg.norm(a_2_student - a2) < eps) or (np.linalg.norm(a_1_student - a2) < eps and np.linalg.norm(a_2_student - a1) < eps)
|
||||
|
||||
|
||||
##############################
|
1
cs457-gc/assignment_3_1/test/test_data.json
Normal file
1
cs457-gc/assignment_3_1/test/test_data.json
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user