[Solved]Friction?

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

[Solved]Friction?

Post by XianForce »

So I'm currently trying to set up motion in my game, but I'm having trouble implementing friction. I looked at this thread, and see two methods of implementing friction. But if you use the multiplicative method, the velocity never actually hits 0, which is the whole purpose of me implementing friction in the first place. Looking at the second one, I don't really understand some of it through the misspellings, so can someone explain that to me? Or perhaps some other method of implementing friction?

As of now, I have rigid bodies, which you can apply forces too. The rigid bodies have a mass, acceleration, velocity, and max speed.

And I understand that this resisting force can't actually be friction in a 2d game that doesn't have gravity... Considering you can't really calculate the normal force, right?
Last edited by XianForce on Mon Jun 06, 2011 11:15 am, edited 1 time in total.
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Friction?

Post by avansc »

Not entirely sure what you mean by friction. I am going to assume that you are neglecting "air" resistance, and you are talking about friction between rigid bodies.

Well this is a rather tricky thing to do.

First of all you need to understand that there is a difference between static and kinetic friction, and more importantly that static friction is always greater then kinetic friction.

To correctly calculate "friction" you have to know what you contact patch is. It how much surface area is in contact to provide the "friction forces" its rather complex and a bit above my head.

if you are just doing air resistance like dandy was you can simply do a multiplication of a friction scalar.but if you want to be physically correct the formula is

for low speeds
AirResistanceForce = -b*v

b = your scalar to linearly scale
v = velocity of object relative to fluid.

for high speeds
AirResistanceForce = -1/2*p*A*C*(v.v)*(v/|v|)

p = density of fluid
A = area of object
C = drag coef
v = vector of object velocity relative to fluid.

EDIT:

As for the not hitting 0 bit, you are doing something wrong then. if you do not have gravity, and you are scaling your velocity each iteration by the "air resistance" scalar, it will hit 0 eventually. But air resistance at low speeds wont really slow anythign down to a dead stop.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Friction?

Post by XianForce »

Well, I'm just trying to calculate a force that would gradually bring an object to a stop. When I look at the air resistance force, it doesn't seem like the velocity would ever reach 0... Looks like it'd be an asymptote?
User avatar
EccentricDuck
Chaos Rift Junior
Chaos Rift Junior
Posts: 305
Joined: Sun Feb 21, 2010 11:18 pm
Current Project: Isometric "2.5D" Airship Game
Favorite Gaming Platforms: PS2, SNES, GBA, PC
Programming Language of Choice: C#, Python, JScript
Location: Edmonton, Alberta

Re: Friction?

Post by EccentricDuck »

To get completely accurate friction the second equation avansc posted was spot on. A simpler (and less accurate) way that I used just uses the multiplicative method you mentioned. If you look at both equations though (the simplified low speed equation and the high speed equation) the force is directly proportional to the velocity of your object. For the high speed equation it's also proportional to the surface area and drag coefficients (which are typically constant).

For the purposes of a non-realistic simulation, you'd probably just fudge these numbers anyway. The multiplicative method just approximates this by multiplying your velocity by some constant that is slightly less than 1 and setting that value (or multiplying your velocity by a number slightly greater than 0 and subtracting that new value from your current velocity - same thing). Basically, I just end up using the simplified equation for low speeds that avansc posted except rather than resolving the resistance into a force and creating a negative acceleration relative to my velocity, I just applied the result directly. My way is simpler if you also disregard mass, which I did, although if you want to treat objects like they have a particular mass then you'd be best off resolving friction into a force since the resulting acceleration (opposite your velocity) is proportional to the mass of your object.

When I was playing around with flying in 3D I found that a drag coefficient of about 0.03 worked nicely. The game was running about 30-32 updates calls a second and it felt about right for what I was doing. I would just multiply my present velocity by 0.97 and set that value. To bring my ship to a stop I'd do a check to see if the velocity dropped below 0.01 (floating point value). If it did, I just set the velocity to 0. If you keep track of the value using integers it'll just automatically truncate the value to 0 for you.
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Friction?

Post by avansc »

