## Beziers versus catmull-rom splines

relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

### Beziers versus catmull-rom splines

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<>""