module Geometry.Bezier where import Geometry.Data import Geometry.Vector {- | A synonym describing a quadratic Bezier curve as three 'Point2's: start, control and end. -} type BQuad = (Point2,Point2,Point2) {- | Split a quadratic Bezier curve into two at a fractional point along the curve. If the fraction is not between 0 and 1, this will create backwards curves. -} splitBezierquad :: BQuad -> Float -> (BQuad,BQuad) splitBezierquad (a,b,c) z = ( ( a , (z *.* b) -.- ((z-1) *.* a) , (z**2 *.* c) +.+ ((z-1)**2 *.* a) -.- (2*z*(z-1) *.* b) ) , ( (z**2 *.* c) +.+ ((z-1)**2 *.* a) -.- (2*z*(z-1) *.* b) , (z *.* c) -.- ((z-1) *.* b) , c ) ) {- | Split a quadratic Bezier curve into a given number of straight lines, and return the list of points defining these lines. -} bQuadToLine :: BQuad -> Int -> [Point2] bQuadToLine (a,_,c) 0 = [a,c] bQuadToLine x i = let (l,r) = splitBezierquad x 0.5 in bQuadToLine l (i-1) ++ bQuadToLine r (i-1) {- | Transform a quadratic Bezier curve into a function. -} bQuadToF :: (Point2,Point2,Point2) -> Float -> Point2 bQuadToF (c,b,a) t = t *.* (t *.* a +.+ (1-t) *.* b) +.+ (1-t) *.* (t *.* b +.+ (1-t) *.* c)