Beziers are kinda sexier than Catmull Roms but Catmull's behavior are easy to predict(visualize) since they (catmulls) would follow a set of points while B-splines are vector based. Preferably just a single bezier to got through all the points.
What I'm trying to achieve is for a Bezier to follow the trajectory the catmull in this demo does.
Or I'm shooting myself in the knee for even attempting this?
FreeBasic code
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,,2
randomize timer
const as integer MAXPOINTS = 5
dim i as integer
dim points(0 to (MAXPOINTS-1)) as Tpoint
dim p as Tpoint
dim p0 as Tpoint
dim p1 as Tpoint
dim p2 as Tpoint
dim p3 as Tpoint
for i = 0 to MAXPOINTS-1
points(i).x = rnd * 640
points(i).y = rnd * 480
next i
'points(MAXPOINTS-1).x = points(0).x
'points(MAXPOINTS-1).y = points(0).y
dim current_color as integer
current_color = 2
dim index as integer
index = 0' maxpoints+1
do
locate 1,1
print index
for i = 0 to MAXPOINTS - 1
circle (points(i).x,points(i).y), 5, i+1
next i
p0.x = points(index).x
p0.y = points(index).y
p1.x = points((index + 1) mod MAXPOINTS).x
p1.y = points((index + 1) mod MAXPOINTS).y
p2.x = points((index + 2) mod MAXPOINTS).x
p2.y = points((index + 2) mod MAXPOINTS).y
p3.x = points((index + 3) mod MAXPOINTS).x
p3.y = points((index + 3) mod MAXPOINTS).y
for i = 0 to 99
dim as single t
t = i/100
p = catmull_rom(p0,p1,p2,p3,t)
if i = 0 then
pset (p.x,p.y), current_color
else
line -(p.x,p.y), current_color
end if
sleep 5
next i
index += 1
if index > MAXPOINTS-1 then
index = 0
current_color = 1 + (current_color + 1) and 15
end if
loop until inkey <> ""
Thanks!!!