Voici une proposition de correction de l'exercice 2.18 du poly d'analyse numérique sur les courbes de Bézier.
Haskell
import Graphics.EasyPlot type Point = (Float,Float) mapT :: (Float -> Float) -> Point -> Point mapT f (a1, a2) = (f a1, f a2) zipT :: (Float -> Float -> Float) -> Point -> Point -> Point zipT f (a,b) (c,d) = (f a c, f b d) infixr 4 @* (@*) :: Float -> Point -> Point (@*) k p = mapT (*k) p infixr 2 @+ (@+) :: Point -> Point -> Point (@+) p1 p2 = zipT (+) p1 p2 (@-) :: Point -> Point -> Point (@-) p1 p2 = zipT (-) p1 p2 bezier2 :: [Point] -> [Graph2D Float Float] bezier2 [p0,p1,p2] = let m = \ t -> (1 - t)**2 @* p0 @+ 2*t*(1 - t) @* p1 @+ t**2 @* p2 in [ Data2D [Title "Courbe de Bézier d'ordre 2", Color Blue, Style Lines] [] [m t | t <- [0, 2**(-8) .. 1]], Data2D [Title "Direction de départ", Color Green, Style Lines] [] [p0,p1], Data2D [Title "Direction d'arrivée", Color Red , Style Lines] [] [p1,p2] ] bezier2 _ = [] bezier3 :: [Point] -> [Graph2D Float Float] bezier3 [p0,p1,p2,p3] = let m = \ t -> (1 - t)**3 @* p0 @+ 3*t*(1 - t)**2 @* p1 @+ 3*(1 - t)*t**2 @* p2 @+ t**3 @* p3 in [ Data2D [Title "", Color Blue, Style Lines] [] [m t | t <- [0, 2**(-8) .. 1]], Data2D [Title "", Color Green, Style Lines] [] [p0,p1], Data2D [Title "", Color Red , Style Lines] [] [p2,p3] ] bezier3 _ = [] beziaux :: [Point] -> [Point] -- Rajoute les points pour que la courbe soit de classe C1 beziaux (p1:p2:p3:p4:xs) = p1:p2:p3:p4:(beziaux (p4:((2 @* p4) @- p3):xs)) beziaux _ = [] bezierP :: [Point] -> [Graph2D Float Float] -- Colle les bouts de bezier3 bezierP [] = [] bezierP listeP = let (x1,x2) = splitAt 4 listeP in (bezier3 x1) ++ (bezierP x2) bezier :: TerminalType -> [Point] -> IO Bool -- crée le graphique avec le type de terminal en option (X11, PDF, ...) bezier option listeP = plot option (bezierP $ beziaux listeP) --bezier X11 [(0,2),(0,3),(0,6),(-2,6),(-4,2),(-4,0),(0,-10),(0,-10),(4,-2),(4,0),(4,6),(2,6),(0,3),(0,2)] bspline3 :: [Point] -> [Graph2D Float Float] bspline3 [p0,p1,p2,p3] = let m = \ t -> (1/6) @* ((1 - t)**3 @* p0 @+ (3*t**3 -6*t**2 +4) @* p1 @+ (-3*t**3 + 3*t**2 + 3*t + 1) @* p2 @+ t**3 @* p3) in [ Data2D [Title "", Color Blue, Style Lines] [] [m t | t <- [0, 0.01 .. 1]], Data2D [Title "", Color Green, Style Lines] [] [p0,p1], Data2D [Title "", Color Red , Style Lines] [] [p2,p3] ] bspline3 _ = [] bsplinaux :: [Point] -> [Point] -- Rajoute les points pour que la courbe soit de classe C1 bsplinaux (p1:p2:p3:p4:xs) = p1:p2:p3:p4:(bsplinaux (p2:p3:p4:xs)) bsplinaux _ = [] bsplineP :: [Point] -> [Graph2D Float Float] -- Colle les bouts de bezier3 bsplineP [] = [] bsplineP listeP = let (x1,x2) = (take 4 listeP, drop 4 listeP) in (bspline3 x1) ++ (bsplineP x2) bspline :: TerminalType -> [Point] -> IO Bool -- crée le graphique avec le type de terminal en option (X11, PDF, ...) bspline option listeP = plot option (bsplineP $ bsplinaux listeP)