Subscribe to Stuck in an Infiniteloop        RSS Feed
-----

Gravitational Effects on a Particle in 3D Space

Icon 2 Comments
Consider a point in 3D space, i.e. a 3D vector. We have x, y, and z coordinates, however for the purposes of the following snippet, it is easier to picture a 2D graph with X and Z axes since I won't be doing any changes on the Y value.

In a video game, collision detection is very important. In fact, it makes or breaks a game. You want that bad guy to die when you shoot him right? While this is the most intimate form of collision that gamers are familiar with, there are many others that one can explore. Today, that one is the affects of gravity on a particle with a certain velocity. We have a particle in space, apply some velocity to it, and then we see how gravity affects it. As long as the velocity is not parallel to gravity, we'll get a parabolic graph/curve each and every time (good to know).

The equation is: p(t) = pInit + vInit*(t-tInit) + (1/2)*gravity*(t-tInit)^2

Here is the function by itself (although it does have quite a few dependencies, since the computer doesn't know how to do scalar multiplication of a 3D vector by default):

// --Snippet focus -- 
void Vector::gravitationalAcceleration(Vector* vInit)
{
	//given the gravity vector Earth [0, 0, -9.81] and the particle initial position (the vector itself)
	// and the velocity desired we can calculate where it moves in 't' timesteps, a second for example
	//as long as the velocity is not parallel to the gravity, the result will be parabolic


		 //*************Equation*******************
		//  p(t) = pInit + vInit*(t-tInit) + (1/2)*gravity*(t-tInit)^2
		//****************************************
	//This example assumes a start time (tInit) of 0, so we begin with the position at t = 1

	cout << *vInit << endl;
	Vector* curPosition = new Vector();
	Vector* gravity = new Vector(0, 0, -9.81);
	for(int i = 1; i <= 10; i++) //10 moments in time
	{
		*curPosition = *this + vInit->scalarMultiplication(i);
		*curPosition = *curPosition + gravity->scalarMultiplication(0.5*(pow(i,2.0)));
		cout << *curPosition << endl;
	}

	delete curPosition, gravity;
}




We can track the location (or current position) of the particle at a certain time. In the following example I use time intervals of 1 (could be a second, etc... its not really relevant). We'll display the particle's position for 10 time intervals. The code is well commented around the featured function, it assumes you know about classes, overloaded operators, etc... If you have any questions, comments, suggestions, feel free to tell me! Here is the entire code with an example main():

#include <iostream>
#include <cmath>
using namespace std;

//A Vector class i made up for the purpose of other snippets, note the mutator/accessor functions
//Plus I overloaded the outstream so I can simply do cout << vectorObject
//Addition: overloaded = and + 
class Vector {
private:
	double x, y, z;
public:
	Vector()								{ x = y = z = 0; };
	Vector(double pX, double pY, double pZ)								{ x = pX; y = pY; z = pZ; };
	~Vector() {};
	void setX(double pX)							{ x = pX; };
	void setY(double pY)							{ y = pY; };
	void setZ(double pZ)							{ z = pZ; };
	double getX()								{ return x; };
	double getY()								{ return y; };
	double getZ()								{ return z; };
	Vector scalarMultiplication(double);
	void gravitationalAcceleration(Vector*);
	Vector operator+(Vector&);
	Vector operator=(Vector&);

	friend ostream& operator<< (ostream& os, Vector& vect)
	{
		os << "[" << vect.getX() << ", " << vect.getY() << ", " << 
			vect.getZ() << "]";
		return os;
	}

};

//--Example--
int main()
{
	Vector* curPosition = new Vector(0, 0, 400); //particle's current position in space
	Vector* velocity = new Vector(25, 0, 35); //the velocity of the particle

	curPosition->gravitationalAcceleration(velocity);//calculate a particle's motion

	delete curPosition, velocity;
	return 0;
}

Vector Vector::scalarMultiplication(double num)
{
	Vector temp;
	temp.setX(this->getX()*num);
	temp.setY(this->getY()*num);
	temp.setZ(this->getZ()*num);

	return temp;
}

// --Snippet focus -- 
void Vector::gravitationalAcceleration(Vector* vInit)
{
	//given the gravity vector Earth [0, 0, -9.81] and the particle initial position (the vector itself)
	// and the velocity desired we can calculate where it moves in 't' timesteps, a second for example
	//as long as the velocity is not parallel to the gravity, the result will be parabolic


		 //*************Equation*******************
		//  p(t) = pInit + vInit*(t-tInit) + (1/2)*gravity*(t-tInit)^2
		//****************************************
	//This example assumes a start time (tInit) of 0, so we begin with the position at t = 1

	cout << *vInit << endl;
	Vector* curPosition = new Vector();
	Vector* gravity = new Vector(0, 0, -9.81);
	for(int i = 1; i <= 10; i++) //10 moments in time
	{
		*curPosition = *this + vInit->scalarMultiplication(i);
		*curPosition = *curPosition + gravity->scalarMultiplication(0.5*(pow(i,2.0)));
		cout << *curPosition << endl;
	}

	delete curPosition, gravity;
}

Vector Vector::operator+(Vector& rhs)
{
	Vector temp;
	temp.setX(this->getX() + rhs.getX());
	temp.setY(this->getY() + rhs.getY());
	temp.setZ(this->getZ() + rhs.getZ());
	return temp;
}

Vector Vector::operator=(Vector& rhs)
{
	this->setX(rhs.getX());
	this->setY(rhs.getY());
	this->setZ(rhs.getZ());

	return *this;
}



Hope you found this both fun and interesting. Happy coding!

--KYA

2 Comments On This Entry

Page 1 of 1

polymath 

12 March 2009 - 11:44 AM
Aah. Parametric physics. You should add a function to add in trigonometry because if you are given an angle and velocity:

[theta] == angle
v == velocity
v(x) = v(xy)*sin([theta])
v(y) = v(xy)*sin([theta])

Isaac looked at the apple, and said, "minus one half ... g t squared!"
0

KYA 

12 March 2009 - 12:09 PM
Good idea. I know what I'm doing later today :)
0
Page 1 of 1

January 2022

S M T W T F S
      1
2345678
9101112131415
161718192021 22
23242526272829
3031     

Tags

    Recent Entries

    Recent Comments

    Search My Blog

    15 user(s) viewing

    15 Guests
    0 member(s)
    0 anonymous member(s)