Code Snippet: Launch velocity from target position and angle

Snippet

This is the first of hopefully many little coding snippets; pieces of code I feel may be useful to others. Most of the code will come from theRedEngine, the 3D Engine I’ve been working on for a few years now, so you may have to do a bit of ctrl-h’ing to format it appropriately. Many of the snippets will assume some formal knowledge and may require prerequisite functions. In general, these functions will be widely known but if you struggle please do contact me or use the comments. These snippets may be hot off the press (I.e. I’ve just implemented them), so could be subject to optimisation, cleaning-up and enhancements over time. I’ll try my best to reflect those changes here.

The first snippet is a handy function to set the launch velocity required to hit a target when firing at a specified angle (in degrees). The ‘tRE_CBody’ class contains members ‘m_vPosition’, which is the origin of the projectile, and ‘m_vVelocity’ which is the value we’re calculating. The only other input is gravity, which I’ve defaulted to 9.81f. This function accounts for vertical offsets too, i.e. the angle is relative to the vector between source and target positions:

// Set the velocity required to hit the specified target using the specified launch angle (degrees)
//
tRE_void tRE_CBody::SetLaunchVelocityToHit( const tRE_f32 kfAngle, const tRE_SVector3f& krvTarget, const tRE_f32 kfGravity )
{
	// Projectile velocity
	const tRE_SVector3f kvDifference = ( krvTarget - m_vPosition );
	const tRE_f32 kfDistance = kvDifference.Length();

	// Launch angle
	const tRE_f32 kfTheta = tRE_DegreesToRadians( kfAngle );

	// Determine slope distance (http://fact-archive.com/encyclopedia/Trajectory)
	const tRE_f32 kfFlatDistance = tRE_NMaths::Sqrt( ( kvDifference.X * kvDifference.X ) + ( kvDifference.Z * kvDifference.Z ) );
	const tRE_f32 kfSlopeAngle = tRE_NMaths::ATan( kvDifference.Y / kfFlatDistance );
	const tRE_f32 kfSlopeDistance = kfDistance / ( ( 1.0f - tRE_NMaths::Tan( kfTheta ) * tRE_NMaths::Tan( kfSlopeAngle ) ) / tRE_NMaths::Cos( kfSlopeAngle ) );

	// Required firing velocity
	const tRE_f32 kfRequiredSpeed = tRE_NMaths::Sqrt( ( kfSlopeDistance * kfGravity ) / tRE_NMaths::Sin( 2.0f * kfTheta ) );

	// Rotate launch angle
	tRE_SMatrix44 mTransform;
	mTransform.BuildLookAt( m_vPosition, krvTarget );

	tRE_SMatrix44 mRotate;
	mRotate.BuildRotate( tRE_SVector3f( -kfTheta, 0.0f, 0.0f ) );

	tRE_SMatrix44 mInverse( mTransform );
	mInverse.Invert();
	mInverse *= mRotate;
	mInverse *= mTransform;
	mTransform *= mInverse;

	// Set rotated launch angle/speed
	m_vVelocity = ( mTransform.GetForward() * kfRequiredSpeed );
}
Posted in Coding, Games, Snippet | Tagged , , | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

> Talk to me!

Twitter profile for Richard Turnbullwitter:
  • Attempting to load Twitter feed..
Facebook profile for Richard Turnbull LinkedIn profile for Richard Turnbull

> Tools

Share |

> Advert