• Advertisement
Sign in to follow this  

Speed Division Problem, Help Please.

Recommended Posts



void update()
{

	if (thrust)
	{
		dx += cos(angle*DEGTORAD)*.02;
		dy += sin(angle*DEGTORAD)*.02;
	}
	else
	{
		dx*=0.99;
		dy*=0.99;
	}

	int maxSpeed = 15;
	float speed = sqrt(dx*dx+dy*dy);

	if (speed>maxSpeed)
	{
		dx *= maxSpeed/speed;
		dy *= maxSpeed/speed;
	}

	x+=dx;
	y+=dy;

.
.
.

}

In the above code, why is maxSpeed being divided by the speed variable.  I'm stumped.

 

Thank you,

Josheir

Share this post


Link to post
Share on other sites
Advertisement

it caps the speed to maxSpeed.

basically it's a minor optimization instead of doing:

	float maxSpeed = 15.0f;
	float Len = sqrt(dx*dx+dy*dy);
	float Speed = min(Len, maxSpeed);
	dx = dx/Len*Speed;
	dy = dy/Len*Speed;
	

which normalizes the vector(this means the vector has a length of 1) then scaling to your desired speed, the above sidesteps that dy/Len*Speed to do dy *= maxSpeed/Len;  which is effectivly the same operation, but only done when your speed is actually higher instead of every frame.

if you don't understand what normalizing a vector means then i'd start with learning that, then things should become more clear.

Share this post


Link to post
Share on other sites

maxSpeed should be a float, not an int.

To unserstand the math, reduce it to 1D:

maxSpeed = 15

speed = 20

if (20>15)

{

factor = 15/20, so 0.75

speed * 0.75 = 15, so the max speed we want

}

That's easy. Do you understand the move from 2D to 1D here?

Share this post


Link to post
Share on other sites

It's been a long time...They're both helpful!

4 hours ago, Josheir said:

float speed = sqrt(dx*dx+dy*dy);

Now, I'm understanding that speed is the magnitude of the vector.  What I'm not understanding is how dx's and dy's time numerator is working.  

Thank you,

Josheir

Share this post


Link to post
Share on other sites

What we want is to set the magnitude to max speed, maybe altering the equation helps:

dx *= maxSpeed/speed;

new_dx = dx * maxSpeed / speed

new_dx = dx / speed * maxSpeed // note that speed is the current magnitude

so, first dividing by speed we set the magnitude of the vector to 1 (assuming we do it fot y as well)

Then by multiplying with maxSpeed the new magnitude becomes maxSpeed.

Share this post


Link to post
Share on other sites
On ‎12‎/‎15‎/‎2017 at 1:12 PM, Josheir said:

float speed = sqrt(dx*dx+dy*dy);

A quick question:  how is speed achieved from the sqrt(... )?  Speed is distance over time and I am failing to understand if dx and dy are distance over time too?

Thank you,

Josheir

 

EDIT: perhaps the time is one second and the :   dx += cos(angle*DEGTORAD)*.02

is adjusting the dx by the decimal multiplication.

Edited by Josheir

Share this post


Link to post
Share on other sites
1 hour ago, Josheir said:

A quick question:  how is speed achieved from the sqrt(... )?  Speed is distance over time and I am failing to understand if dx and dy are distance over time too?

 

dx and dy are the x and y components of the velocity vector, so they are in terms of "distance/time" along the x and y basis of the coordinate frame.   The code uses the Pythagorean Theorem to calculate the length of that vector, i.e. the speed.  Dividing by the speed at the end normalized the vector to length 1.0, and then multiplying by maxSpeed sets the speed to that while keeping the direction.

Share this post


Link to post
Share on other sites

That's pretty much the 'dimension reduction' i meant earlier what you ask for.

 

First let's look at this:

x = cos(angle);

y = sin(angle);

Depending on angle we always get a point with a distance of exactly 1 from the origin at (0,0).

(If we do it for every angle and plot each point, we get the unit circle with example points (0,1), (1,0), (0.7*0.7), (-1,0) etc. - Every possible direction, but each at a distance of one)

 

x = cos(angle) * 5;

y = sin(angle) * 5;

 

So if we multiply both dimensions with a constant (5), the resulting length of the vector becomes 5 as well, but how to calculate this if we don't know neither length nor angle?

Imagine a line from origin (0,0) to a given point (3,5). We want to know the length of that line. Note the right angled triangle we get if we set one dimension to zero, e.g.: (3,5) (3,0) (5,0). We get side lengths of the right angled sides of a:3 and b:5.

Now we can use Pythagoras right angled triangle rule applied to get the length if that vector.

a*a + b*b = c*c  // c is the non right angled side we want to calculate

sqrt (a*a + b*b) = c

sqrt (3*3 +5*5) = 5.83 

