Code archives/Algorithms/Smoothly moving object

This code has been declared by its author to be Public Domain code.

Download source code

Smoothly moving object by Matt Merkulov
(Posted 20 years ago)
From article: Cubic spline interpolation (rus)
;Object in 2D smoothly passing thru random set of points visiting them in certain time (dual cubic spline interpolation) by Matt Merkulov

SeedRnd MilliSecs ()

Const q=10

; As coordinates x and y are processed equally, files, where are created
; These coordinates and factors for functions on a current interval of time are stored(kept)
Dim ptc#(q+2,1)
Dim a#(1)
Dim b#(1)
Dim c#(1)
Dim d#(1)
; A file for time in which the object should visit(attend) the set point
Dim tim (q+2)
; A file of coordinates of object
Dim oc#(1)

Graphics 800,600
SetFont LoadFont ("Arial", 16)

x#=0
y#=300
Color 255,0,0
For n=1 To q
 x#=Rnd (50,750)
 y#=Rnd (50,550)
 ptc#(n, 0)=x#
 ptc#(n, 1)=y#
 tim (n)=t
 Oval x#-4, y#-4,9,9
 Text x#, y#+ 4, .001*t + "s", True
 t=t+Rand (1000,3000)
Next

; Values of parameters of extreme points for maintenance of cyclicity are set
For nn=0 To 1
 ptc#(0, nn)=ptc#(q, nn)
 ptc#(q+1, nn)=ptc#(1, nn)
 ptc#(q+2, nn)=ptc#(2, nn)
Next
tim (q+1)=t
tim (q+2)=t+tim (2)
tim (0)=tim (q)-t

Color 255,255,255
; We keep a background
i=CreateImage (800,600)
GrabImage i, 0,0
SetBuffer BackBuffer ()

; time counter it is established(installed) outside an interval of a cycle, that
; To calculate factors for an initial interval of time, having passed(having taken place) through a condition
t=t+1
n=q+1
Repeat
 If t> tim (n+1) Then
 n=n+1
 ; If number of unit has fallen outside the limits a file - return on unit 1, zeroing
 ; The counter of time
 If n> q Then
  n=1
  ms=0
  tbeg=MilliSecs ()
 End If
 For nn=0 To 1
  d#(nn)=ptc#(n, nn)
  c#(nn)=(ptc#(n+1, nn)-ptc#(n-1, nn)) / (tim (n+1)-tim (n-1))
  dy2#=(ptc#(n+2, nn)-ptc#(n, nn)) / (tim (n+2)-tim (n))
  x3#=tim (n+1)-tim (n)
  xx3#=x3#*x3#
  b#(nn)=(3*ptc#(n+1, nn)-dy2#*x3#-2*c#(nn)*x3#-3*d#(nn))/xx3#
  a#(nn)=(dy2#-2*b#(nn)*x3#-c#(nn)) / (3*xx3#)
 Next
 End If

 ; Calculation of coordinates of object
 For nn=0 To 1
 v#=t-tim (n)
 vv#=v#*v#
 oc#(nn)=a#(nn)*vv#*v#+ b#(nn)*vv#+ c#(nn)*v#+ d#(nn)
 Next

 ; Display of a background, object and current time
 DrawBlock i, 0,0
 Oval oc#(0)-9, oc#(1)-9,19,19
 Text 0,0, " Time: " + (.001*t) + "s"
 Flip

 t=MilliSecs ()-tbeg
Until KeyHit (1)

Comments

Naughty Alien
(Posted 20 years ago)
nice..3D version will be fine to o

impixi
(Posted 20 years ago)
Excellent.

impixi
(Posted 20 years ago)
Here's a BlitzMax port + modification, if anybody is interested:


SuperStrict

Graphics 1024, 768

SeedRnd MilliSecs()

Local Paths:TPath[] = createPaths(3)

While Not KeyHit(KEY_ESCAPE)

	If MouseHit(1) Or MouseHit(2)
		
		Paths = Null
		GCCollect
		
		Paths = createPaths(3)
	
	EndIf
	
	renderPaths Paths

Wend

End

Function createPaths:TPath[](qty:Int = 1)

	Local paths:TPath[] = New TPath[qty]

	For Local n:Int = 0 To paths.length - 1
	
		paths[n] = New TPath
		
		paths[n].init Rand(3, 10)
		paths[n].generateCoords
			
	Next

	Return paths

EndFunction

