GMS 2 How can I orbit an object around another?

Sultown

Member
I'm trying to make a game similar to One More Line but I cannot think of a solution to making it so when I click a button, it latches on to the stationary object and revolves around it with a fixed radius.

I believe watching gameplay of or playing One More Line would help to understand my question. I'm doing this as programming practice by mimicking these styles of games.

Thanks :)
 

Sabnock

Member
i would do it using cos() && sin()

x = o_orbited_obj.x + radius * cos(angle);
y = o_orbited_obj.y + radius * sin(angle);

but there are other ways of doing it
 

NightFrost

Member
You could also use lengthdir_x and lengthdir_y but those are basically just wrappers for the above trigonometry math for those who haven't wrapped (ha ha) their heads around this use of trig yet.
 

Sabnock

Member
sorry, i should have mentioned that the "angle" is in radians but you can use dcos() and dsin() if you want to work with degrees

you might need to invert the sin() to get the desired result i.e -dsin(angle);
 

Joe Ellis

Member
I prefer using lengthdir_x & y, just cus I forget which axis cos and sin is for, but I also found that lengthdir is slightly faster than multiplying radius * cos\sin(angle), so that was a deal maker for me. It's the same with point_distance, and dot_product, they're about 3 times faster than doing them manually
 

Sabnock

Member
I prefer using lengthdir_x & y, just cus I forget which axis cos and sin is for, but I also found that lengthdir is slightly faster than multiplying radius * cos\sin(angle), so that was a deal maker for me. It's the same with point_distance, and dot_product, they're about 3 times faster than doing them manually
cos() deals with the x axis and sin() the y axis.

Lengthdir_x & y are perfectly legitimate ways of doing as well. not measured the speed of operation though. Are you able to put some figures to that?
 
Last edited:

Joe Ellis

Member
I just ran 3 different tests: but the results are actually quite different for each one so I can't be sure. Although 2/3 tests showed that the radius * dcos(angle) is slightly faster. Test 1 is the test I normally use, and that's the one where lengthdir is faster, but I think the other 2 tests are more accuate\reliable ways of testing, as they're not hindered by the script_execute

Code:
var start_time = get_timer(), reps = 0;

while get_timer() - start_time < 15000
{
script_execute(script, random(500), random(360))
++reps
}

if script = scr_lengthdir
{
total_reps_lengthdir = reps
average_reps_lengthdir = reps / ++num_steps_lengthdir
script = scr_dcos
}
else
{
script = scr_lengthdir
total_reps_dcos = reps
average_reps_dcos = reps / ++num_steps_dcos
}
Here the average amount of reps each can do per step was roughly:

lengthdir: 19200
dcos: 18700

Lengthdir can do around 500 more reps step than radius * dcos(angle) or dsin(angle).

Code:
var start_time = get_timer(), reps = 0, val;

if script = "lengthdir"
{
while get_timer() - start_time < 15000
{
val = lengthdir_x(random(500), random(360))
++reps
}
total_reps_lengthdir += reps
average_reps_lengthdir = total_reps_lengthdir / ++num_steps_lengthdir
script = "dcos"
}
else
{
while get_timer() - start_time < 15000
{
val = random(500) * dcos(random(360))
++reps
}
total_reps_dcos += reps
average_reps_dcos = total_reps_dcos / ++num_steps_dcos
script = "lengthdir"
}
Here the dcos method could do around 200 more reps per step on average

Code:
var start_time = get_timer(), reps = 0, val;

while get_timer() - start_time < 15000
{
val = lengthdir_x(random(500), random(360))
//val = random(500) * dcos(random(360))
++reps
}
total_reps += reps
average_reps = total_reps / ++num_steps
Here I switched between the two commenting and uncommenting each one, and here the dcos method could do around 150 more reps per step average.
 

Sabnock

Member
very nice.

What about just using sin() and cos() as dcos() and dsin() will have to convert degrees back to radians and back again to degrees at a guess?
 

Sabnock

Member
I just ran 3 different tests: but the results are actually quite different for each one so I can't be sure. Although 2/3 tests showed that the radius * dcos(angle) is slightly faster. Test 1 is the test I normally use, and that's the one where lengthdir is faster, but I think the other 2 tests are more accuate\reliable ways of testing, as they're not hindered by the script_execute
did you write this code yourself?
 

Joe Ellis

Member
Yeah, I've been using this way of speed testing for a few years now, I used to use: repeat(n) {script_execute(script)} and measure the average fps_real, then I thought of seeing how many times each operation could be run per step before lag occurs as I thought it would be more accurate, so I increased repeat "n" until the fps_real drops below 60, then I realized you can do this with the get_timer() function.

I just tested cos vs dcos, and lengthdir: (using test3 and left each one running for 1 minute)

reps in 1 minute:
cos: 99749843
dcos: 96483938
lengthdir_x: 96502303

average reps per second:
cos: 1662497
dcos: 1608065
lengthdir_x: 1608371

average reps per step:
cos: 27708
dcos: 26801
lengthdir_x: 26806

So there seems to be virtually no difference between lengthdir and dcos, but 900 extra reps per step with cos,
so I guess if you use the same angle over and over with dcos or lengthdir, pre calculating the radians for it could be alot quicker.
 
Top