smoothly interpolating positions/rotations -- hermite preferably..

Blitz3D Forums/Blitz3D Programming/smoothly interpolating positions/rotations -- hermite preferably..

DrakeX(Posted 2003) [#1]
OK i'm writing a sort of scripting thing for scripting camera movements and whatnot. however i don't want to use linear interpolation because it looks bad. very clunky.

what i have is a set of positions and a set of angles for each point (keyframes, really). but i have 2 problems:

1) i need to use hermite interpolation to calculate the path. i used DBP's built-in 3d math commands to do this before, and found that hermite interpolation gave me the best-looking path, but BB doesn't have it as a command.. so i need some way to hermite interpolate stuff. anyone have any code? (i really can't look at sites with calculus on them and translate that into code.. especially since i'm only in geometry)

2) once i have the path... i need some way to make the camera follow it at a constant speed, as hermite creates a nice path -- but it speeds up and slows down. i've never been able to solve this and i did find a solution on some site after hours of searching but it was in calc and i didn't understand it at all.

i'd really like to know how to do this as it can be applied to a lot of stuff.


jhocking(Posted 2003) [#2]
I'ld be interested in this too. A code archives post of spline interpolation would be really useful.

Actually come to think of it there is a post of Bezier interpolation in the 3D Graphics section of the code archives. That may be what you need.


DrakeX(Posted 2003) [#3]
oh cool :) it's very easy to use too, not too much setup.

now all i need is a way to make it a constant speed...


ashmantle(Posted 2003) [#4]
I think the speed is somewhat controlled by the space between each point along the curve..
if you have a big space, you have fewer points and a faster movement.

kinda like this:
x..........x ;slow
x._._._._._._._._._.x ;faster
x.__.__.__.__.__.__.__.__.__.x ;warp speed


Algo(Posted 2003) [#5]
In the AGore 3D sample folder there's some code and demos that use hermite interpolation.

There's also some info about maintaining a constant speed at:
http://www.cubic.org/~submissive/sourcerer/hermite.htm#ma1


DrakeX(Posted 2003) [#6]
tore -- you're absolutely right and that's what i'm trying to circumvent.

ALG -- lol you've found the site that i was talking about! thanks, i've now gone full circle with this thing.

i think i'll have another shot at this site. good thing you found it :)


Binary_Moon(Posted 2003) [#7]
drake - This is the code you found (in the archives) yeah?

http://www.blitzbasic.com/codearcs/codearcs.php?code=651

To make this a constant speed is easy. Since its already a constant speed. the line is 1 unit long (0 being the start, 1 being the end) so you just use a constant value to get the position of the camera (the same way the points are drawn.

 st#=0.01
 mu=0.0

 Repeat

  Bezier4 p,ve(0),ve(1),ve(2),ve(3),mu ;Only 4 Points

  ;Bezier p,mu  ;All Points

  Plot3D p

  mu=mu+st
  If mu>1.0 Then Exit
 Forever


stu is the step unit so you just increase or decrease that value to speed up or slow down the camera position


Binary_Moon(Posted 2003) [#8]
BTW I think a better example of the code above is to swap
PositionEntity camp,0,0,-200

for
MoveEntity cam,0,0,-200

and add
TurnEntity camp,0,.5,0

before the flip in the main loop. Lets you see the line in 3d.


DrakeX(Posted 2003) [#9]
binary moon -- no, that's not what i mean. if you look at the yellow dots being drawn, you'll notice that they are spaced further apart near V3 and are closer together near V0. i want to counteract this as to --

wait!

you're right

nevermind :)

i think i've got it now.

(i never did figure out that site anyway after 2 1/2 hours of trying ::) )


Binary_Moon(Posted 2003) [#10]
The reason they look closer at the start is because of the perspective (3d ness) of the dots being plotted in the render.


DrakeX(Posted 2003) [#11]
yep :) thank you for cluing me in about that, i'd still be trying to make my own functions if you hadn't..


DrakeX(Posted 2003) [#12]
hey i was wondering how it's possible to change how much each node affects the curve so that i can make the path go through each point.


Mathieu A(Posted 2003) [#13]
Hi Drake X!!

I'm made my own cinematic editor based on the work of A gore. It works with constant keyframe. I can change the focal of the camera.

I try to complete my editor to control TCB parameters and variable Keyframe.

I can't give you the code yet, because I'm not at home. But when I've got it I will send you if you want.

Take a look at my editor:

http://blitz.idigicon.com/project_detailb.asp?ProjectName=AD%20VITAM%20AETERNAM%20Editeur

it's old pictures. Today, my editor is much more completed.


giza(Posted 2003) [#14]
An example of Hermite splines

Global gfxwidth=400
Global gfxheight=300

Global freq=10
Global amp=200


Global sType=1


SeedRnd MilliSecs()

Graphics gfxwidth,gfxheight,16,2
AppTitle "1D Interpolation - Keys 1-5 Change interpolation"


Dim point(freq,2)


For t=1 To freq
	point(t,1)=((gfxwidth/2)-150)+(300/freq)*t
	point(t,2)=(gfxheight/2+(amp/2))-Rand(0,amp)
Next


SetBuffer BackBuffer()

While Not KeyHit(1)
	Cls


	If KeyHit(2) sType=1
	If KeyHit(3) sType=2
	If KeyHit(4) sType=3
	If KeyHit(5) sType=4
	If KeyHit(6) sType=5

	DrawGraph()

	Color 255,255,255
	Text 0,0,"Freqency: "+freq
	Text 0,12,"Amplitude: "+amp

	Flip
Wend
End


Function DrawGraph()
	oldlx=point(1,1)
	oldly=point(1,2)
	For t=1 To freq-1

		For v=1 To 10

			If t-1<1
				oldy=point(t,2)
			Else	
				oldy=point(t-1,2)
			EndIf


			ay=point(t,2)
			by=point(t+1,2)


			If t+2>freq
				newy=point(t+1,2)
			Else
				newy=point(t+2,2)
			EndIf


			lx#=point(t,1)+((point(t+1,1)-point(t,1))/10.0)*v

			Select sType

			Case 1
				ly#=CosineInterpolate(ay,by,v/10.0)
				Color 255,255,255 Text 0,24,"Cosine Interpolation"

			Case 2
				ly#=LinearInterpolate(ay,by,v/10.0)
				Color 255,255,255 Text 0,24,"Linear Interpolation"

			Case 3
				ly#=CubicInterpolate(oldy,ay,by,newy,v/10.0)
				Color 255,255,255 Text 0,24,"Cubic Interpolation"

			Case 4
				ly#=HermiteInterpolate(oldy,ay,by,newy,v/10.0)
				Color 255,255,255 Text 0,24,"Hermite Interpolation"

			Case 5
				ly#=HermiteInterpolate(0.5*(by-oldy),ay,by,0.5*(newy-ay),v/10.0)
				Color 255,255,255 Text 0,24,"Hermite Interpolation (Catmull-Rom splines)"

			End Select

			Color 255,0,0
			Line oldlx,oldly,lx,ly

			oldlx=lx
			oldly=ly

		Next

		Color 0,255,0
		Rect point(t,1)-1,point(t,2)-1,3,3

	Next
	Rect point(freq,1)-1,point(freq,2)-1,3,3

End Function


Function CubicInterpolate#(v0#,v1#,v2#,v3#,x#)
	p#=(v3-v2)-(v0-v1)
	q#=(v0-v1)-p
	r#=v2-v0
	s#=v1
	Return (P*(x^3))+(Q*(x^2))+(R*x)+S
End Function


Function HermiteInterpolate#(v0#,v1#,v2#,v3#,x#)
	p#=2*(x^3)-3*(x^2) + 1
	q#=-2*(x^3)+3*(x^2)
	r#=x^3-2*(x^2)+x
	s#=x^3-x^2
	Return p*v1+q*v2+r*v0+s*v3
End Function


Function CosineInterpolate#(a#,b#,x#)
	ft#=x#*180
	f#=(1-Cos(ft#))*0.5
	Return a#*(1.0-f#)+b#*f#
End Function


Function LinearInterpolate#(a#,b#,x#)
	Return a#+(b#-a#)*x#
End Function