Note that a negative length of -3 would result in the same: (-3*-3 + 5*5) == (3*3 + 5*5). Signs get canceled out by multiplication with itself. So it does not matter what direction the vector points, to the negative or positive sides of our coordinate system, we get the correct length anyways.

 

This is what you see in that line:

speed = sqrt(x*x+y*y)

 

Here, we do not care which direction the 2D vector (x,y) points or in what direction an example vehicle is driving, we only care about its 1D speed, and that's the length of it's 2D vector.

There are other possibilities of reduced dimensions, e.g. if we set each y (upwards) coord of a rotating 3D cube to zero and draw this in black, we get a shadow of the cube. What we do is projecting the cube to the 2D xz plane, which is different to the example above where we use lengths.

 

1 hour ago, Josheir said:

EDIT: perhaps the time is one second and the :   dx += cos(angle*DEGTORAD)*.02

The context of the given code is not clear, it seems dx,dy means acceleration, but i'm not sure what's the timestep etc.

Here is a example for simple physics of an object under constant external force like gravity to introduce some better terminology:

 

vec2 p(0,-8); // position
vec2 v(1,0.1); // velocity
vec2 a(0,0.2); // acceleration (we keep this constant like gravity)
float timestep = 0.16;

for (float time = 0; time < 20.0; time += timestep) // do a number of integration steps
{
v += a * timestep; // update velocity with acceleration
p += v * timestep; // update position with velocity
PlotPoint (p);
}

The plot should show a hyperbolic trajectory like we see when throwing a stone.

Games like Super Mario use this kind of physics, while games like Pac Man don't use acceleration and objects just use (mostly constant) velocity.

(You could rewrite this code using float pX=0, pY=-8; etc. instead vec2 p(0,-8);)

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites
On ‎12‎/‎21‎/‎2017 at 4:36 PM, JoeJ said:

p += v * timestep; // update position with velocity

How is this done, please?

Sincerely,

Josheir

Share this post


Link to post
Share on other sites
46 minutes ago, Josheir said:

How is this done, please?

Sincerely,

Josheir

With position p and velocity v being vectors, this is just simple vector math. I would recommend reading up on vectors and vector math if this is unknown territory for you currently.

If timestep is a float, v * timestep is just a scalar multiplcation of the vector -- scaling all components of the vector by the same amount.

v * timestep is the same as "delta offset this timestep" (and the result of this is a vector). This resultant vector can then be added onto p to change the position.

Share this post


Link to post
Share on other sites

If you're more visual of a learner Jorge Rodriguez on YouTube is a good instructor on the subject of vector maths (along with a ton of other subjects once you've learned the basics, he even covers character movements in 2D and 3D):

 

Share this post


Link to post
Share on other sites
22 minutes ago, Josheir said:

How is this done, please?

Probably you need to refine your question, do you mean how to do it in 2D without a vec2 struct? That would be simply:

vx += ax * timestep; vy += ay * timestep;

px += vx * timestep; py += vy * timestep;

Or is it a question about physics? I'd say that ignoring air resistance and external forces like gravity a body travels at constant velocity.

If we add constant external force like gravity or a thruster, this force creates acceleration that increases velocity over time. 

Note how the linear increasing velocity causes squared increase of position. If we plot numbers, we get something like

velocity  /  position

10              1

20              2

30              5

40              18

This is because timestep is a factor for both velocity and position, so we get a quadratic equation of motion.

For the simple case of constant acceleration, we could use a exact analytic solution for our example:

position_after_time = initial_position + 0.5 * constant_acceleration * time*time; // assuming initial velocity is zero

With this equation you get position at any time without the need to do many integration iterations using small timestep as above.

Unfortunately this rarely works in practice as many forces may affect a body at any time (collisions, thrusters, bullet hit etc), so we use integration instead which is only an approximisation but good enough if we are careful. (careful means using small timesteps to keep error small as well.)

But the analytic equation can answer difficult questions like: How long does it take until a falling stone hits the ground, or at what angle and velocity do i need to launch a projectile to hit a distant target under natural trajectory.

 

