Simple math/geometry problem

Started by InCreator, Mon 19/07/2010 19:38:45

Previous topic - Next topic

InCreator

Imagine our galaxy as 2D plane. Say, in a computer game.

Sun is in the middle.
Planet needs to move towards sun from random starting point. No physics involved...


How do I find exactly how much planet needs to move both on X and Y axis to go directly towards sun? Point is in that planet could be placed at random point when starting.
Sounds like junior geometry exercise, but I'm totally blocked!

Basically, planets were example. I'm actually making top-view rain and need to calculate each raindrop so they'd move towards center of the screen.

Calin Leafshade


Code: ags

Sun.x = 160;
Sun.y = 120;

Planet.x = Random(320);
Planet.y = Random(240);

float PlanetXFromSun = IntToFloat(Sun.x - Planet.x);
float PlanetYFromSun = IntToFloat(Sun.y - Planet.y);

//so if you want it to take 40 game loops to get there just divide each value by 40 and thats the amount you need to move each loop
//but you really need to do it as floats to keep it accurate

float XPerLoop = PlanetXFromSun / 40.0;
float YPerLoop = PlanetYFromSun / 40.0;


InCreator


Calin Leafshade

Quote

so if you want it to take 40 game loops to get there just divide each value by 40

the 40 is the number of loops you want it to take to get there..

since PlanetXFromSun is the distance between the planet and the sun you need to divide that value by the number of loops you want it to take..

for example

if the sun were 10 pixels from the planet and i wanted the planet to take 5 loops to get there i would have to divide the 10 pixels by 5.. so it would move 2 pixels each loop.


InCreator

Ok, got it. For me, 40 = particle life

and after some mess of a script, it worked! Thanks

Stupot

Oooh, a Maths debate!  ;D

[Edit]
Yes, I'm 27...
MAGGIES 2024
Voting is over  |  Play the games

paolo

#6
Calin's code is fine except that the raindrops move the same amount each loop. If you want a perspective effect (in other words, the drops move fast when they're far from the sun and slower the closer they get), then you could try something like the following:

Use the same code as Calin has written, but change the last too lines to something like:

Code: ags

float XPerLoop = PlanetXFromSun / 5.0;
float YPerLoop = PlanetYFromSun / 5.0;


This will make the drops start off moving 8 times faster (= 40.0 / 5.0) than they currently do. (The value of 5.0 is just a suggestion - experiment to see what value gives best results, but make sure it is greater than 1.0 or it won't work.)

Then, inside the loop where you animate the drops, add the following after you've moved the drops to their new positions:

Code: ags

XPerLoop = XPerLoop / 2.0;
YPerLoop = YPerLoop / 2.0;


This will move the drops a smaller and smaller distance each time, slowing them down. Dividing by 2.0 gives a perspective effect.

Note that Calin's code will make the raindrops reach the sun in 40 steps. The above changes mean that they will never reach the sun. You might therefore want to include a test for how close your raindrops are to the sun, and stop drawing them when they are close enough, by modifying your loop:

Code: ags

bool closeEnough = false;
float smallDistance = 0.5;    //stop when raindrops are this close to sun

while (!closeEnough)
{
    //code to update raindrops goes here

    float xDistanceToSun = raindrop.X - sun.X;
    float yDistanceToSun = raindrop.Y - sun.Y;

    if (xDistanceToSun < 0.0)
        xDistanceToSun = -xDistanceToSun;

    if (yDistanceToSun < 0.0)
        yDistanceToSun = -yDistanceToSun;

    if (xDistanceToSun < smallDistance || yDistanceToSun < smallDistance)
        closeEnough = true;
}


I haven't tried out any of this code, so I don't guarantee it works, but hopefully this is helpful and gives you the general idea.

Calin Leafshade

obviously if this were in an AGS game you couldnt really use a while statement unless you wanted it to be a blocking function (i.e with a Wait(1) in there)

you would check the condition in rep_ex

if(closeenough) {
etc
}

paolo

Quote from: Calin Leafshade on Tue 27/07/2010 00:10:12
obviously if this were in an AGS game you couldnt really use a while statement unless you wanted it to be a blocking function (i.e with a Wait(1) in there)

you would check the condition in rep_ex

if(closeenough) {
etc
}

Quite right... thanks Calin. I was thinking in plain old C++...

SMF spam blocked by CleanTalk