createCurve :: CurveInput -> Curve 
createCurve (CurvePointsAndT e params@((lextr,t, b):(p2,_,_):ps)) = BezierJoints $ Through lextr dv b : Control clextr : go params
  where
    dv = computeDVector (centralSymAbout lextr p2) lextr p2 t
    clextr = lextr .+^ (e *^ dv)
    go [(pbl,_,_),(rextr,t, b)] = [Control crextr, Through rextr dv b]
      where
        dv = computeDVector pbl rextr (centralSymAbout rextr pbl) t
        crextr = rextr .-^ (e *^ dv)
    go ((p1,_,_):ps@((p2,t,b):(p3,_,_):_)) = Control lcp : Through p2 dv b : Control rcp : go ps
      where
        dv = computeDVector p1 p2 p3 t
        lcp = p2 .-^ (e *^ dv)
        rcp = p2 .+^ (e *^ dv)
createCurve :: CurveInput -> Curve
createCurve (CurvePointsAndT e params@((lextr,t, b):(p2,_,_):ps)) = BezierJoints $ Through lextr dv b : Control clextr : go params
  where
    dv = computeDVector (centralSymAbout lextr p2) lextr p2 t
    clextr = lextr .+^ (e *^ dv)
    go [(pbl,_,_),(rextr,t, b)] = [Control crextr, Through rextr dv b]
      where
        dv = computeDVector pbl rextr (centralSymAbout rextr pbl) t
        crextr = rextr .-^ (e *^ dv)
    go ((p1,_,_):ps@((p2,t,b):(p3,_,_):_)) = Control lcp : Through p2 dv b : Control rcp : go ps
      where
        dv = computeDVector p1 p2 p3 t
        lcp = p2 .-^ (e *^ dv)
        rcp = p2 .+^ (e *^ dv)
createCurve (CurvePointsAndT e params@((lextr,t, b):(p2,_,_):ps)) = BezierJoints $ Through lextr dv b : Control clextr : go params
  where
    dv = computeDVector (centralSymAbout lextr p2) lextr p2 t
    clextr = lextr .+^ (e *^ dv)
    go [(pbl,_,_),(rextr,t, b)] = [Control crextr, Through rextr dv b]
      where
        dv = computeDVector pbl rextr (centralSymAbout rextr pbl) t
        crextr = rextr .-^ (e *^ dv)
    go ((p1,_,_):ps@((p2,t,b):(p3,_,_):_)) = Control lcp : Through p2 dv b : Control rcp : go ps
      where
        dv = computeDVector p1 p2 p3 t
        lcp = p2 .-^ (e *^ dv)
        rcp = p2 .+^ (e *^ dv)