making vector converge onto another

Started by
6 comments, last by kVandaele 18 years, 11 months ago
first paragraph: converge. I know not everyone's english is that good but titles are supposed to be short and descriptive... I had to look up myself if it really was the right word tho :) Merriam-Webster: 1 : to tend or move toward one point or one another : come together The use is in a 3d game in set in space (free movement, negligible gravity). The code put in is to deal with collisions (between 2 objects, like ships). It's nothing too complicated. There are 6 variables that matter here, m_fVel is the 'set' velocity (what the ship would like to be travelling at). m_fMoveVel is the 'moving' velocity, for now this changes with collisions, later on also used for if say player set to full speed, this would 'slowly' go to m_fVel. m_fAccel is how fast you can get from m_fMoveVel to m_fVel m_Pos is the 3d position m_Dir is the direction you want to be going in m_Move is your current direction, should become m_Dir over time there should also be some sort of 'm_fDir2MoveRotation' variable, i haven't gotten that far but if someone wants to put it in that would be very nice :) problem: the ships are shown for a frame (i can see them for a split second) then vanish (at the very least outside the camera distance which is 20,000.0f). Problem occured when i tried the improve my system, as per explained below explanation of code: the commented code works fine, but isn't right. What it does is make the vectors and velocity converge, but it does so in a circle where movement should be elliptical. example: if 2 ships are heading for a head-on collision, but say the left ship is a little above the right ship. They would hit, the left should would bounce left and up a bit, the right right and down a bit. But then when the left should be going a _little_ up and mostly left or right (eventually just right again no more up), it goes from left and up a bit in a perfect circle to just up to up right, to just right (just right is what you wanted, but that's not how you wanted to get there). What should have happened instead is it should have kept going a _little_ up, but less and less up, while it was going from fast left to slow left to no left-right to slow right to fast right. Also: i'm using absolute velocity (never negative) and multiplying m_Move by -1 to make it move backwards. I'm now starting to think it would probably be easier to just make velocity positive or negative (so if from -10 to 20, just add 30) and keep m_Move always in 'forward' direction.
void CFlightShip::UpdatePos(DWORD dwTimeElapsed){
/*	if(m_fMoveVel > m_fVel + 0.001f || m_fMoveVel < m_fVel - 0.001f){
		if(m_fMoveVel < m_fVel){
			if(m_fMoveVel < m_fVel + 0.050f)
				m_fMoveVel += 0.001f * (float)dwTimeElapsed;	// 1.0f / second
			else
				m_fMoveVel = m_fVel;
		}else{
			if(m_fMoveVel > m_fVel - 0.050f)
				m_fMoveVel -= 0.001f * (float)dwTimeElapsed;
			else
				m_fMoveVel = m_fVel;
		}
	}*/
//	New position = old position + (direction * distance moved)
	m_Pos = m_Pos + m_Move * ((float)dwTimeElapsed/1000.0f * m_fMoveVel);
//	m_Move = m_Move * (float)(1000-dwTimeElapsed) + m_Dir * (float)dwTimeElapsed;
//	D3DXVec3Normalize(&m_Move, &m_Move);
	D3DXVECTOR3 tempVec3 = m_fMoveVel * m_Move + 0.001f * (float)dwTimeElapsed * m_fAccel * m_fVel * (m_Dir-m_Move);
	m_fMoveVel = sqrtf(tempVec3.x*tempVec3.x + tempVec3.y*tempVec3.y + tempVec3.z*tempVec3.z); // length of tempVec3
	m_Move = tempVec3 / m_fMoveVel;	// cheap normalise
}


Also useful, how i handle collisions

		tempVec3 = Ship1Pos - Ship2Pos;
		// fTemp = distance^2; square root is CPU buster
		fTemp = tempVec3.x*tempVec3.x + tempVec3.y*tempVec3.y + tempVec3.z*tempVec3.z;
		// if (distance from thispos to checkpos < radius+radius
		if( fTemp < (fMaxThisRadius+fMaxCheckRadius)*(fMaxThisRadius+fMaxCheckRadius) ){
// distance between shields, always negative 
//(shields are 'in' each other when ships collide... which they just did)
			fTemp = sqrtf(fTemp) - (fMaxThisRadius + fMaxCheckRadius);	
			D3DXVec3Normalize(&tempVec3, &tempVec3);
			Ship1Pos += (tempVec3 * -1 * fTemp / 2);
			Ship2Pos += (tempVec3 * fTemp / 2);
			m_pFlightShips.at(dwShip1)->SetPos(Ship1Pos);
			m_pFlightShips.at(dwShip2)->SetPos(Ship2Pos);
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
			m_pFlightShips.at(dwShip1)->SetMove(tempVec3);
			m_pFlightShips.at(dwShip2)->SetMove(tempVec3 * -1.0f);
			fVel = m_pFlightShips.at(dwShip2)->GetMoveVel() * 0.40f + m_pFlightShips.at(dwShip1)->GetMoveVel() * 0.40f;
			m_pFlightShips.at(dwShip1)->SetMoveVel(fVel);
			m_pFlightShips.at(dwShip2)->SetMoveVel(fVel);

			// slows the whole thing quite a bit
			if(dwShip2<dwShip1 || !bCheckAll) CollisionDetect(dwShip2, bCheckAll);
		}


[Edited by - kVandaele on May 22, 2005 9:16:32 AM]
Advertisement
I have NO idea what you're trying to say here. You totally failed to explain what you're trying to achieve. What vectors do you want to converge? And what will the final effect of this converging be? Is it part of collision response, so you just want to know the new accelerations of two colliding objects, or what?
How does something converge in a circle? o_O
hmm i did sort of put it longwinded. Also, converge may be the wrong word since m_Dir stays static (does not change here, only m_Move).

before collision, m_Move = m_Dir and m_fMoveVel = m_fVel. When two ships collide, m_Move and m_fMoveVel are changed appropriately. Then, over time, m_Move becomes m_Dir and m_fMoveVel becomes m_fVel. m_Dir and m_fVel do not change in this scenario.

this is how something converges to in a circle:
D = dir, M = move, o = object (like a ship)(changes over time)1. D---o---M2. D---o        |       (backslashes are converted into tabs, sry)         |          |           M3. D---o       |       |       |       M4. D---o      /     /    /   M5. D=Mhere's what should happen:1. D---o---M2. D---o--M3. D---o-M4. D---oM5. D---o6. D--Mo7. D-M-o8. DM--o9. D=M


i hope i properly explained myself now...
Uhm, not really :)

