Dans ma vie professionnelle, et pas plus tard qu’hier, j’ai souvent eu à trouver l’équation d’une parabole passant par 3 points. Pourquoi ? Parce que dans les exercices que l’on propose aux élèves, c’est pratique!

Le problème est que le logiciel geobegra ne permet pas de le faire à ma connaissance.

J’ai donc dû m’y coller en Python…

Trouver l’équation d’une parabole passant par 3 points: aspect mathématique

Voyons avant tout l’aspect mathématique du problème. C’est assez simple: on connait les coordonnées de trois points, et on cherche les coefficients a, b et c de la fonction f(x) = ax² + bx + c de sorte que sa courbe représentative passe par les trois points.

Formallisation

On pose \(A(x_A;y_A)\), \(B(x_B;y_B)\) et \(C(x_C;y_C)\) nos trois points. On a alors le système:$$\left\{\begin{array}{l}ax_A^2+bx_A+c=y_A\\ax_B^2+bx_B+c=y_B\\ax_C^2+bx_C+c=y_C \end{array}\right.$$

Résolution algébrique

Ce système est un système linéaire de trois équations à trois inconnues, donc rien de bien méchant à résoudre…C’est juste un peu long si on le fait à la main. Mais nous n’allons pas le faire, bien sûr… car nous sommes des sacripants… 🙂

Nous allons écrire ce système de façon matricielle:$$\begin{pmatrix}x_A^2 & x_A & 1\\x_B^2 & x_B & 1\\x_C^2 & x_C & 1\\ \end{pmatrix}\begin{pmatrix}a\\b\\c\end{pmatrix}=\begin{pmatrix}y_A\\y_B\\y_C\end{pmatrix}.$$

On en déduit alors:$$\begin{pmatrix}a\\b\\c\end{pmatrix}=\begin{pmatrix}y_A\\y_B\\y_C\end{pmatrix}\begin{pmatrix}x_A^2 & x_A & 1\\x_B^2 & x_B & 1\\x_C^2 & x_C & 1\\ \end{pmatrix}^{-1}.$$

Trouver l’équation d’une parabole passant par 3 points: implémentation en Python

Il existe une méthode pour résoudre de tels systèmes linéaires en Python. Avec le module numpy et linalg.solve, l’affaire est pliée… Sauf que la plupart du temps, le système est résolu sur les flottants et donne donc comme résultats des nombres en valeurs approchées! Scrogneugneu! C’est carrément naze! Il nous faut donc mettre ce qui nous sert de cerveau en mode cogitum.

Des coefficients rationnels

L’idée est de manipuler des rationnels, et non des flottants. On ne va donc pas utiliser numpy mais sympy qui, d’ailleurs, est quand-même approprié pour faire de l’algèbre.

from sympy import Matrix, Rational

def parabola(A,B,C):
    L = [A,B,C]
    matrice = Matrix([[Rational(a**2),Rational(a),Rational(1)] for a,b in L])
    other = Matrix([[Rational(b)] for a,b in L])

    return matrice.solve(other)

if __name__ == '__main__':
    A, B, C = (-5,4), (0,-3), (7,5)
P = parabola(A,B,C)

Voilà! Avec la fonction parabola, j’ai la matrice des coefficients a, b, c. Il nous faut maintenant peaufiner tout ça.

Tracé de la parabole en Python

Une fois l’expression de la parabole obtenue, je vais la tracer. Je vais définir alors les deux fonctions suivantes.

from sympy import Matrix, Rational, latex
import matplotlib.pyplot as plt
import numpy as np

def f(P,x):
    return P[0]*x*x + P[1]*x + P[2]
    
def draw_parabola(A, B, C):
    P = parabola(A,B,C)
    x = np.linspace(-10, 10, 400)
    y = f(P,x)

    # Convertir les coefficients en chaînes de caractères LaTeX
    P_latex = [latex(P[i]) for i in range(3)]
    chaine = rf'$f(x) = {P_latex[0]}x^2'
    if P[1] < 0:
        chaine += rf' {P_latex[1]}x'
    else:
        chaine += rf' + {P_latex[1]}x'
    if P[2] < 0:
        chaine += rf' {P_latex[2]}$'
    else:
        chaine += rf' + {P_latex[2]}$'
        
    plt.plot(x, y, label=chaine)

    # Ajouter les points

    for a,b in [A,B,C]:
        plt.scatter(a, b, color='red', zorder=5)
        plt.annotate(f'({a},{b})', (a, b), textcoords="offset points", xytext=(-15,-10), ha='center', color='red')
    plt.title('Graphique de la fonction f(x)')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()

    # Afficher la grille
    plt.grid(True)

    # Afficher le graphique
    plt.show()

Là, une magnifique courbe se dessine alors, faisant apparaître les trois points imposés.

trouver parabole passant par 3 points python

Tracé de la courbe en \(LaTeX\)

Si on souhaite créer de beaux devoirs pour nos chers chérubins, le graphique à la matplotlib ne suffira pas nécessairement. Le top du top, c’est tout de même d’avoir un graphique en \(\LaTeX\). Alors soit!

On va créer une fonction qui crée la courbe en \(\LaTeX\) à l’aide de TiKZ.

import os

def export_latex(A, B, C, x_range=(-10, 10), num_points=100):
    P = parabola(A,B,C)
    # Convertir les coefficients en chaînes de caractères LaTeX
    P_latex = [ '({}/{})'.format(P[i].numerator,P[i].denominator) for i in range(3)]
    
    y_min, y_max = 0,0
    x = x_range[0]
    while x <= x_range[1]:
        if P[0]*x*x+P[1]*x+P[2] < y_min:
            y_min = P[0]*x*x+P[1]*x+P[2]
        if P[0]*x*x+P[1]*x+P[2] > y_max:
            y_max = P[0]*x*x+P[1]*x+P[2]
        x += (x_range[1]-x_range[0])/num_points
    
    y_min, y_max = y_min-1, y_max+1
    points_latex = ''
    
    for x,y in [A,B,C]:
        points_latex += f"""
            \\fill[red] ({x},{y}) circle (4pt);\n
        """
    
    tikz_code = f"""
\\documentclass{{standalone}}
\\usepackage{{tikz}}
\\begin{{document}}
\\begin{{tikzpicture}}
    \\draw[gray,dashed] ({x_range[0]},{y_min}) grid ({x_range[1]},{y_max});
    \\draw[thick,->,>=latex] ({x_range[0]},0) -- ({x_range[1]},0);
    \\draw[thick,->,>=latex] (0,{y_min}) -- (0,{y_max});
    \\draw[thick] (1,0.1) -- (1,-0.1) node[below] {{1}};
    \\draw[thick] (0.1,1) -- (-0.1,1) node[left] {{1}};
    \\draw[thick, smooth, domain={x_range[0]}:{x_range[1]}, samples={num_points}] plot (\\x, {{ {P_latex[0]}*\\x*\\x + {P_latex[1]}*\\x + {P_latex[2]} }});
    {points_latex}
\\end{{tikzpicture}}
\\end{{document}}
"""
    with open('parabola_plot.tex', 'w') as f:
        f.write(tikz_code)
        
    cmd = "pdflatex  --shell-escape -synctex=1 -interaction=nonstopmode parabola_plot.tex"
    os.system(cmd)
    
    readpdf = "START parabola_plot.pdf"
    os.system(readpdf)

Voili-voilou!

trouver parabole passant par 3 points LaTeX TiKZ

Cette fonction exporte le fichier \(\LaTeX\), puis le compile via PdfLaTeX. Ainsi, on peut le retoucher si besoin est.

Il y a fort à parier que ce code est à conserver dans vos outils de profs, n’est-ce pas ? ça vous laissera plus de temps pour regarder Netflix 🙂 (bon, là, je parle pour moi…).

Le script complet

# -*- coding: utf-8 -*-
"""
Created on Fri May 17 18:13:53 2024

@author: Stéphane Pasquet
@url: https://www.mathweb.fr/euclide/2024/05/18/trouver-lequation-dune-parabole-passant-par-3-points/
"""

from sympy import Matrix, Rational, latex
import matplotlib.pyplot as plt
import numpy as np
import os

# retourne a, b, x de y = ax² + bx + c, où A, B, C sont sur la parabole

def parabola(A,B,C):
    L = [A,B,C]
    matrice = Matrix([[Rational(a**2),Rational(a),Rational(1)] for a,b in L])
    other = Matrix([[Rational(b)] for a,b in L])

    return matrice.solve(other)
    
def f(P,x):
    return P[0]*x*x + P[1]*x + P[2]
    

def draw_parabola(A, B, C):
    P = parabola(A,B,C)
    x = np.linspace(-10, 10, 400)
    y = f(P,x)

    # Convertir les coefficients en chaînes de caractères LaTeX
    P_latex = [latex(P[i]) for i in range(3)]
    chaine = rf'$f(x) = {P_latex[0]}x^2'
    if P[1] < 0:
        chaine += rf' {P_latex[1]}x'
    else:
        chaine += rf' + {P_latex[1]}x'
    if P[2] < 0:
        chaine += rf' {P_latex[2]}$'
    else:
        chaine += rf' + {P_latex[2]}$'
        
    plt.plot(x, y, label=chaine)

    # Ajouter les points

    for a,b in [A,B,C]:
        plt.scatter(a, b, color='red', zorder=5)
        plt.annotate(f'({a},{b})', (a, b), textcoords="offset points", xytext=(-15,-10), ha='center', color='red')
    plt.title('Graphique de la fonction f(x)')
    plt.xlabel('x')
    plt.ylabel('f(x)')
    plt.legend()

    # Afficher la grille
    plt.grid(True)

    # Afficher le graphique
    plt.show()

def export_latex(A, B, C, x_range=(-10, 10), num_points=100):
    P = parabola(A,B,C)
    # Convertir les coefficients en chaînes de caractères LaTeX
    P_latex = [ '({}/{})'.format(P[i].numerator,P[i].denominator) for i in range(3)]
    
    y_min, y_max = 0,0
    x = x_range[0]
    while x <= x_range[1]:
        if P[0]*x*x+P[1]*x+P[2] < y_min:
            y_min = P[0]*x*x+P[1]*x+P[2]
        if P[0]*x*x+P[1]*x+P[2] > y_max:
            y_max = P[0]*x*x+P[1]*x+P[2]
        x += (x_range[1]-x_range[0])/num_points
    
    y_min, y_max = y_min-1, y_max+1
    points_latex = ''
    
    for x,y in [A,B,C]:
        points_latex += f"""
            \\fill[red] ({x},{y}) circle (4pt);\n
        """
    
    tikz_code = f"""
\\documentclass{{standalone}}
\\usepackage{{tikz}}
\\begin{{document}}
\\begin{{tikzpicture}}
    \\draw[gray,dashed] ({x_range[0]},{y_min}) grid ({x_range[1]},{y_max});
    \\draw[thick,->,>=latex] ({x_range[0]},0) -- ({x_range[1]},0);
    \\draw[thick,->,>=latex] (0,{y_min}) -- (0,{y_max});
    \\draw[thick] (1,0.1) -- (1,-0.1) node[below] {{1}};
    \\draw[thick] (0.1,1) -- (-0.1,1) node[left] {{1}};
    \\draw[thick, smooth, domain={x_range[0]}:{x_range[1]}, samples={num_points}] plot (\\x, {{ {P_latex[0]}*\\x*\\x + {P_latex[1]}*\\x + {P_latex[2]} }});
    {points_latex}
\\end{{tikzpicture}}
\\end{{document}}
"""
    with open('parabola_plot.tex', 'w') as f:
        f.write(tikz_code)
        
    cmd = "pdflatex  --shell-escape -synctex=1 -interaction=nonstopmode parabola_plot.tex"
    os.system(cmd)
    
    readpdf = "START parabola_plot.pdf"
    os.system(readpdf)


if __name__ == '__main__':
    A, B, C = (-5,4), (0,-3), (7,5)
    draw_parabola(A, B, C)
    export_latex(A, B, C)

0 0 votes
Évaluation de l'article
S’abonner
Notification pour
guest
2 Commentaires
Le plus ancien
Le plus récent Le plus populaire
Commentaires en ligne
Afficher tous les commentaires
vincek

Bonjour,

Dans geogebra, Polynôme(A, B, C), trace la parabole passant par A, B et C. C’est très utile pour les activités de modélisation polynomiale avec les élèves.

En python, c’est toujours intéressant.

Cdt

Vincek

2
0
Nous aimerions avoir votre avis, veuillez laisser un commentaire.x