Beziers versus catmull-rom splines

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

Beziers versus catmull-rom splines

Post by relsoft »

Although baziers look "sexier" catmull-rom splines are easier to use n entity motion because the interpolated spline is guaranteed to pass through all the control points.

White for catmull and magenta for beziers


Code: Select all

Type Tpoint
    x           as single
    y           as single
end type

function catmull_rom(byval p0 as TPoint, byval p1 as TPoint, byval p2 as TPoint, byval p3 as TPoint, byval t as single) as Tpoint

	dim as single  t2 = t * t
	dim as single  t3 = t2 * t
    dim as Tpoint catmull_point
	catmull_point.x = 0.5f * ( ( 2.0 * p1.x ) +_
        ( -p0.x + p2.x ) * t +_
		( 2.0 * p0.x - 5.0 * p1.x + 4 * p2.x - p3.x ) * t2 +_
		( -p0.x + 3.0 * p1.x - 3.0 * p2.x + p3.x ) * t3 )
	catmull_point.y = 0.5 * ( ( 2.0 * p1.y ) +_
		( -p0.y + p2.y ) * t +_
		( 2.0 * p0.y - 5.0 * p1.y + 4 * p2.y - p3.y ) * t2 +_
		( -p0.y + 3.0 * p1.y - 3.0 * p2.y + p3.y ) * t3 )
    
    return catmull_point
    
end function


function cosine_spline(byval p0 as TPoint, byval p1 as TPoint, byval t as single) as Tpoint

    dim as Tpoint cosine_point
    dim as single ft,f        
    ft = t * 3.1415927
    f = (1 - cos(ft)) * 0.5
    
    cosine_point.x =  p0.x *(1-f) + p1.x *f
    cosine_point.y =  p0.y *(1-f) + p1.y *f
    	
    return cosine_point
    
end function


function bezier(byval p0 as TPoint, byval p1 as TPoint, byval p2 as TPoint, byval p3 as TPoint, byval t as single) as Tpoint
    
    dim as Tpoint bez
    dim as single b
    
    'A = p1
    'B = p0
    'C = p3
    'D = p2
           
    b = 1 - t
            
    bez.x = p1.x*b^3 + 3*p0.x*(b^2)*t + 3*p3.x*(b)*(t^2) + p2.x*(t^3)
    bez.y = p1.y*b^3 + 3*p0.y*(b^2)*t + 3*p3.y*(b)*(t^2) + p2.y*(t^3)

    return bez

  
    
end function




cls
screen 18

randomize timer


dim i as integer
dim p as Tpoint
dim p0 as Tpoint
dim p1 as Tpoint
dim p2 as Tpoint
dim p3 as Tpoint

p0.x = rnd * 640
p0.y = rnd * 480

p1.x = rnd * 640
p1.y = rnd * 480

p2.x = rnd * 640
p2.y = rnd * 480

p3.x = rnd * 640
p3.y = rnd * 480




do
    

circle (p0.x,p0.y), 5, 1
circle (p1.x,p1.y), 5, 2
circle (p2.x,p2.y), 5, 3
circle (p3.x,p3.y), 5, 4



for i = 0 to 100
    
    dim as single t
    t = i/100
    
    p = catmull_rom(p0,p1,p2,p3,t)
    
    if i = 0 then
        pset (p.x,p.y), 15
    else
        line -(p.x,p.y), 15
    end if
        
    sleep 1

next i


'' bezier
for i = 0 to 100
    
    dim as single t
    t = i/100
    
    
    p = bezier(p0,p1,p2,p3,t)
    if i = 0 then
        pset (p.x,p.y), 5
    else
        line -(p.x,p.y), 5
    end if
    
    sleep 1

next i



p0.x = -300 + rnd * 600
p0.y = -200 + rnd * 400

p1.x = p2.x
p1.y = p2.y

'p1.x = rnd * 640
'p1.y = rnd * 480


p2.x = rnd * 640
p2.y = rnd * 480


p3.x = -300 +  rnd * 600
p3.y = -200 +  rnd * 400



loop until inkey<>""




    
Post Reply