Instead, try stating the problem, not involving your names of variables or anything like that, they tend to just mess things up.

State your problem along the lines of "I have two ships flying towards eachother. Upon collision, i want the ships to move in a blahblah fashion, according to the law of blehbleh".

You see, when i just see non-descriptional names of vectors, and is told that you want them to converge, that just makes me confused. To, you the result you want is obvious, but you've obviously spent quite some time thinking about it.
Explain the wanted behaviour, not your attempt at an algorithm.
What i want is when two objects (ellipsoids) collide, to have a realistic collision (with new direction vector and appropriately altered velocity). I believe i have correctly done this in the second piece of coding, so i don't need help with this.

What i do need help with is the following:
at this point the objects are moving in a direction and velocity different from the original. Through accelleration, that direction and velocity become the original (pre-collision) direction and velocity.

So, i have 2 (3D, normalised with the variable/velocity as length) vectors and 2 variables, namely:
pre-collision/wanted direction
actual direction
pre-collision/wanted velocity
actual velocity

the problem is getting from the vector/velocity from _right_ after the collision, in steps (frames) back to the pre-collision direction/velocity.

I'm afraid i don't know what law that would follow... I checked my code and algorithm several times and i couldn't find an error yet it must be a mathematical error or otherwise the ships wouldn't just vanish...

does this clarify my problem? (or did i pick the wrong forum... i figured since it was purely vector work this was the forum)
new dir after refelcting off a normal is

{ Where V is the Vel and N is the normal }

new Dir = V - ( 2 * V dot N ) * N
Ah, now i see. You want some sort of autocorrection of the velocity after the collision?
Well, what I'd do is i'd find the angular difference between the original velocityvector and the current one, and then simply interpolate between them over whatever time you want.
i think i've got it thanks :)

This topic is closed to new replies.

Advertisement