modelowanie_geometryczne/parametric_curves_1.ipynb

1316 lines
216 KiB
Plaintext
Raw Permalink Normal View History

2023-10-27 18:41:58 +02:00
{
"cells": [
{
"cell_type": "markdown",
"id": "1b1c1dc2",
"metadata": {},
"source": [
"\\textbf{Copyright:} Wojciech Kowalewski WMiI UAM\n",
"\n",
"\\textbf{Kurs}: Modelowanie geometryczne 2021/22\n",
"\n",
"---\n",
"---\n",
"# Modelowanie geometryczne\n",
"---\n",
"---\n",
"# I. Modelowanie parametryczne"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e2b5e255",
"metadata": {
"deletable": false,
"editable": false
},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import math\n",
"import ipywidgets as widgets"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b306a0ae",
"metadata": {
"deletable": false,
"editable": false
},
"outputs": [],
"source": [
"def dot(a,b):\n",
" \"\"\"\n",
" a,b: wektory\n",
" \"\"\"\n",
" assert len(a)==len(b), \"Nierówne długosci wektrów\"\n",
" res = 0\n",
" for i in range(len(a)):\n",
" res += a[i]*b[i]\n",
" return res"
]
},
{
"cell_type": "markdown",
"id": "5ed3ebee",
"metadata": {},
"source": [
"## 1. Krzywe Hermite'a stopnia 3\n",
"======================================"
]
},
{
"cell_type": "markdown",
"id": "e7502ecf",
"metadata": {},
"source": [
"### 1.1. Macierz funkcji bazowych"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9a0525f7",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[2.0, -3.0, 0.0, 1.0],\n",
" [-2.0, 3.0, 0.0, 0.0],\n",
" [1.0, -2.0, 1.0, 0.0],\n",
" [1.0, -1.0, 0.0, 0.0]]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hermite_basis_matrix_2D = [\n",
" [2.0,-3.0,0.0,1.0],\n",
" [-2.0,3.0,0.0,0.0],\n",
" [1.0,-2.0,1.0,0.0],\n",
" [1.0,-1.0,0.0,0.0]\n",
"]\n",
"hermite_basis_matrix_2D"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "27713848",
"metadata": {},
"outputs": [],
"source": [
"hermite_basis_function_2D = []\n",
"hermite_basis_function_2D.append(\n",
" lambda t: hermite_basis_matrix_2D[0][0]*t**3 + hermite_basis_matrix_2D[0][1]*t**2 + hermite_basis_matrix_2D[0][2]*t + hermite_basis_matrix_2D[0][3],\n",
") \n",
"hermite_basis_function_2D.append(\n",
"lambda t: hermite_basis_matrix_2D[1][0]*t**3 + hermite_basis_matrix_2D[1][1]*t**2 + hermite_basis_matrix_2D[1][2]*t + hermite_basis_matrix_2D[1][3]\n",
")\n",
"hermite_basis_function_2D.append(\n",
" lambda t: hermite_basis_matrix_2D[2][0]*t**3 + hermite_basis_matrix_2D[2][1]*t**2 + hermite_basis_matrix_2D[2][2]*t + hermite_basis_matrix_2D[2][3]\n",
")\n",
"hermite_basis_function_2D.append(\n",
"lambda t: hermite_basis_matrix_2D[3][0]*t**3 + hermite_basis_matrix_2D[3][1]*t**2 + hermite_basis_matrix_2D[3][2]*t + hermite_basis_matrix_2D[3][3]\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "19dd701d",
"metadata": {},
"source": [
"### 1.2. Wykresy funkcji bazowych"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "7b1508e0",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Funkcje bazowe Hermite\")\n",
"\n",
"for n in range(4):\n",
" ax.plot(t,hermite_basis_function_2D[n](t) , label=\"h_\"+str(n)+\"(t)\")\n",
"\n",
"leg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"leg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "c411dee2",
"metadata": {},
"outputs": [],
"source": [
"def find_ext(x,y, lp, lk):\n",
" t = np.arange(lp, lk, 0.001)\n",
" xmin = xmax = x(lp)\n",
" ymin = ymax = y(lp)\n",
" for p in t:\n",
" if x(p) < xmin:\n",
" xmin = x(p)\n",
" else:\n",
" if x(p) > xmax:\n",
" xmax = x(p)\n",
" if y(p) < ymin:\n",
" ymin = y(p)\n",
" else:\n",
" if y(p) > ymax:\n",
" ymax = y(p)\n",
" return [[xmin,xmax],[ymin,ymax]]"
]
},
{
"cell_type": "markdown",
"id": "c446ac17",
"metadata": {},
"source": [
"### 1.3. Przykłady\n",
"\n",
"#### 1.3.1. Przykład 1"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "e1a529b0",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"Pp = [0.0,0.0]\n",
"Pk = [1.0,0.0]\n",
"Tp = [4.0,4.0]\n",
"Tk = [4.0,-4.0]\n",
"\n",
"lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
"lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Segment krzywej Hermite'a\")\n",
"\n",
"\n",
"def X(t):\n",
" return Pp[0]*hermite_basis_function_2D[0](t) + Pk[0]*hermite_basis_function_2D[1](t) + Tp[0]*hermite_basis_function_2D[2](t) + Tk[0]*hermite_basis_function_2D[3](t)\n",
"\n",
"def Y(t):\n",
" return Pp[1]*hermite_basis_function_2D[0](t) + Pk[1]*hermite_basis_function_2D[1](t) + Tp[1]*hermite_basis_function_2D[2](t) + Tk[1]*hermite_basis_function_2D[3](t)\n",
"\n",
"\n",
"extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
"borderXp = min(extr[0][0],Pp[0]+Tp[0],Pk[0]+Tk[0])-0.1\n",
"borderXk = max(extr[0][1],Pp[0]+Tp[0],Pk[0]+Tk[0])+0.1\n",
"\n",
"borderYp = min(extr[1][0],Pp[1]+Tp[1],Pk[1]+Tk[1])-0.1\n",
"borderYk = max(extr[1][1],Pp[1]+Tp[1],Pk[1]+Tk[1])+0.1\n",
"\n",
"\n",
"plt.xlim(borderXp, borderXk)\n",
"plt.ylim(borderYp, borderYk)\n",
"\n",
"x = X(t)\n",
"y = Y(t)\n",
"\n",
"ax.set_aspect('equal')\n",
"\n",
"ax.plot(x,y, color='red')\n",
"\n",
"ax.plot(Pp[0], Pp[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(Pk[0], Pk[1], color='blue', marker=\".\", markersize=20)\n",
"\n",
"plt.quiver(Pp[0],Pp[1], Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"plt.quiver(Pk[0],Pk[1], Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
"#eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"leg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "0b4e7777",
"metadata": {},
"source": [
"#### 1.3.2. Przykład 2"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "a91edba9",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"Pp = [1.0,0.5]\n",
"Pk = [0.0,-0.5]\n",
"Tp = [1.0,1.0]\n",
"Tk = [1.0,-1.0]\n",
"\n",
"lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
"lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Segment krzywej Hermite'a\")\n",
"\n",
"\n",
"def X(t):\n",
" return Pp[0]*hermite_basis_function_2D[0](t) + Pk[0]*hermite_basis_function_2D[1](t) + Tp[0]*hermite_basis_function_2D[2](t) + Tk[0]*hermite_basis_function_2D[3](t)\n",
"\n",
"def Y(t):\n",
" return Pp[1]*hermite_basis_function_2D[0](t) + Pk[1]*hermite_basis_function_2D[1](t) + Tp[1]*hermite_basis_function_2D[2](t) + Tk[1]*hermite_basis_function_2D[3](t)\n",
"\n",
"\n",
"extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
"borderXp = min(extr[0][0],Pp[0]+Tp[0],Pk[0]+Tk[0])-0.1\n",
"borderXk = max(extr[0][1],Pp[0]+Tp[0],Pk[0]+Tk[0])+0.1\n",
"\n",
"borderYp = min(extr[1][0],Pp[1]+Tp[1],Pk[1]+Tk[1])-0.1\n",
"borderYk = max(extr[1][1],Pp[1]+Tp[1],Pk[1]+Tk[1])+0.1\n",
"\n",
"\n",
"plt.xlim(borderXp, borderXk)\n",
"plt.ylim(borderYp, borderYk)\n",
"\n",
"x = X(t)\n",
"y = Y(t)\n",
"\n",
"ax.set_aspect('equal')\n",
"\n",
"ax.plot(x,y, color='red')\n",
"\n",
"ax.plot(Pp[0], Pp[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(Pk[0], Pk[1], color='blue', marker=\".\", markersize=20)\n",
"\n",
"plt.quiver(Pp[0],Pp[1], Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"plt.quiver(Pk[0],Pk[1], Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
"#eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"leg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "b606bf77",
"metadata": {},
"source": [
"#### 1.3.3. Wersja interaktywna"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "cfd6c277",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e68a1b80fa3442fd9cbf442ee296dc72",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(VBox(children=(FloatSlider(value=0.0, description='PpX', layout=Layout(grid_area='widget001'), …"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "15142bb167054b61803cf27ad42801ca",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"\n",
"def draw_Hermite_segment(PpX,PpY,PkX,PkY,TpX,TpY,TkX,TkY):\n",
" t = np.arange(0.0, 1.01, 0.01)\n",
" \n",
" lenTp = math.sqrt(TpX**2+TpY**2)/2.54\n",
" lenTk = math.sqrt(TkX**2+TkY**2)/2.54 \n",
"\n",
" fig, ax = plt.subplots()\n",
" #ustawienie rozmiaru obrazka na 10x10 cali\n",
" fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
" plt.title(\"Segment krzywej Hermite'a\")\n",
"\n",
"\n",
" def X(t):\n",
" return PpX*hermite_basis_function_2D[0](t) + PkX*hermite_basis_function_2D[1](t) + TpX*hermite_basis_function_2D[2](t) + TkX*hermite_basis_function_2D[3](t)\n",
"\n",
" def Y(t):\n",
" return PpY*hermite_basis_function_2D[0](t) + PkY*hermite_basis_function_2D[1](t) + TpY*hermite_basis_function_2D[2](t) + TkY*hermite_basis_function_2D[3](t)\n",
"\n",
"\n",
" extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
" borderXp = min(extr[0][0],PpX+TpX,PkX+TkX)-0.1\n",
" borderXk = max(extr[0][1],PpX+TpX,PkX+TkX)+0.1\n",
"\n",
" borderYp = min(extr[1][0],PpY+TpY,PkY+TkY)-0.1\n",
" borderYk = max(extr[1][1],PpY+TpY,PkY+TkY)+0.1\n",
"\n",
"\n",
" plt.xlim(borderXp, borderXk)\n",
" plt.ylim(borderYp, borderYk)\n",
"\n",
" x = X(t)\n",
" y = Y(t)\n",
"\n",
" ax.set_aspect('equal')\n",
"\n",
" ax.plot(x,y, color='red')\n",
"\n",
" ax.plot(PpX, PpY, color='blue', marker=\".\", markersize=20)\n",
" ax.plot(PkX, PkY, color='blue', marker=\".\", markersize=20)\n",
"\n",
" plt.quiver(PpX,PpY, TpX , TpY,color='green', angles='xy', scale_units='xy', scale=1)\n",
" plt.quiver(PkX,PkY, TkX , TkY,color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
" #eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
" #leg.get_frame().set_alpha(0.5)\n",
" plt.grid();\n",
"\n",
" plt.show()\n",
"\n",
"Pp1 = [0.0,0.0]\n",
"Pk1 = [1.0,0.0]\n",
"Tp1 = [1.0,1.0]\n",
"Tk1 = [1.0,-1.0]\n",
" \n",
"#draw_Hermite_segment(Pp1[0],Pp1[1],Pk1[0],Pk1[1],Tp1[0],Tp1[1],Tk1[0],Tk1[1])\n",
"grid = widgets.GridspecLayout(4, 2)\n",
"grid[0, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Pp1[0],description='PpX')\n",
"grid[0, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Pp1[1],description='PpY')\n",
"grid[1, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Pk1[0],description='PkX')\n",
"grid[1, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Pk1[1],description='PkY')\n",
"grid[2, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Tp1[0],description='TpX')\n",
"grid[2, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Tp1[1],description='TpY')\n",
"grid[3, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Tk1[0],description='TkX')\n",
"grid[3, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=Tk1[1],description='TkY')\n",
"\n",
"k1 = widgets.VBox([grid[0,0],grid[1,0],grid[2,0],grid[3,0]])\n",
"k2 = widgets.VBox([grid[0,1],grid[1,1],grid[2,1],grid[3,1]])\n",
"ui = widgets.HBox([k1,k2])\n",
"\n",
"out = widgets.interactive_output(draw_Hermite_segment, {'PpX': grid[0,0], 'PpY': grid[0,1], \n",
" 'PkX': grid[1,0], 'PkY': grid[1,1],\n",
" 'TpX': grid[2,0], 'TpY': grid[2,1], \n",
" 'TkX': grid[3,0], 'TkY': grid[3,1]\n",
" })\n",
"\n",
"display(ui, out)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "5968b7a3",
"metadata": {},
"source": [
"## 2. Krzywe Beziera stopnia 3\n",
"===================================="
]
},
{
"cell_type": "markdown",
"id": "d982705f",
"metadata": {},
"source": [
"### 2.1. Macierz funkcji bazowych"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "90b8487d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[[-1.0, 3.0, -3.0, 1.0],\n",
" [3.0, -6.0, 3.0, 0.0],\n",
" [-3.0, 3.0, 0.0, 0.0],\n",
" [1.0, 0.0, 0.0, 0.0]]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"bezier_basis_matrix_2D = [\n",
" [-1.0,3.0,-3.0,1.0],\n",
" [3.0,-6.0,3.0,0.0],\n",
" [-3.0,3.0,.0,0.0],\n",
" [1.0,0.0,0.0,0.0]\n",
"]\n",
"bezier_basis_matrix_2D"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "f0f7435c",
"metadata": {},
"outputs": [],
"source": [
"bezier_basis_function_2D = []\n",
"bezier_basis_function_2D.append(\n",
" lambda t: bezier_basis_matrix_2D[0][0]*t**3 + bezier_basis_matrix_2D[0][1]*t**2 + bezier_basis_matrix_2D[0][2]*t + bezier_basis_matrix_2D[0][3],\n",
") \n",
"bezier_basis_function_2D.append(\n",
"lambda t: bezier_basis_matrix_2D[1][0]*t**3 + bezier_basis_matrix_2D[1][1]*t**2 + bezier_basis_matrix_2D[1][2]*t + bezier_basis_matrix_2D[1][3]\n",
")\n",
"bezier_basis_function_2D.append(\n",
" lambda t: bezier_basis_matrix_2D[2][0]*t**3 + bezier_basis_matrix_2D[2][1]*t**2 + bezier_basis_matrix_2D[2][2]*t + bezier_basis_matrix_2D[2][3]\n",
")\n",
"bezier_basis_function_2D.append(\n",
"lambda t: bezier_basis_matrix_2D[3][0]*t**3 + bezier_basis_matrix_2D[3][1]*t**2 + bezier_basis_matrix_2D[3][2]*t + bezier_basis_matrix_2D[3][3]\n",
")\n"
]
},
{
"cell_type": "markdown",
"id": "7cb6a787",
"metadata": {},
"source": [
"### 2.2. Wykresy funkcji bazowych"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "041f6aee",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Funkcje bazowe Beziera stopnia 3\")\n",
"\n",
"for n in range(4):\n",
" ax.plot(t,bezier_basis_function_2D[n](t) , label=\"b_\"+str(n)+\"(t)\")\n",
"\n",
"leg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"leg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "8a0079a0",
"metadata": {},
"outputs": [],
"source": [
"def find_ext(x,y, lp, lk):\n",
" t = np.arange(lp, lk, 0.001)\n",
" xmin = xmax = x(lp)\n",
" ymin = ymax = y(lp)\n",
" for p in t:\n",
" if x(p) < xmin:\n",
" xmin = x(p)\n",
" else:\n",
" if x(p) > xmax:\n",
" xmax = x(p)\n",
" if y(p) < ymin:\n",
" ymin = y(p)\n",
" else:\n",
" if y(p) > ymax:\n",
" ymax = y(p)\n",
" return [[xmin,xmax],[ymin,ymax]]"
]
},
{
"cell_type": "markdown",
"id": "0356ad14",
"metadata": {},
"source": [
"### 2.3. Przykłady\n",
"\n",
"#### 2.3.1. Przykład 1"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "49b5119f",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"### %matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"P0 = [0.0,0.0]\n",
"P1 = [0.25,1.0]\n",
"P2 = [0.75,1.0]\n",
"P3 = [1.0,0.0]\n",
"\n",
"Tp= [3.0*(P1[0]-P0[0]),3.0*(P1[1]-P0[1])]\n",
"Tk= [3.0*(P3[0]-P2[0]),3.0*(P3[1]-P2[1])]\n",
"\n",
"lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
"lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Segment krzywej Beziera\")\n",
"\n",
"\n",
"def X(t):\n",
" return P0[0]*bezier_basis_function_2D[0](t) + P1[0]*bezier_basis_function_2D[1](t) + P2[0]*bezier_basis_function_2D[2](t) + P3[0]*bezier_basis_function_2D[3](t)\n",
"\n",
"def Y(t):\n",
" return P0[1]*bezier_basis_function_2D[0](t) + P1[1]*bezier_basis_function_2D[1](t) + P2[1]*bezier_basis_function_2D[2](t) + P3[1]*bezier_basis_function_2D[3](t)\n",
"\n",
"\n",
"extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
"borderXp = min(extr[0][0],P0[0]+Tp[0],P3[0]+Tk[0],P0[0],P1[0],P2[0],P3[0])-0.1\n",
"borderXk = max(extr[0][1],P0[0]+Tp[0],P3[0]+Tk[0],P0[0],P1[0],P2[0],P3[0])+0.1\n",
"\n",
"borderYp = min(extr[1][0],P0[1]+Tp[1],P3[1]+Tk[1],P0[1],P1[1],P2[1],P3[1])-0.1\n",
"borderYk = max(extr[1][1],P0[1]+Tp[1],P3[1]+Tk[1],P0[1],P1[1],P2[1],P3[1])+0.1\n",
"\n",
"\n",
"plt.xlim(borderXp, borderXk)\n",
"plt.ylim(borderYp, borderYk)\n",
"\n",
"x = X(t)\n",
"y = Y(t)\n",
"\n",
"ax.set_aspect('equal')\n",
"\n",
"ax.plot(x,y, color='red')\n",
"\n",
"ax.plot(P0[0], P0[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P1[0], P1[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P2[0], P2[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P3[0], P3[1], color='blue', marker=\".\", markersize=20)\n",
"\n",
"\n",
"\n",
"plt.quiver(P0[0],P0[1], Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"plt.quiver(P3[0],P3[1], Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
"#eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"#eg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "d4c94e72",
"metadata": {},
"source": [
"#### 2.3.2. Przykład 2"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "1a029ca7",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x720 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"### %matplotlib inline\n",
"\n",
"t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
"P0 = [0.0,0.0]\n",
"P1 = [0.25,1.0]\n",
"P2 = [1.0,0.0]\n",
"P3 = [0.75,1.0]\n",
"\n",
"Tp= [3.0*(P1[0]-P0[0]),3.0*(P1[1]-P0[1])]\n",
"Tk= [3.0*(P3[0]-P2[0]),3.0*(P3[1]-P2[1])]\n",
"\n",
"lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
"lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
"\n",
"fig, ax = plt.subplots()\n",
"#ustawienie rozmiaru obrazka na 10x10 cali\n",
"fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
"plt.title(\"Segment krzywej Beziera\")\n",
"\n",
"\n",
"def X(t):\n",
" return P0[0]*bezier_basis_function_2D[0](t) + P1[0]*bezier_basis_function_2D[1](t) + P2[0]*bezier_basis_function_2D[2](t) + P3[0]*bezier_basis_function_2D[3](t)\n",
"\n",
"def Y(t):\n",
" return P0[1]*bezier_basis_function_2D[0](t) + P1[1]*bezier_basis_function_2D[1](t) + P2[1]*bezier_basis_function_2D[2](t) + P3[1]*bezier_basis_function_2D[3](t)\n",
"\n",
"\n",
"extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
"borderXp = min(extr[0][0],P0[0]+Tp[0],P3[0]+Tk[0],P0[0],P1[0],P2[0],P3[0])-0.1\n",
"borderXk = max(extr[0][1],P0[0]+Tp[0],P3[0]+Tk[0],P0[0],P1[0],P2[0],P3[0])+0.1\n",
"\n",
"borderYp = min(extr[1][0],P0[1]+Tp[1],P3[1]+Tk[1],P0[1],P1[1],P2[1],P3[1])-0.1\n",
"borderYk = max(extr[1][1],P0[1]+Tp[1],P3[1]+Tk[1],P0[1],P1[1],P2[1],P3[1])+0.1\n",
"\n",
"plt.xlim(borderXp, borderXk)\n",
"plt.ylim(borderYp, borderYk)\n",
"\n",
"x = X(t)\n",
"y = Y(t)\n",
"\n",
"ax.set_aspect('equal')\n",
"\n",
"ax.plot(x,y, color='red')\n",
"\n",
"ax.plot(P0[0], P0[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P1[0], P1[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P2[0], P2[1], color='blue', marker=\".\", markersize=20)\n",
"ax.plot(P3[0], P3[1], color='blue', marker=\".\", markersize=20)\n",
"\n",
"\n",
"\n",
"plt.quiver(P0[0],P0[1], Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"plt.quiver(P3[0],P3[1], Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
"#eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
"#leg.get_frame().set_alpha(0.5)\n",
"plt.grid();\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "1ecf0af3",
"metadata": {},
"source": [
"#### 2.3.3. Wersja interaktywna"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "d4210ae6",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "b6b227c29e834926ad774bdd3dafc8d2",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"HBox(children=(VBox(children=(FloatSlider(value=0.0, description='P0X', layout=Layout(grid_area='widget001'), …"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "fd689802c0ef40998471c416457c43c1",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"\n",
"def draw_Bezier_segment(P0X,P0Y,P1X,P1Y,P2X,P2Y,P3X,P3Y):\n",
" t = np.arange(0.0, 1.01, 0.01)\n",
" \n",
" ### %matplotlib inline\n",
"\n",
" t = np.arange(0.0, 1.01, 0.01)\n",
"\n",
" Tp= [3.0*(P1X-P0X),3.0*(P1Y-P0Y)]\n",
" Tk= [3.0*(P3X-P2X),3.0*(P3Y-P2Y)]\n",
"\n",
" lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
" lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
"\n",
" fig, ax = plt.subplots()\n",
" #ustawienie rozmiaru obrazka na 10x10 cali\n",
" fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
" plt.title(\"Segment krzywej Beziera\")\n",
"\n",
"\n",
" def X(t):\n",
" return P0X*bezier_basis_function_2D[0](t) + P1X*bezier_basis_function_2D[1](t) + P2X*bezier_basis_function_2D[2](t) + P3X*bezier_basis_function_2D[3](t)\n",
"\n",
" def Y(t):\n",
" return P0Y*bezier_basis_function_2D[0](t) + P1Y*bezier_basis_function_2D[1](t) + P2Y*bezier_basis_function_2D[2](t) + P3Y*bezier_basis_function_2D[3](t)\n",
"\n",
"\n",
" extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
" borderXp = min(extr[0][0],P0X+Tp[0],P3X+Tk[0],P0X,P1X,P2X,P3X)-0.2\n",
" borderXk = max(extr[0][1],P0X+Tp[0],P3X+Tk[0],P0X,P1X,P2X,P3X)+0.2\n",
"\n",
" borderYp = min(extr[1][0],P0Y+Tp[1],P3Y+Tk[1],P0Y,P1Y,P2Y,P3Y)-0.2\n",
" borderYk = max(extr[1][1],P0Y+Tp[1],P3Y+Tk[1],P0Y,P1Y,P2Y,P3Y)+0.2\n",
"\n",
" plt.xlim(borderXp, borderXk)\n",
" plt.ylim(borderYp, borderYk)\n",
"\n",
" x = X(t)\n",
" y = Y(t)\n",
"\n",
" ax.set_aspect('equal')\n",
"\n",
" ax.plot(x,y, color='red')\n",
"\n",
" ax.plot(P0X, P0Y, color='blue', marker=\".\", markersize=20)\n",
" ax.plot(P1X, P1Y, color='blue', marker=\".\", markersize=20)\n",
" ax.plot(P2X, P2Y, color='blue', marker=\".\", markersize=20)\n",
" ax.plot(P3X, P3Y, color='blue', marker=\".\", markersize=20)\n",
"\n",
"\n",
"\n",
" plt.quiver(P0X,P0Y, Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
" plt.quiver(P3X,P3Y, Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
" #eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
" #leg.get_frame().set_alpha(0.5)\n",
" plt.grid();\n",
"\n",
" plt.show()\n",
"\n",
"p0 = [0.0,0.0]\n",
"p1 = [0.25,1.0]\n",
"p2 = [0.75,1.0]\n",
"p3 = [1.0,0.0]\n",
" \n",
"#draw_Hermite_segment(Pp1[0],Pp1[1],Pk1[0],Pk1[1],Tp1[0],Tp1[1],Tk1[0],Tk1[1])\n",
"grid = widgets.GridspecLayout(4, 2)\n",
"grid[0, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p0[0],description='P0X')\n",
"grid[0, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p0[1],description='P0Y')\n",
"grid[1, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p1[0],description='P1X')\n",
"grid[1, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p1[1],description='P1Y')\n",
"grid[2, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p2[0],description='P2X')\n",
"grid[2, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p2[1],description='P2Y')\n",
"grid[3, 0] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p3[0],description='P3X')\n",
"grid[3, 1] = widgets.FloatSlider(min=-5, max=5, step=0.2,value=p3[1],description='P3Y')\n",
"\n",
"k1 = widgets.VBox([grid[0,0],grid[1,0],grid[2,0],grid[3,0]])\n",
"k2 = widgets.VBox([grid[0,1],grid[1,1],grid[2,1],grid[3,1]])\n",
"ui = widgets.HBox([k1,k2])\n",
"\n",
"out = widgets.interactive_output(draw_Bezier_segment, {'P0X': grid[0,0], 'P0Y': grid[0,1], \n",
" 'P1X': grid[1,0], 'P1Y': grid[1,1],\n",
" 'P2X': grid[2,0], 'P2Y': grid[2,1], \n",
" 'P3X': grid[3,0], 'P3Y': grid[3,1]\n",
" })\n",
"\n",
"display(ui, out)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "31c960d2",
"metadata": {},
"source": [
"### 2.4. Krzywe Beziera dowolnego stopnia"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "c0e13970",
"metadata": {},
"outputs": [],
"source": [
"import scipy.special\n",
"def bernstein(n,i,t):\n",
" return scipy.special.binom(n,i)*t**i*(1-t)**(n-i)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "ea3578d6",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "8ff7f68765a64213b8aed50f2aa183f9",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"GridspecLayout(children=(FloatText(value=0.0, description='pX', layout=Layout(grid_area='widget001', width='20…"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "5c51597250a147da82698a932816b9dc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"Output()"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "118d311db79b4725be01e9bdb5b36ab5",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Checkbox(value=False, description='Show convex hull', indent=False), Output()), _dom_cla…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"from IPython.display import clear_output\n",
"from scipy.spatial import ConvexHull, convex_hull_plot_2d\n",
"from ipywidgets import Button, Layout\n",
"from ipywidgets import interact\n",
"\n",
"out = widgets.Output()\n",
"\n",
"def onclick(event):\n",
" print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %\n",
" ('double' if event.dblclick else 'single', event.button,\n",
" event.x, event.y, event.xdata, event.ydata))\n",
"\n",
"\n",
"def draw_Bezier_segment_n(control_points,out, hull = False):\n",
" t = np.arange(0.0, 1.01, 0.01)\n",
" \n",
" ### %matplotlib inline\n",
"\n",
" t = np.arange(0.0, 1.01, 0.01)\n",
" \n",
" n = len(control_points)-1\n",
"\n",
" Tp= [3.0*(control_points[1][0]-control_points[0][0]),3.0*(control_points[1][1]-control_points[0][1])]\n",
" Tk= [3.0*(control_points[n][0]-control_points[n-1][0]),3.0*(control_points[n][1]-control_points[n-1][1])]\n",
"\n",
" lenTp = math.sqrt(Tp[0]**2+Tp[1]**2)/2.54\n",
" lenTk = math.sqrt(Tk[0]**2+Tk[1]**2)/2.54 \n",
"\n",
" \n",
" with out:\n",
" fig, ax = plt.subplots()\n",
" \n",
" cid = fig.canvas.mpl_connect('button_press_event', onclick)\n",
"\n",
" #ustawienie rozmiaru obrazka na 10x10 cali\n",
" fig.set_size_inches(25.4/2.54, 25.4/2.54, forward=True)\n",
" plt.title(\"Segment krzywej Beziera stopnia \"+str(n))\n",
"\n",
"\n",
" def X(t):\n",
" res = 0\n",
" for i in range(n+1):\n",
" res += control_points[i][0]*bernstein(n,i,t)\n",
" return res\n",
" \n",
" \n",
" def Y(t):\n",
" res = 0\n",
" for i in range(n+1):\n",
" res += control_points[i][1]*bernstein(n,i,t)\n",
" return res\n",
" \n",
"\n",
" extr = find_ext(X,Y,0.0,1.01)\n",
"\n",
" \n",
" extr_points = [[control_points[0][0],control_points[0][0]],[control_points[0][1],control_points[0][1]]]\n",
" for i in range(1,n+1):\n",
" if control_points[i][0] < extr_points[0][0]:\n",
" extr_points[0][0] = control_points[i][0]\n",
" else:\n",
" if control_points[i][0] > extr_points[0][1]:\n",
" extr_points[0][1] = control_points[i][0]\n",
" if control_points[i][1] < extr_points[1][0]:\n",
" extr_points[1][0] = control_points[i][1]\n",
" else:\n",
" if control_points[i][1] > extr_points[1][1]:\n",
" extr_points[1][1] = control_points[i][1]\n",
"\n",
" borderXp = min(extr[0][0],control_points[0][0]+Tp[0],control_points[n][0]+Tk[0],extr_points[0][0])-0.2\n",
" borderXk = max(extr[0][1],control_points[0][0]+Tp[0],control_points[n][0]+Tk[0],extr_points[0][1])+0.2\n",
" \n",
" borderYp = min(extr[1][0],control_points[0][1]+Tp[1],control_points[n][1]+Tk[1],extr_points[1][0])-0.2\n",
" borderYk = max(extr[1][1],control_points[0][1]+Tp[1],control_points[n][1]+Tk[1],extr_points[1][1])+0.2\n",
" \n",
" \n",
"\n",
" plt.xlim(borderXp, borderXk)\n",
" plt.ylim(borderYp, borderYk)\n",
"\n",
" x = X(t)\n",
" y = Y(t)\n",
"\n",
" ax.set_aspect('equal')\n",
"\n",
" with out:\n",
" clear_output(True)\n",
" \n",
" ax.plot(x,y, color='red')\n",
"\n",
" for i in range(n+1):\n",
" ax.plot(control_points[i][0], control_points[i][1], color='blue', marker=\".\", markersize=20)\n",
"\n",
"\n",
"\n",
" plt.quiver(control_points[0][0], control_points[0][1], Tp[0] , Tp[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
" plt.quiver(control_points[n][0], control_points[n][1], Tk[0] , Tk[1],color='green', angles='xy', scale_units='xy', scale=1)\n",
"\n",
"\n",
" #eg = ax.legend(loc='upper center', ncol=2, shadow='True')\n",
" #leg.get_frame().set_alpha(0.5)\n",
" plt.grid();\n",
"\n",
" if hull and len(points)>2:\n",
" Hull = ConvexHull(points)\n",
" #print(Hull.vertices.tolist())\n",
" a=[]\n",
" b=[]\n",
" for i in Hull.vertices.tolist():\n",
" #ax.plot(points[i][0], points[i][1], color='orange', marker=\"*\", markersize=8)\n",
" a.append(points[i][0])\n",
" b.append(points[i][1])\n",
" a.append(a[0])\n",
" b.append(b[0])\n",
" #print(a)\n",
" #print(b)\n",
" for i in Hull.vertices.tolist():\n",
" #print(points[Hull.vertices.tolist()[i]])\n",
" #ax.plot(points[i][0], points[i][1], 'r--', color='black')\n",
" ax.plot(a, b, 'r--', color='black')\n",
" for i in Hull.vertices.tolist():\n",
" ax.plot(points[i][0], points[i][1], color='orange', marker=\"*\", markersize=8)\n",
" \n",
" #_ = convex_hull_plot_2d(Hull)\n",
" \n",
" plt.show()\n",
"\n",
"\n",
"points = [[0.0,0.0], [1.0,0.0],[2.0,2.0]]\n",
"\n",
"\n",
"pointX = widgets.FloatText(\n",
" value=0.0,\n",
" description='pX',\n",
" disabled=False,\n",
" layout=Layout(width='200px')\n",
")\n",
"\n",
"pointY = widgets.FloatText(\n",
" value=0.0,\n",
" description='pY',\n",
" disabled=False,\n",
" layout=Layout(width='200px')\n",
")\n",
"\n",
"\n",
"addIdx = widgets.IntText(\n",
" value=0,\n",
" description='Add Idx',\n",
" disabled=False,\n",
" layout=Layout(width='200px')\n",
")\n",
"\n",
"delIdx = widgets.IntText(\n",
" value=0,\n",
" description='Del Idx',\n",
" disabled=False,\n",
" layout=Layout(width='200px')\n",
")\n",
"\n",
"show_hull = widgets.Checkbox(\n",
" value=False,\n",
" description='Show convex hull',\n",
" disabled=False,\n",
" indent=False\n",
")\n",
"\n",
"def hull_fun(val):\n",
" draw_Bezier_segment_n(points,out,val)\n",
"\n",
"def update_plot(b):\n",
" if b.description == 'Add Point':\n",
" points.insert(addIdx.value,[pointX.value,pointY.value])\n",
" if b.description == 'Del Point':\n",
" del points[delIdx.value]\n",
" draw_Bezier_segment_n(points,out,show_hull.value)\n",
" \n",
"add_button = widgets.Button(description='Add Point',layout=Layout(width='200px'),merge=False)\n",
"del_button = widgets.Button(description='Del Point',layout=Layout(width='200px'))\n",
"add_button.on_click(update_plot)\n",
"del_button.on_click(update_plot)\n",
"\n",
"grid = widgets.GridspecLayout(4, 2,width='460px')\n",
"grid[0, 0] = pointX\n",
"grid[1, 0] = pointY\n",
"grid[2, 0] = addIdx\n",
"grid[3, 0] = add_button\n",
"grid[0, 1] = delIdx\n",
"grid[1, 1] = del_button\n",
"\n",
"\n",
"\n",
"display(grid,out)\n",
"interact(hull_fun,val=show_hull)\n",
"draw_Bezier_segment_n(points,out,show_hull.value)\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "dac98b97",
"metadata": {},
"source": [
"## Zadania "
]
},
{
"cell_type": "markdown",
"id": "a2ba0722",
"metadata": {},
"source": [
"\n",
" \\begin{enumerate}\n",
" \\item Do skryptu w punkcie 2.4. dodać możliwość modyfikacji dowolnego punktu kontrolnego (nieobowiązkowe)\n",
" \\item Napisać skrypt demonstrujący łączenie krzywych Beziera 3-go stopnia, z ciągłością parametryczną w punkcie łączenia.\n",
" \\item Napisać skrypt implementujący rysowanie krzywych Beziera 3-go stopnia algorytmem de Casteljau.\n",
" \\end{enumerate}\n",
" Alternatywnie napisać własny program realizujący te zadania.<p></p>\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9a635bc7",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"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.5"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
}
},
"nbformat": 4,
"nbformat_minor": 5
}