Enveloppe d’une famille de droites

En parcourant le livre “Mathematiques et graphismes” de 1985, j’ai trouvé page 41 un programme intéressant en BASIC (pour TO7/Apple/Commodore 64/Oric etc) permettant de tracer une enveloppe de droites (de la forme ax+by+c = 0). En faisant varier a,b et c en fonction d’un paramètre (noté t dans le programme), on obtient des visuels sympathiques :

Traduction en Python (avec 18 exemples)

Version pour la NUMWORKS ici.

import turtle
from math import *
from time import sleep

t = turtle.Turtle()
t.hideturtle()
t.pensize(2)

w, h = 800, 600

wn = turtle.Screen()

wn.colormode(255)
t.pencolor(255, 255, 0)


def ex0():
    def g(t):
        return 2 - t * t, -2 * t, t**3

    return g, -5, 5, -2, 1.5, -3, 3


def ex1():
    def g(t):
        return cos(3 * t), sin(3 * t), sin(t) ** 2

    return g, -1, 1, -1.1, 1.1, 0, 2 * pi


def ex2():
    def g(t):
        return cos(3 * t), sin(3 * t), cos(t)

    return g, -1.2, 0.8, -1.2, 1.2, -pi / 2, pi / 2


def ex3():
    def g(t):
        return cos(t), sin(t), exp(-exp(-t / 5))

    return g, -2, 2, -2, 3, -5, 10


def ex4():
    def g(t):
        return cos(t), sin(t), -sin(t) / t

    return g, -0.3, 1.2, -0.9, 0.9, -5, 5


def ex5():
    def g(t):
        return cos(t), sin(t), -1 - int(t / 2 / pi)

    return g, -6, 6, -6, 6, 0, 10 * pi


def ex6():
    def g(t):
        return cos(t), sin(t), 1 / t

    return g, -2, 2, -1, 0.5, -10, 10


def ex7():
    def g(t):
        return cos(t), sin(t), log10(t)

    return g, -4, 4, -4, 4, 0.2, 20


def ex8():
    def g(t):
        return cos(t), sin(t), t * t * sin(t)

    return g, -4, 4, -10, 3, -pi, pi


def ex9():
    def g(t):
        return cos(t), sin(t), t * t / (1 + t * t)

    return g, -1, 1, -1, 1, -2 * pi, 2 * pi


def ex10():
    def g(t):
        return cos(t), sin(t), (1 - t * t) / (1 + t * t)

    return g, -1.5, 1.5, -1.5, 1.5, -2 * pi, 2 * pi


def ex11():
    def g(t):
        return cos(t), sin(t), sqrt(abs(t))

    return g, -4, 4, -4, 4, -10, 10


def ex12():
    def g(t):
        return cos(t), sin(t), t / (1 + t)

    return g, -3, 3, -3, 3, -10, 10


def ex13():
    def g(t):
        return cos(t), sin(t), 2 + cos(t / 2)

    return g, -4, 4, -4, 4, -2 * pi, 2 * pi


def ex14():
    def g(t):
        return cos(t), sin(t), -0.5 + cos(t / 2)

    return g, -2, 2, -2, 2, -2 * pi, 2 * pi


def ex15():
    def g(t):
        return cos(t), sin(t), t * t * sin(t)

    return g, -4, 4, -10, 3, -pi, pi


def ex16():
    def g(t):
        return cos(t), sin(t), t * t / (1 - t * t)

    return g, -1.5, 2, -2, 2, -2 * pi, 2 * pi


def ex17():
    def g(t):
        return cos(t), sin(t), sin(t) + sin(t) ** 2 / 2 + sin(t) ** 3 / 3

    return g, -2, 2, -3, 0, -pi, pi


def tracer(x, y):
    global f, pts
    if x < xi or x > xs or y < yi or y > ys:
        return
    f += 1
    pts[f] = [
        -w / 2 + ceil(w * (x - xi) / (xs - xi)),
        -h / 2 + ceil(h * (y - yi) / (ys - yi)),
    ]
    if f == 1 and pts[0] == pts[1]:
        f = -1
    elif f == 1:
        t.penup()
        t.goto(pts[0])
        t.pendown()
        t.goto(pts[1])


t.hideturtle()
for k in range(18):
    turtle.Screen().bgcolor(0, 0, 0)
    t.clear()
    wn.tracer(0)
    g, xi, xs, yi, ys, ti, ts = eval("ex" + str(k) + "()")
    pts = [[0, 0], [0, 0]]
    n = 200
    th = (ts - ti) / (n - 1)
    for i in range(n):
        try: a, b, c = g(ti + i * th)
        except: continue
        f = -1
        if b != 0:
            tracer(xi, -(c + a * xi) / b)
            tracer(xs, -(c + a * xs) / b)
        if a != 0:
            tracer(-(c + b * yi) / a, yi)
            tracer(-(c + b * ys) / a, ys)
    wn.update()
    sleep(2)