However, notice that squared time appearing in both methods. If we choose a timestep of 1, 1*1 is still 1 so this is a common source of mistakes and confusion if you try to learn this stuff with little math background. Looking at your code snippet i guess you're on your way to pitfalls like that. I'm self taught as well and i remember... :) So using established terminology helps to communicate and using correct math helps to understand. (But realistic physics might not be what you want for your current game.)

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By mister345
      Hi guys, so I have about 200 files isolated in their own folder [physics code] in my Visual Studio project that I never touch. They might as well be a separate library, I just keep em as source files in case I need to look at them or step through them, but I will never actually edit them, so there's no need to ever build them.
      However, when I need to rebuild the entire solution because I changed the other files, all of these 200 files get rebuilt too and it takes a really long time.
      If I click on their properties -> exclude from build, then rebuild, it's no good because then all the previous built objects get deleted automatically, so the build will fail.
      So how do I make the built versions of the 200+ files in the physics directory stay where they are so I never have to rebuild them, but
      do a normal rebuild for everything else? Any easy answers to this? The simpler the better, as I am a noob at Visual Studio settings. Thanks.
    • By Snaked
      Im working in this project for 1 year .... mostly i develop a tool and databases for make the different maps and now i'm doing the client for play the game
      Tell me if you like it......
      this is a capture of how is viewing atm

       
       
      https://youtu.be/9251v4wDTQ0
    • By reenigne
      For those that don't know me. I am the individual who's two videos are listed here under setup for https://wiki.libsdl.org/Tutorials
      I also run grhmedia.com where I host the projects and code for the tutorials I have online.
      Recently, I received a notice from youtube they will be implementing their new policy in protecting video content as of which I won't be monetized till I meat there required number of viewers and views each month.

      Frankly, I'm pretty sick of youtube. I put up a video and someone else learns from it and puts up another video and because of the way youtube does their placement they end up with more views.
      Even guys that clearly post false information such as one individual who said GLEW 2.0 was broken because he didn't know how to compile it. He in short didn't know how to modify the script he used because he didn't understand make files and how the requirements of the compiler and library changes needed some different flags.

      At the end of the month when they implement this I will take down the content and host on my own server purely and it will be a paid system and or patreon. 

      I get my videos may be a bit dry, I generally figure people are there to learn how to do something and I rather not waste their time. 
      I used to also help people for free even those coming from the other videos. That won't be the case any more. I used to just take anyone emails and work with them my email is posted on the site.

      I don't expect to get the required number of subscribers in that time or increased views. Even if I did well it wouldn't take care of each reoccurring month.
      I figure this is simpler and I don't plan on putting some sort of exorbitant fee for a monthly subscription or the like.
      I was thinking on the lines of a few dollars 1,2, and 3 and the larger subscription gets you assistance with the content in the tutorials if needed that month.
      Maybe another fee if it is related but not directly in the content. 
      The fees would serve to cut down on the number of people who ask for help and maybe encourage some of the people to actually pay attention to what is said rather than do their own thing. That actually turns out to be 90% of the issues. I spent 6 hours helping one individual last week I must have asked him 20 times did you do exactly like I said in the video even pointed directly to the section. When he finally sent me a copy of the what he entered I knew then and there he had not. I circled it and I pointed out that wasn't what I said to do in the video. I didn't tell him what was wrong and how I knew that way he would go back and actually follow what it said to do. He then reported it worked. Yea, no kidding following directions works. But hey isn't alone and well its part of the learning process.

      So the point of this isn't to be a gripe session. I'm just looking for a bit of feed back. Do you think the fees are unreasonable?
      Should I keep the youtube channel and do just the fees with patreon or do you think locking the content to my site and require a subscription is an idea.

      I'm just looking at the fact it is unrealistic to think youtube/google will actually get stuff right or that youtube viewers will actually bother to start looking for more accurate videos. 
    • By mister345
      Hi, can someone please explain why this is giving an assertion EyePosition!=0 exception?
       
      _lightBufferVS->viewMatrix = DirectX::XMMatrixLookAtLH(XMLoadFloat3(&_lightBufferVS->position), XMLoadFloat3(&_lookAt), XMLoadFloat3(&up));
      It looks like DirectX doesnt want the 2nd parameter to be a zero vector in the assertion, but I passed in a zero vector with this exact same code in another program and it ran just fine. (Here is the version of the code that worked - note XMLoadFloat3(&m_lookAt) parameter value is (0,0,0) at runtime - I debugged it - but it throws no exceptions.
          m_viewMatrix = DirectX::XMMatrixLookAtLH(XMLoadFloat3(&m_position), XMLoadFloat3(&m_lookAt), XMLoadFloat3(&up)); Here is the repo for the broken code (See LightClass) https://github.com/mister51213/DirectX11Engine/blob/master/DirectX11Engine/LightClass.cpp
      and here is the repo with the alternative version of the code that is working with a value of (0,0,0) for the second parameter.
      https://github.com/mister51213/DX11Port_SoftShadows/blob/master/Engine/lightclass.cpp
    • By Rannion
      Hi, I am sending data to peers and those data need to be retreived from a scenegraph with a mutex to lock the data.
      The process of gathering the data is taking a bit less than a ms. I'm starting the thread every time I want to gather the data. If I'm running at 60 fps, I'm starting the thread 60 times per second so is that a performance or design problem?
      Would it be much better to have the thread always running and some kind of mechanism to ask him to perform the task whenever it's needed, so around 60 or 120fps?
      Also, does starting a thread creates some memory alloc/dealloc and then produce on the long run some kind of fragmentation?
      Thank you all.
  • Advertisement