Function renderPaths(paths:TPath[])

	Cls

	SetColor 255, 255, 255
	DrawText "Click mouse button for a new set of paths.", 10, 10

	Local t:Int = MilliSecs()

	For Local p:TPath = EachIn paths
		p.process t
		p.render
	Next

	Flip True
	
EndFunction


'******** 


Type TPath

	Field Qty:Int

	Field Coords:TCoord[]
	
	Field CurrentPosition:TCoord
	Field TimeNow:Int

	'**** "Scratchpad" variables
	Field a:TCoord
	Field b:TCoord
	Field c:TCoord
	Field d:TCoord 
	Field n:Int 
	Field tbeg:Int
	'*****

	'**** For rendering only
	Field red:Byte
	Field green:Byte
	Field blue:Byte
	'****

	Method init(q:Int = 5)
	
		Qty = q
	
		Coords = New TCoord[Qty + 3]

		For Local n:Int = 0 To Coords.length - 1
			Coords[n] = TCoord.create()
		Next
	
		CurrentPosition = New TCoord
	
		a = New TCoord
		b = New TCoord
		c = New TCoord
		d = New TCoord
		n = Qty + 1
	
		red = Rand(128, 255)
		green = Rand(0, 255)
		blue = Rand(0, 255)
	
	EndMethod

	Method generateCoords()
	
		Local t:Int = 0

		For Local n:Int = 1 To Qty
			Coords[n].set Rnd(50, GraphicsWidth() - 50), Rnd(50, GraphicsHeight() - 50), t
			t :+ Rand(1000, 3000)
		Next
				
		Coords[0].set Coords[Qty].X, Coords[Qty].Y, Coords[Qty].Time - t
		Coords[Qty + 1].set Coords[1].X, Coords[1].Y, t
		Coords[Qty + 2].set Coords[2].X, Coords[2].Y, Coords[2].Time + t 
		
	EndMethod

	Method render()
	
		SetColor red, green, blue
		For Local n:Int = 1 To Qty
			DrawOval Coords[n].X - 4, Coords[n].Y - 4, 9, 9
			DrawText n, Coords[n].X, Coords[n].Y + 4
		Next

		DrawOval CurrentPosition.X - 9, CurrentPosition.Y - 9, 19, 19		
					
	EndMethod

	Method process(t:Int)

		TimeNow = t - tbeg

		If TimeNow > Coords[n+1].Time
			 
			n :+ 1
		
			If n > Qty 
	 			n = 1
  				tbeg = t
 			End If
					
			d.set Coords[n].X, Coords[n].Y
			c.set ((Coords[n+1].X - Coords[n-1].X) / (Coords[n+1].Time - Coords[n-1].Time)), ((Coords[n+1].Y - Coords[n-1].Y) / (Coords[n+1].Time - Coords[n-1].Time))
					
			Local dy2:TCoord = New TCoord
			dy2.set ((Coords[n+2].X - Coords[n].X) / (Coords[n+2].Time - Coords[n].Time)), ((Coords[n+2].Y - Coords[n].Y) / (Coords[n+2].Time - Coords[n].Time))
					
			Local x3# = Coords[n+1].Time - Coords[n].Time
	  		Local xx3# = x3# * x3#
		
			b.set ((3 * Coords[n+1].X - dy2.X * x3# - 2 * c.X * x3# - 3 * d.X) / xx3#), ((3 * Coords[n+1].Y - dy2.Y * x3# - 2 * c.Y * x3# - 3 * d.Y) / xx3#)
			a.set ((dy2.X - 2 * b.X * x3# - c.X) / (3 * xx3#)), ((dy2.Y - 2 * b.Y * x3# - c.Y) / (3 * xx3#))
		
 		End If

		Local v# = TimeNow - Coords[n].time
		Local vv# = v# * v#
		CurrentPosition.set (a.X * vv# * v# + b.X * vv# + c.X * v# + d.X), (a.Y * vv# * v# + b.Y * vv# + c.Y * v# + d.Y)

	EndMethod

EndType


Type TCoord

	Field X:Float
	Field Y:Float
	Field Time:Int

	Function create:TCoord(px:Float = 0.0, py:Float = 0.0, t:Int = 0.0)
	
		Local c:TCoord = New TCoord
		
		c.set px, py, t
		
		Return c
	
	EndFunction
	
	Method set(px:Float = 0.0, py:Float = 0.0, t:Int = 0.0)
	
		X = px
		Y = py
		Time = t
	
	EndMethod
		
EndType



Code Archives Forum