Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Constant speed through a Catmullrom Vector path - Help needed!

Author
Message
PiaPoi
13
Years of Service
User Offline
Joined: 4th Dec 2012
Location:
Posted: 6th Mar 2014 03:05
I'm plotting the course of a ship (2D sprite), using the Catmullrom vector command to make a nice smooth course between waypoints.

How can I get it to move at a constant speed along the line drawn?


(sorry you just have to add something as "Sprite.bmp" 20x50 pixels).


My problem is getting the speed of the ship constant. Two complications:
(1) Because it moves proportionally between each point (0-1), it moves faster the closer together the points are. I try to resolve this by slowing it down by the same degree but it doesn't seem to work.

This is my main question!
(2) The Catmullrom spline distributes the points such that they bunch together around waypoints, and particularly tight corners, so even if my (1) solution worked, the speed would still fluctuate.

I'd be really grateful for anyone's help. Thank you
Le Verdier
14
Years of Service
User Offline
Joined: 10th Jan 2012
Location: In the mosh-pit
Posted: 7th Mar 2014 21:27 Edited at: 8th Mar 2014 11:36
here are my thoughts, this is partial thoughts I wrote quickly
so I hope that it won't be too much confusing...
the problem is : "we know the coords of a point on the curve, we want to find the next point at a given distance".(I'll call this "sampling distance")
There is no analytical solution for arbitrary curves. I would opt for a dichotomy search.


firstly, break the curve into segments. pre divide a part between two waypoints into 4 segments(maybe more). this to avoid some cases where the distance between end and start point are smaller than the sampling distance.


Type SplineSegment
WayPointIndex
DichLower#
DichUpper#
Depth
EndType

then we init search stack:




the algorithm would look like this:

currentwaypoint = SegStack(StackPtrI).WayPointIndex
init CMR vectors with waypoints


while segment not accepted
dec StackPtrI
if currentwaypoint ≠ SegStack(StackPtrI).WayPointIndex
init CMR vectors with waypoints
currentwaypoint = SegStack(StackPtrI).WayPointIndex
endif
calculate coords of curve at SegStack(StackPtrI).DichUpper#
distance between thispoint and startpoint
if thisdistance > samplingdistance

if thisdistance ≤ samplingdistancemax or depthmax reached
AcceptSegment = true
else
divide segment
endif
endif

endwhile

For the next frame:
startpoint = thispoint

...
finding the very exact distance is not always possible.. instead we accept
a value bounded between samplingdistance & samplingdistancemax

we define samplingdistancemax as: samplingdistance + a small value.
e.g samplingdistance + samplingdistance /(2^ depthmax)

we can compare squared distances. this avoids a unnecessary sqrt

No need large depth search. The dichotomy fills a bit in the the floating number at each iteration and these are limited to 23...

the divide segment code:



Voila!
It is not ready to run, but hope that helps..

PiaPoi
13
Years of Service
User Offline
Joined: 4th Dec 2012
Location:
Posted: 8th Mar 2014 03:46
Wow thanks, LV!

My programming knowledge is not sufficient to know immediately what you have in mind, but I'll do my best to work my way through your instructions and see what I can learn!

Is the idea that you sample loads of points along the spline, work out the actual distances between each, then altar the "speed" accordingly, such that it would go faster through the more densely packed points, and slower through the sparser points, giving the overall effect of a constant speed?

If not, I'll try to understand more by working through it!

Thank you again.
Le Verdier
14
Years of Service
User Offline
Joined: 10th Jan 2012
Location: In the mosh-pit
Posted: 8th Mar 2014 11:34 Edited at: 8th Mar 2014 11:35
Not really. We want to avoid computing a load of points. Only the less possible for required accuracy..
But before discussing I noticed there is something missing in your code

sync on : sync rate 0
...
Do
...
Sync
Loop


This implies to use a TBM
This topic has been recently discussed here
http://forum.thegamecreators.com/?m=forum_view&t=210153&b=6

When updating a position we use Pos=Pos+Velocity*ElapsedTime
or Pos=Pos+Speed*ElapsedTime in scalar form, Speed*ElapsedTime is the distance linearily travelled. linearily because this is not the length of the part of the curve..
We know the speed, the elapsed time, so the distance can be figured out for each frame..

Phaelax
DBPro Master
23
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 10th Mar 2014 03:24
I tried finding a solution to this same issue with beziers a long time ago, never really did find what I wanted. My method, though not very efficient, was to calculate the length of each line segment making up the curves. Sounds similar to what Verdier is suggesting, I'll have to look at his example.

Login to post a reply

Server time is: 2026-07-06 04:27:23
Your offset time is: 2026-07-06 04:27:23