XianForce wrote:Well, I'm just trying to calculate a force that would gradually bring an object to a stop. When I look at the air resistance force, it doesn't seem like the velocity would ever reach 0... Looks like it'd be an asymptote?
air_resistance(x) = x*0.9;

vel = 10;
//this happens each iteration
vel = air_resistance(vel); // vel = 9
vel = air_resistance(vel); // vel = 8.1
vel = air_resistance(vel); // vel = 7.29
vel = air_resistance(vel); // vel = 6.561

and so on, finally having its asymptote at 0.

**not sure this is correct math, but just showing that if you do it enough vel becomes 0**
limit vel=air_resistance(vel) = 0
x->inf


EDIT:

here is a simple opengl/glut program that should prove this to you incase you are still skeptical.
Image

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <GLUT/glut.h>

#define START_VEL 350

void drawString(int x, int y, const char *str)
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glRasterPos2i(x, y);
	
	for(int i=0, len=strlen(str); i<len; i++){
		if(str[i] == '\n'){
			y -= 16;
			glRasterPos2i(x, y);
		} else {
			glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, str[i]);
		}
	}
}

void draw_grid()
{
	char data[200];

	for(int a = 0;a <= START_VEL;a+=10)
	{
		glColor3f(0, 0.2, 0);
		glBegin(GL_LINES);
		glVertex2f(0, a);
		glVertex2f(START_VEL, a);
		glEnd();
		
		glBegin(GL_LINES);
		glVertex2f(a, 0);
		glVertex2f(a, START_VEL);
		glEnd();
		
		sprintf(data, "%d", a);
		if(a%20==0)
		{
			drawString(-20, a-5, data);
			drawString(a-5, -10, data);
		}
	}
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
	glPushMatrix();
	glScaled(1.5, 1.5, 1);
	glTranslated(50, 50, 0);
	
	draw_grid();
	
	glColor3f(0.7, 0.8, 1);
	glBegin(GL_LINE_STRIP);
	float vel = START_VEL;
	for(int x = 0;x < START_VEL;x++)
	{
		glVertex2d(x, vel);
		vel*=0.96; /// this is your "air resistance"
	}
	glEnd();
	glPopMatrix();
	
    glutSwapBuffers();
}

void reshape(int width, int height)
{
	glViewport(0, 0, width, height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
}

void idle(void)
{
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(START_VEL+300, START_VEL+300);
    
    glutCreateWindow("Damping");
    
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    
    glutMainLoop();
    return EXIT_SUCCESS;
}
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: Friction?

Post by XianForce »

Thank You :D! It works great :)
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: [Solved]Friction?

Post by Falco Girgis »

XianForce wrote:And I understand that this resisting force can't actually be friction in a 2d game that doesn't have gravity... Considering you can't really calculate the normal force, right?
Why do you say that? Normal is just referring to perpendicular. There are still perpendicular vectors in 2D...
XianForce wrote:But if you use the multiplicative method, the velocity never actually hits 0, which is the whole purpose of me implementing friction in the first place.
The correct technical term for that is "damping." A popular way to implement this is to check if the velocity is below a certain epsilon then "put the object to sleep" by setting its velocity vector equal to the zero vector, like EccentricDuck said.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: [Solved]Friction?

Post by XianForce »

GyroVorbis wrote:Why do you say that? Normal is just referring to perpendicular. There are still perpendicular vectors in 2D...
Well isn't the force of friction calculated by the coefficient of friction (be it static or kinetic) multiplied by the Normal force? And the normal force is the force holding the object up; Same magnitude as gravity, just opposite in direction? So if I don't have gravity, I don't know how to calculate a legitimate friction force :/. But then again, I only had a year of CP Physics as a Sophomore in high school, so my physics knowledge is a little lacking...

EDIT: But I suppose even in 2D, I could just add a mass attribute to objects, and bs some sort of gravitational force (which would be solely used to calculate friction), then multiply that by a coefficient, which would depend upon the "material" of the object. Didn't really think of doing that until just now...
GyroVorbis wrote:The correct technical term for that is "damping." A popular way to implement this is to check if the velocity is below a certain epsilon then "put the object to sleep" by setting its velocity vector equal to the zero vector, like EccentricDuck said.
That's what I ended up doing, and it works very well!
Post Reply