Page 1 of 1

2D Rope Physics Example

Posted: August 19th, 2021, 3:04 am
by mzxtuelkl

2D Rope Physics Example

Username: mzxtuelkl
Project Title: 2D Rope Physics Example
Time to Complete: 2 weeks
SDK: Psy-Q
Genre: Example
Latest Release: Version 1.0
In Development: No
Initial Release Date: 18-AUGUST-2021
Last Date Updated: 31-AUGUST-2021
Controller: Digital
Players: 1
Memory Card: -
Languages: Eng
Region: -
Burn and Play: -
Executable Included: Yes
Source Included: Yes

Last month I was following NeHe's tutorial on how to do rope physics and it worked! In a nutshell, the rope is composed of 24 masses (the tutorial uses 80). Each pair of masses is connected via a spring, and we use Hooke's Law (F = -k * (x-d)) to determine the forces upon each spring. Note that we've written Hooke's Law in a way that only works in one dimension, so to expand into two dimensions we multiply the formula with a unit vector like so: (F = u * (-k * (x-d))).

We obtain the unit vector by first finding the difference of the two masses' positions connected to the spring. Store that into a VECTOR struct called "v". Next, find the length of "v" and store the result into an int called "r". Finally, divide each component of "v" by the length (r) and store it into the final unit vector called "u". More information can be found here. Here's some code:

Code: Select all

/* 
 * modified code snippet of spring_solve() from physics.c.
 * Note how 2^6 (and not 4096) == 1.0 here
 */
 
/* determine unit vector */
setVector(&u, 0, 0, 0);
setVector(&f, 0, 0, 0);

setVector(&v,	p_spring->p_mass1->pos.vx - p_spring->p_mass2->pos.vx,
		p_spring->p_mass1->pos.vy - p_spring->p_mass2->pos.vy,
		0);

r = psqrt(	((v.vx*v.vx)>>6) +
		((v.vy*v.vy)>>6) );

if( r != 0 )
{
	if( r>>6 != 0 )
	{
		setVector(&u,	v.vx / (r>>6),
				v.vy / (r>>6),
				0);
	}
}
From there just apply all the other forces you want: gravitational force, friction force, forces from other objects, etc..

I've made it so that all physics calculations use 2^6 format (64 == 1.0) instead of 2^12 (4096 == 1.0), which allows a far greater range when doing certain operations (such as squaring numbers). This also means that I had to write a few custom math routines to accommodate 2^6 format in pfixed.c. If you decide to play around with the rope values, there's a chance that the rope may go haywire since my iffy handling of fixed-point arithmetic in the physics functions can sometimes fail to produce fractional values under certain conditions.. at least that's what I think is happening. I've had to do some dumb stuff like doubling the amount of gravity to get the rope to fall faster but ehhhh...

Image

EXE and Source Code: https://www.mediafire.com/file/ei8y4l0w ... pe.7z/file


Re: 2D Rope Physics Example

Posted: August 26th, 2021, 5:26 pm
by Shadow
That is extremely impressive. Very nice job :)