Author Topic: Is there a good way to make a Bezier spline act like a Catmull Rom Spline?  (Read 3657 times)

0 Members and 1 Guest are viewing this topic.

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
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
Code: [Select]

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


« Last Edit: January 16, 2009 by relsoft »
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Hey Rel, you're a maths professor and I am not, but I'd stick to Catmul rom splines to be sure that it intersects the control points, unless you're trying to do this as a mathematical excercise.

I think it is going to be highly difficult to make a bezier behave like a catmul, although you do know that it's going to hit the start and end points so maybe you can connect several beziers and mess around with the control points to create some nice movements?

I atteched an exe of your nice catmul rom routine for peeps without FB to try it :)



Shockwave ^ Codigos
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Quote
What I'm trying to achieve is for a Bezier to follow the trajectory the catmull
But what's the benefit of bezier then?
If you just want more control over your catmull-path, you can simply specify tangents like eg. kochanek-bartels splines.

Quote
Preferably just a single bezier to got through all the points
So you want to calculate a set of (bezier-)points approximating a given curve?
Since the bezier is basically a polynomial, you can find a best-regression polynomial of given degree (cholesky decomposition) and solve the control-points from its' coefficients.
Challenge Trophies Won:

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
After hours of trying with disastrous results, I think I'll stick with multiple catmulls. :*(

I tried brute force, I tried DeCasteljau interpolation and the best result I got is still with Catmull roms. :*(
 :whack:

Hell fire: I don't know both (cholesky decomposition) and kochanek-bartels splines. You have a link to those?


[edit]
Ive just read kochanek-bartels splines and they seem to he Hermite based as is the Catmull and the sample curves they do wouldn't look good at all.

Cholesky decomposition seems to be hermite in nature too.


« Last Edit: January 16, 2009 by relsoft »
Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
I'm still not quite sure what you're trying to do or why you're trying it.
What I suggested was: get a couple of sample points from your catmull spline, calculate a regression polynomial through these samples and solve the bezier-controlpoints from the polynomial's equation.

Kochanek-Bartels is exactly the same as catmull-rom except that you can modify the orientation and weighting of the tangents (which makes the curve more flexible) - in catmull-rom they're fixed.
Cholesky solves a linear system of equations which you'll get for the regression polynomial.
Challenge Trophies Won: