Last active
February 22, 2021 10:37
-
-
Save jeanpat/5065759d0cac56fe7dbda4dcc5dc3c30 to your computer and use it in GitHub Desktop.
This python notebook is introduction to algorithmic. It mixes, video, activities with geogebra and algorithms with a turtle to simulate a waterjet cutter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# ALGORITHME DE DECOUPAGE D'UN POLYGONE REGULIER" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "## Le module mobilechelonian est disponible, pas nécessaire de l'installer.\n", | |
| "#%pip install mobilechelonian\n", | |
| "# sur mybinder.org, il faut importer sympy\n", | |
| "%pip install sympy" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# ATTENTION: LANCER CE NOTEBOOK DANS LE MODE *CLASSIC*\n", | |
| "Si vous utilisez ce notebook depuis la plateforme lycée connecté, votre environnement est jupyterlab. Il faut basculer en mode classic:\n", | |
| "```\n", | |
| " menu > Help\n", | |
| " Launch Classic notebook\n", | |
| "```\n", | |
| "Double cliquer ensuite sur **Découpe.ipynb**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Programmation d'une découpeuse\n", | |
| "Les découpeuses (jet d'eau ou laser) sont capables de découper des matériaux (plans) aussi variés que de l'acier ou bien du papier.\n", | |
| "Commençons par regarder les deux premières vidéos montrant une découpeuse à jet d'eau réalisant des découpes circulaires dans une plaque d'acier, puis une découpeuse laser réalisant des découpes de formes complexes dans du papier.\n", | |
| "\n", | |
| "*Pour jouer les vidéos, exécuter chacune des cellules ci dessous* en cliquant la cellule pour la sélectionner puis en cliquant la **flêche droite** de la barre d'outil ou au clavier avec les touches **SHIFT+Entrée**" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from IPython.display import HTML" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "iframe_dec = '<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/Vzxgo1J1J-8\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>'\n", | |
| "iframe_saber = '<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/FBkQX0Ri0Co\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>'\n", | |
| "HTML(iframe_dec)\n", | |
| "#HTML(iframe_saber)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "iframe_laser= '<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/acqQlOx6Jgw\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>'\n", | |
| "HTML(iframe_laser)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "raw", | |
| "metadata": {}, | |
| "source": [ | |
| "## Comparaison usinage vs découpe laser (désactivé)\n", | |
| "#iframe_cnc_vs_laser = '<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/rMv9GUEutW0\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>'\n", | |
| "#HTML(iframe_cnc_vs_laser)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Problématique:\n", | |
| "**Comment découper des trous avec une découpeuse à jet d'eau ou bien avec une découpeuse laser?**\n", | |
| "\n", | |
| "\n", | |
| "Comme pour les vidéos, exécuter chacune des cellules ci dessous avec la **flêche droite** (*Run the selected cells...* quand le curseur survole son icône) de la barre d'outil ou au clavier avec les touches **SHIFT+Entrée** (maintenir la touche *SHIFT* puis taper la touche *Entrée*)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Analyse géométrique du problème:\n", | |
| "### Polygone régulier à côté de longueur constante\n", | |
| "\n", | |
| "Dans un premier temps, le côté de la découpe polygonale a une longueur fixe (par exemple côté=1). Faire varier, le nombre de côtés de la découpe en augmentant la valeur de $n$.\n", | |
| "\n", | |
| " * Que faut-il faire pour que la découpe soit de forme quasi circulaire?\n", | |
| " * La surface de la découpe augmente-t-elle ou diminue-t-elle?\n", | |
| " * Que faut-il faire alors pour conserver une surface de découpe presque constante? " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "iframe1 = '<iframe scrolling=\"no\" title=\"Polygone régulier à côté de longueur fixée\" src=\"https://www.geogebra.org/material/iframe/id/rtcnfxrw/width/800/height/502/border/888888/sfsb/true/smb/false/stb/false/stbh/false/ai/false/asb/false/sri/true/rc/false/ld/false/sdz/true/ctl/false\" width=\"882px\" height=\"502px\" style=\"border:0px;\"> </iframe>'\n", | |
| "HTML(iframe1)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### Découpe polygonale inscrite dans un cercle de rayon fixe.\n", | |
| "\n", | |
| "La découpe est représentée par un polygone régulier inscrit dans un cercle de rayon choisi (exemple $r=1$). On peut augmenter le nombre $n$ de côtés du polygone.\n", | |
| "\n", | |
| " * Comment varie la longueur $AB$, d'un côté, lorsque le nombre de côté augmente ?\n", | |
| " \n", | |
| "Pour $n=12$ la forme découpe est déjà assez proche d'un cercle. En concervant le rayon du cercle inscrit égal à $r=1~unité$:\n", | |
| "\n", | |
| " * Quelle est la distance parcourue par la tête de la découpeuse pour aller de $A$ à $B$ , dans la direction $\\overrightarrow{AB}$?\n", | |
| "\n", | |
| "Arrivée au point $B$, la tête de la découpeuse dois changer de direction vers $\\overrightarrow{BC}$\n", | |
| "\n", | |
| " * Quel est l'angle entre les directions $\\overrightarrow{AB}$ (identique à $\\overrightarrow{BA'}$) et $\\overrightarrow{BC}$ ?\n", | |
| " * Comment ce changement de direction de la tête de découpe est-il noté dans la figure ci-dessous?\n", | |
| " * Quelle est la mesure de cet angle en degré?" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "iframe= '<iframe scrolling=\"no\" title=\"Longueur du côté d\\'un polygone régulier\" src=\"https://www.geogebra.org/material/iframe/id/xnaumwwv/width/800/height/526/border/888888/sfsb/true/smb/false/stb/false/stbh/false/ai/false/asb/false/sri/true/rc/false/ld/false/sdz/true/ctl/false\", width=\"994px\" height=\"526px\" style=\"border:0px;\"> </iframe>)'\n", | |
| "HTML(iframe)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "Dans la figure ci-dessous, choisir la valeur de $n$ pour tracer un **décagone régulier** inscrit dans un cercle de rayon $r=1$.\n", | |
| "\n", | |
| "Dans la figure ci-dessous on a représenté la longueur $AB$ d'un côté du polygone en fonction du nombre $x$ de cotés de la figure.\n", | |
| "\n", | |
| " * Quelle est la longueur du côté d'un hexagone?\n", | |
| " * Quelle est la longueur du côté d'un décagone?\n", | |
| " * En zoomant et en décalant la figure vers la droite avec la souris, quelle est la longueur du coté d'un polygone à 40 cotés?\n", | |
| " \n", | |
| "Les deux courbes représentent les courbes des fonctions associant le nombre de côtés $x$ d'un polygone et la longueur $f(x)=AB$ d'un coté.\n", | |
| " $$f: x \\mapsto f(x) $$\n", | |
| " $$x:nombre~de~côtés$$\n", | |
| " $$f(x):AB ~longueur ~d'un ~côté $$\n", | |
| "\n", | |
| " * Pourquoi trace-t-on la courbe de $g$ pour $x\\geq 3$?\n", | |
| " * Que représente $g(5)$?\n", | |
| " * Cela a-t-il un sens de calculer $f(12.5)$ ou $g(12.5)$ ?" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "iframe_courbe = '<iframe scrolling=\"no\" title=\"Polygone: nombre de côtés et longueur d\\'un côté\" src=\"https://www.geogebra.org/material/iframe/id/u7a8qn7d/width/800/height/480/border/888888/sfsb/true/smb/false/stb/false/stbh/false/ai/false/asb/false/sri/true/rc/false/ld/false/sdz/true/ctl/false\" width=\"800px\" height=\"480px\" style=\"border:0px;\"> </iframe>'\n", | |
| "HTML(iframe_courbe)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Programmation de la découpeuse\n", | |
| "Nous allons simuler la programmation du déplacement de la tête de la découpeuse (jet d'eau, laser) par un programme python.\n", | |
| "\n", | |
| "Nous allons commencer par importer le module *mobilechelonian* qui nous fournira une tortue, *Turtle* en anglais; puis instancier une tortue que l'on nommera **decoupeuse** (sans accent).\n", | |
| "\n", | |
| "```python\n", | |
| "from mobilechelonian import Turtle\n", | |
| "decoupeuse = Turtle()\n", | |
| "```\n", | |
| "\n", | |
| "Pour savoir ce que l'instance *decoupeuse* peut recevoir comme ordres (c'est à dire pour connaître les méthodes de l'objet decoupeuse), on écrit *decoupeuse* dans une cellule de code suivi d'un point et on tape la touche TAB.\n", | |
| "\n", | |
| "*Les chéloniens sont des reptiles dont le tronc est protégé par une carapace dorsale et un plastron ventral (ordre des Chéloniens ; ex. les tortues terrestres et aquatiques*." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from mobilechelonian import Turtle\n", | |
| "decoupeuse = Turtle()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Quelques ordres à la découpeuse:\n", | |
| "**Vitesse de coupe**\n", | |
| "la vitesse de coupe est fixée par l'instruction suivante (de 1 à 10):\n", | |
| "```python\n", | |
| " decoupeuse.speed(1)\n", | |
| "```\n", | |
| "Pour déplacer la decoupeuse:\n", | |
| "```python\n", | |
| " decoupeuse.forward(50)\n", | |
| "```\n", | |
| "\n", | |
| "Pour changer la direction de la decoupeuse vers la gauche d'un angle de $45°$:\n", | |
| "```python\n", | |
| " decoupeuse.left(45)\n", | |
| "```\n", | |
| "\n", | |
| "Pour changer la direction de la decoupeuse vers la droite d'un angle de $30°$:\n", | |
| "```python\n", | |
| " decoupeuse.right(30)\n", | |
| "```\n", | |
| "\n", | |
| "Pour simuler le découpage on tracera un trait:\n", | |
| "```python\n", | |
| " decoupeuse.pendown()\n", | |
| "```\n", | |
| "Pour éteindre le laser ou couper le jet de la découpeuse, on lève le crayon:\n", | |
| "```python\n", | |
| " decoupeuse.penup()\n", | |
| "```\n", | |
| "Enfin, on peut choisir la couleur du trait. On pourrait attribuer la couleur rouge au laser et bleu pour une découpeuse à jet d'eau:\n", | |
| "```python\n", | |
| " laser = \"red\"\n", | |
| " jet = \"blue\"\n", | |
| " decoupeuse.pencolor(laser)\n", | |
| "```\n", | |
| "La découpeuse peut indiquer sa position:\n", | |
| "```python\n", | |
| " print(decoupeuse.posX, decoupeuse.posY)\n", | |
| "```\n", | |
| "### Compléter le code ci-dessous pour simuler le découpage d'un carré:\n", | |
| "Exécuter une première fois le code de la cellule ci dessous.\n", | |
| "Dans la cellule de code ci-dessous, vous compléterez le code **entre les lignes** commençant par un double dièse **##** :\n", | |
| "\n", | |
| "```python\n", | |
| "\n", | |
| " decoupeuse = Turtle()\n", | |
| " decoupeuse.speed(5)\n", | |
| " laser=\"red\"\n", | |
| " côté = 100\n", | |
| "\n", | |
| " decoupeuse.pendown()\n", | |
| " decoupeuse.pencolor(laser)\n", | |
| " print(\"Au début, la découpeuse se trouve au point de coordonnées:\", decoupeuse.position())\n", | |
| " ## Compléter le code ci-dessous pour tracer une découpe carrée\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(90)\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(90)\n", | |
| " \n", | |
| " \n", | |
| " ## fin du code à compléter\n", | |
| " print(\"A la fin, la découpeuse se trouve au point de coordonnées:\", decoupeuse.posX, decoupeuse.posY)\n", | |
| "```\n", | |
| "**Remarque :** On peut utiliser le copier-coller (Ctrl+C , Ctrl+v)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": { | |
| "scrolled": false | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(5)\n", | |
| "laser=\"red\"\n", | |
| "côté = 100\n", | |
| "angle = 90\n", | |
| "x, y = decoupeuse.posX, decoupeuse.posY\n", | |
| "\n", | |
| "print(\"Au début, la découpeuse se trouve au point de coordonnées:\", x, y)\n", | |
| "print(\"On allume le laser\")\n", | |
| "decoupeuse.pendown()\n", | |
| "decoupeuse.pencolor(laser)\n", | |
| "\n", | |
| "\n", | |
| "## Compléter le code ci-dessous\n", | |
| "decoupeuse.forward(côté)\n", | |
| "decoupeuse.left(angle)\n", | |
| "decoupeuse.forward(côté)\n", | |
| "decoupeuse.left(angle)\n", | |
| "\n", | |
| "\n", | |
| "## fin du code à compléter\n", | |
| "\n", | |
| "x, y = decoupeuse.posX, decoupeuse.posY\n", | |
| "print(\"A la fin, la découpeuse se trouve au point de coordonnées:\", x, y)\n", | |
| "print(\"On coupe le laser\")\n", | |
| "decoupeuse.penup()\n", | |
| "print(\"On ramène la tête de la découpeuse à sa position initiale et dans son orientation initiale\")\n", | |
| "decoupeuse.home()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### Utilisation d'une boucle pour répéter un bloc de code\n", | |
| "\n", | |
| "Pour répéter un bloc d'instructions, on place ce bloc dans une boucle. Par exemple pour tracer une découpe en forme de triangle équilatéral, on pourra écrire:\n", | |
| "\n", | |
| "```python\n", | |
| " decoupeuse = Turtle()\n", | |
| " decoupeuse.speed(5)\n", | |
| " laser=\"red\"\n", | |
| " côté = 100\n", | |
| " angle = 120\n", | |
| " \n", | |
| " for etape in range(3):\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(angle)\n", | |
| " decoupeuse.penup()\n", | |
| " decoupeuse.home()\n", | |
| "```\n", | |
| "#### Exécuter le code ci-dessous:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(5)\n", | |
| "laser=\"red\"\n", | |
| "côté = 100\n", | |
| "angle = 120\n", | |
| "decoupeuse.pencolor(laser)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "for etape in range(3):\n", | |
| " print(\"étape:\", etape)\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(angle)\n", | |
| "\n", | |
| "decoupeuse.penup()\n", | |
| "decoupeuse.home()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Modifier le code ci-dessous pour tracer un pentagone régulier de côté de longueur égale à 100" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(5)\n", | |
| "laser=\"red\"\n", | |
| "côté = 100\n", | |
| "angle = 120\n", | |
| "decoupeuse.pencolor(laser)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "for etape in range(3):\n", | |
| " print(\"étape:\", etape)\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(angle)\n", | |
| "\n", | |
| "decoupeuse.penup()\n", | |
| "decoupeuse.home()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### Position de la tête de découpage\n", | |
| "Dans la vidéo sur la découpeuse laser, vous remarquez que l'origine du repère est en haut et à gauche. L'axe des abscisses pointe vers le bas.\n", | |
| "Vérifier le en déplaçant la découpeuse.\n", | |
| "\n", | |
| " * Quelle est l'abscisse maximale atteinte par la découpeuse?\n", | |
| " * Quelle est l'ordonnée maximale atteinte par la découpeuse?" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(2)\n", | |
| "decoupeuse.home()\n", | |
| "decoupeuse.penup()\n", | |
| "\n", | |
| "decoupeuse.setposition(0,0)\n", | |
| "decoupeuse.pendown()\n", | |
| "decoupeuse.setposition(50,100)\n", | |
| "decoupeuse.setposition(200,30)\n", | |
| "decoupeuse.setposition(150,400)\n", | |
| "\n", | |
| "decoupeuse.penup()\n", | |
| "decoupeuse.home()\n", | |
| "#print(decoupeuse.points)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### Traçons un triangle equilatéral et un carré superposés:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "\n", | |
| "laser =\"red\"\n", | |
| "jet = \"blue\"\n", | |
| "côté = 100\n", | |
| "angle = 120\n", | |
| "\n", | |
| "decoupeuse.speed(8)\n", | |
| "decoupeuse.penup()\n", | |
| "\n", | |
| "#Tracé du triangle\n", | |
| "decoupeuse.setposition(50,300)\n", | |
| "decoupeuse.pencolor(laser)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "for etape in range(3):\n", | |
| " print(\"étape:\", etape)\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(angle)\n", | |
| "\n", | |
| "#Tracé du carré\n", | |
| "decoupeuse.penup()\n", | |
| "decoupeuse.setposition(50,300)\n", | |
| "angle = 90\n", | |
| "decoupeuse.pencolor(jet)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "for etape in range(4):\n", | |
| " print(\"étape:\", etape)\n", | |
| " decoupeuse.forward(côté)\n", | |
| " decoupeuse.left(angle)\n", | |
| " \n", | |
| " \n", | |
| "decoupeuse.penup()\n", | |
| "decoupeuse.home()\n", | |
| "decoupeuse.pendown()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Tracer une découpe inscrite dans un cercle de rayon fixe:\n", | |
| "\n", | |
| "Dans les algorithmess de découpe précédants, la longueur du côté est **constante**; plus le nombre de côtés augmente, plus l'aire de la découpe augmente, comme dans la première activité geogebra.\n", | |
| "\n", | |
| "On souhaite que la découpe soit un polygone régulier inscrit dans un cercle de rayon choisi à l'avance:\n", | |
| " * la longueur des côtés va **dépendre du nombre de côtés**\n", | |
| " * pour calculer la longueur d'un côté, on va utiliser la fonction dont on a tracé la courbe avec geogebra\n", | |
| " * on connaît \"la formule\" (l'expression de la fonction), c'est:\n", | |
| " \n", | |
| " $$ f(x)= r \\times \\dfrac{sin(\\frac{2 \\pi}{x})}{cos(\\frac{\\pi}{x})}$$ \n", | |
| " \n", | |
| " * avec $x$: le nombre de côtés, $x$ est donc un nombre entier tel que $x\\geq 3$ ou encore $x>2$\n", | |
| " * et $f(x)$ : la longueur d'un côté\n", | |
| " * $r$ : rayon du cercle circonscrit (le polygone est inscrit dans le cercle).\n", | |
| "\n", | |
| "### Utilisons la fonction $f$ donnée:\n", | |
| "Nous allons utiliser le module sympy qui permet de construire des fonctions comme on le fait en mathématiques. Python permet aussi de définir des fonctions de manière un peu différente.\n", | |
| "\n", | |
| "1. importons des éléments du module sympy dont nous aurons besoin (**ligne 1**)\n", | |
| "2. construisons la fonction $f$ (**lignes 2-4**)\n", | |
| "3. demandons le nombre $x$ de côtés du polygone (**ligne 5**)\n", | |
| "4. remplaçons $x$ par sa valeur dans $f$ et affichons la longueur exacte $f(x)$ (**ligne 7**)\n", | |
| "5. affichons la longueur approchée de $f(x)$ (**ligne 8**)\n", | |
| "\n", | |
| " ```python\n", | |
| " from sympy import Symbol, cos, sin, pi, plot, init_printing\n", | |
| " x = Symbol('x')\n", | |
| " r = 50\n", | |
| " f = Lambda(x,r * sin(2*pi/x)/cos(pi/x))\n", | |
| " côtés = int(input(\"Entrer le nombre de côtés et valider par Entrée:\"))\n", | |
| " print(\"Le longueur du côté du polygone à \",côtés,\" côtés est:\")\n", | |
| " pprint(f(côtés))\n", | |
| " print(\"une valeur approchée est:\", f(côtés).evalf())\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from sympy import Symbol, Lambda, cos, sin, pi, plot, pprint, init_printing\n", | |
| "x = Symbol('x')\n", | |
| "r = 50\n", | |
| "f = Lambda(x,r * sin(2*pi/x)/cos(pi/x))\n", | |
| "côtés = int(input(\"Entrer le nombre de côtés et valider par Entrée:\"))\n", | |
| "print(\"Le longueur du côté du polygone à \",côtés,\" côtés est:\")\n", | |
| "pprint(f(côtés))\n", | |
| "print(\"une valeur approchée est:\", f(côtés).evalf())" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "### En utilisant les résulats précédents:\n", | |
| "Modifier le code ci-dessous pour tracer le polygone régulier correspondant aux résultats des calculs précédents. Vous devez-vous poser les questions suivantes:\n", | |
| "\n", | |
| " * Quel nombre de côtés le polygone comporte-t-il?\n", | |
| " * Quelle est la mesure de l'angle de changement de direction?\n", | |
| " * Quelle est la longueur d'un côté du polygone?\n", | |
| "Remarque:\n", | |
| "On peut calculer l'angle automatiquement, un indice (à compléter)\n", | |
| "```python\n", | |
| " angle = 360 / ...\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(10)\n", | |
| "\n", | |
| "laser =\"red\"\n", | |
| "jet = \"blue\"\n", | |
| "longueur_côté = 100\n", | |
| "nombre_côtés = 3\n", | |
| "angle = 120\n", | |
| "\n", | |
| "\n", | |
| "decoupeuse.speed(8)\n", | |
| "decoupeuse.penup()\n", | |
| "\n", | |
| "#Tracé du polygone\n", | |
| "decoupeuse.home()#setposition(100,300)\n", | |
| "decoupeuse.pencolor(laser)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "for côté in range(nombre_côtés):\n", | |
| " decoupeuse.forward(longueur_côté)\n", | |
| " decoupeuse.left(angle)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Houston, on a un problème:\n", | |
| "\n", | |
| "Avez-vous remarqué que la tortue ne tourne pas si l'angle n'est pas un nombre entier?" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "decoupeuse = Turtle()\n", | |
| "longueur_côté = 50\n", | |
| "decoupeuse.speed(8)\n", | |
| "#\n", | |
| "# Code sans erreur\n", | |
| "#\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"red\")\n", | |
| "decoupeuse.left(0)\n", | |
| "decoupeuse.forward(longueur_côté)\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"blue\")\n", | |
| "decoupeuse.left(20)\n", | |
| "decoupeuse.forward(longueur_côté)\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"green\")\n", | |
| "decoupeuse.left(30)\n", | |
| "decoupeuse.forward(longueur_côté)\n", | |
| "\n", | |
| "decoupeuse.penup()\n", | |
| "#\n", | |
| "# Code avec erreur\n", | |
| "#\n", | |
| "decoupeuse.home()\n", | |
| "decoupeuse.setposition(200,300)\n", | |
| "decoupeuse.pendown()\n", | |
| "\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"red\")\n", | |
| "decoupeuse.left(0)\n", | |
| "decoupeuse.forward(longueur_côté)\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"blue\")\n", | |
| "decoupeuse.left(20)\n", | |
| "decoupeuse.forward(longueur_côté)\n", | |
| "\n", | |
| "decoupeuse.pencolor(\"green\")\n", | |
| "decoupeuse.left(30.5)\n", | |
| "decoupeuse.forward(longueur_côté)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Les angles qui permettent de tracer un polygone régulier avec la découpeuse:\n", | |
| "\n", | |
| "Les mesures de ces angles doivent être des valeurs entières.\n", | |
| "Pour un rayon donné du cercle circonscrit au polygone, les mesures des angle" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "angles_possibles = []\n", | |
| "for angle in range(1, 360+1):\n", | |
| " if 360 % angle == 0:\n", | |
| " angles_possibles.append(angle)\n", | |
| "\n", | |
| "print('360° est un multiple des mesures d\\'angle suivants:')\n", | |
| "print(angles_possibles)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Avec les outils numériques de ce notebook, déterminer la nature du polygone suivant:\n", | |
| "\n", | |
| "1. Quelle est la nature d'un polygone tracé par une découpeuse avec un angle de changement de direction de mesure égale à 24°?\n", | |
| "2. Quelle est la longueur d'un côté de ce polygone de rayon égal à 50 unités de longueur (en pratique, on choisitait 50 mm)?\n", | |
| "3. Compléter dans la cellule ci-dessous, le programme implémentant l'algorithme qui permet de tracer ce polygone.\n", | |
| "\n", | |
| "### Rappel:\n", | |
| "Vous disposez de la fonction:\n", | |
| "$$f(x)=r \\times {\\dfrac{sin(\\frac{2 \\pi}{x})}{cos(\\frac{\\pi}{x})}} $$\n", | |
| "avec:\n", | |
| " * $x$ : nombre de coté du polygone\n", | |
| " * $r$ : rayon du cercle circonscrit au polygone représentant la découpe\n", | |
| " * $f(x)$ : la longueur d'un côté du polygone régulier.\n", | |
| "\n", | |
| "Le code python (sympy) définissant $f$ est:\n", | |
| "```python\n", | |
| " f = Lambda(x,rayon * sin(2*pi/x)/cos(pi/x))\n", | |
| "```\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "#\n", | |
| "# Les modules mobilechelonian et sympy doivent avoir été importés (voir ci dessus)\n", | |
| "#\n", | |
| "\n", | |
| "# définition de la fonction f utilisant le module sympy\n", | |
| "x = Symbol('x')\n", | |
| "rayon = 50\n", | |
| "nombre_côtés = #compléter cette variable\n", | |
| "f = Lambda(x,rayon * sin(2*pi/x)/cos(pi/x))\n", | |
| "longueur_côté = f() #compléter la valeur dans f()\n", | |
| "\n", | |
| "print(\"Le longueur du côté du polygone à \",nombre_côtés,\" côtés est:\")\n", | |
| "pprint(f(nombre_côtés))\n", | |
| "print(\"une valeur approchée de la longueur d'un côté est:\", f(nombre_côtés).evalf())\n", | |
| "\n", | |
| "\n", | |
| "# Programmation de la découpeuse\n", | |
| "decoupeuse = Turtle()\n", | |
| "decoupeuse.speed(10)\n", | |
| "\n", | |
| "jet = \"blue\"\n", | |
| "angle = #compléter cette variable\n", | |
| "\n", | |
| "longueur_côté = f(nombre_côtés).evalf() \n", | |
| "# tracé du polygone\n", | |
| "decoupeuse.pencolor(jet)\n", | |
| "decoupeuse. #compléter l'ordre à donner à decoupeuse\n", | |
| "for côté in range(nombre_côtés):\n", | |
| " decoupeuse. #compléter l'ordre à donner à decoupeuse\n", | |
| " decoupeuse.left() #compléter l'ordre à donner à decoupeuse" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "celltoolbar": "Aucun(e)", | |
| "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.6" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment