Moving along a line

BlitzMax Forums/BlitzMax Beginners Area/Moving along a line

slenkar(Posted 2006) [#1]
Hi how do I move an image across a line?
e.g.

x1-10
y1-10

x2-40
y2-50


FlameDuck(Posted 2006) [#2]
Using linear interpolation and/or the bressenham line algorithm. (At work don't have example code - there are examples of both in the Code Archives however if I remember correctly).


sswift(Posted 2006) [#3]
		Function TweenLinear#(X1#, X2#, Tween#)
		
			Value# = X1# + (Tween# * (X2# - X1#))
			Return Value#
			
		End Function


Start tween at 0, and increase to 1 and the return value will go from X1 to X2.

(X2# - X1#) is the length of the line. Multiplying that by Tween# gives us how far to travel along the line from point 1. Adding that to X1# gives us the final position.

If you want to move in 2D, you just call that function once to calculate the X and once to calculate the Y.


Chris C(Posted 2006) [#4]
you can use atan to to find which direction to go in

given
x1,y1 x2,y2 movestep

ta=atan(y1-y2,x1-x2)
xstep=sin(ta)*movestep
ystep=cos(ta)*movestep


slenkar(Posted 2006) [#5]
thanks! the tween function worked


slenkar(Posted 2006) [#6]
For some reason the image stays 1 pixel behind the next set of co-ords until tween reaches 0.5.
Function TweenLinear#(X1#, X2#, Tween#)
		
			Value = Float(X1# + Float(Tween# * Float(X2# - X1#)))

			Return Value
			
End Function

Graphics 640,480,16,2
SetBuffer BackBuffer()


Function create_bloke(name$)
a=CreateImage(StringWidth (name),StringHeight(name))
SetBuffer ImageBuffer(a)
Text 0,0,name
SetBuffer BackBuffer()
Return a
End Function

Type bloke
Field x
Field y
Field speed#
Field tween#
Field image_handle
End Type

b.bloke=New bloke
b\image_handle=create_bloke("trev")
b\speed=.001
b\tween=0

Global destinationx=50
Global destinationy=50

While Not KeyDown(1)
Cls
For b.bloke=Each bloke
b\tween=Float(b\tween+b\speed)
b\x=tweenlinear(b\x,destinationx,b\tween)
b\y=tweenlinear(b\y,destinationy,b\tween)
DrawImage b\image_handle,b\x,b\y
If b\x=destinationx And b\y=destinationy
RuntimeError "arg"
EndIf
Next
Flip
Wend
End

speed has been tested with different values but a similar result happens with all values.


sswift(Posted 2006) [#7]
First of all, this is the Blitzmax forum, and that's regular Blitz code. :-)

Second, you're using the tween function incorrectly:
b\x=tweenlinear(b\x,destinationx,b\tween)

By passing b\x to the tween function, you are tweening between the current position of the object and the destination. That's not what you want to do.

You want to pass the starting position of the object and the ending position.

If you simply want to move an object towards a point, then you should do something entirely different:

; Calculate a normal (a line with a length of 1) which points towards the destination point from the current point.

Length# = Sqr((DestinationX#-CurrentX#)^2 + (DestinationY#-CurrentY#)^2)

; (DestinationX#-CurrentX#) and (DestinationY#-CurrentY#) is our vector, but we need it to have a length of 1, so we divide both axes by the vector's length.
Nx# = (DestinationX#-CurrentX#) / Length#
Ny# = (DestinationY#-CurrentY#) / Length#

; You do not need to calculate the above every frame if your destination point does not move.

; Calculate vector which points in a certain direction and had a length equal to our desired speed:

Vx# = Nx# * Speed#
Vx# = Nx# * Speed#

; Nor do you need to calculate this every frame if the speed does not change.


Now you just move your object like so:

b\x = b\x + Vx#
b\y = b\y + Vy#

Unless you're using frame timing so each frame can take a different amount of time to render in which case you would do this:

b\x = b\x + Vx#*SecondsPassed#
b\y = b\y + Vy#*SecondsPassed#


The only thing is that if you move an object like this, then you can't simply check to see if it is at the right position each frame, because it could skip right over that position. Instead you'll have to check whether the X and Y component are now greater than or less than the desired position depending on which direction you're moving, (the sign of Vx# and Vy# tell you which direction you are moving) and then snap the object to the desired resting point if it has gone beyond these points.