Intuitive Math: Understanding The Triangles Behind Aiming Algorithms

Determining Aim with Trigonometry

The foundation of aim calculation in shooting games relies on basic trigonometric functions. By determining the angles and distances between the barrel of the gun to the target, we can use sine, cosine, and tangent functions to aim precisely. The key is translating the geometric relationship between barrel, target and the intervening space into numerical values that can adjust aim in code.

First, we construct a right triangle from the barrel of the gun to the target location. The space intervening forms the hypotenuse of the triangle with a length equal to the distance between barrel and target. We can determine the angles needed to rotate the barrel based on the ratio of the lengths of the opposite and adjacent legs of the triangle compared to the hypotenuse.

Triangles from Barrel to Target

Here is a diagram of the right triangle formed from the barrel to any target location in 2D space:

Right triangle diagram

As shown, the hypotenuse extends from the gun barrel origin to the target location. We define the triangle’s sides in relation to the angles as follows:

  • Hypotenuse – The distance between barrel and target
  • Adjacent – The side running parallel to the horizontal axis
  • Opposite – The side running parallel to the vertical axis

By using trigonometric ratios relating these triangle sides to angles, we can determine the necessary angle measures to point the gun precisely towards any target location.

Coding Sine, Cosine, and Tangent

The key trigonometric functions used in game aiming algorithms are sine, cosine, and tangent. These mathematical ratios relate the length of one side of our right triangle to one of the acute angles. Here is some sample code for implementing these core functions:


function sin(angle) {
  return opposite / hypotenuse;  
}

function cos(angle) {
  return adjacent / hypotenuse;
}  

function tan(angle) {
  return opposite / adjacent;
}

For any angle we need to calculate, plugging its trigonometric ratio values into these functions returns numbers that reveal the necessary right triangle side lengths to achieve that angle measure from the origin.

Translating Angles into Cursor Movement

By standardizing the hypotenuse length to 1 in our aiming system, the outputs of sine and cosine directly correspond to x and y cursor offsets. Here is sample code for mapping angle measures to cursor movements:


var targetX = Math.cos(angle);
var targetY = Math.sin(angle);

var cursorX += targetX * sensitivity;  
var cursorY += targetY * sensitivity;

This approach directly translates the angles calculated by our trig functions into movement of the aiming reticle matching that angle relative to the center origin. The sensitivity variable additionally allows us to scale the movement for finer control.

Accounting for Distance and Bullet Drop

So far we have only considered aiming horizontally in two dimensions. But we also need to consider the effects of gravity over longer distances. Projectiles arc downwards based on flight time, and targets may be positioned at different vertical elevations than the gun barrel height.

We can adjust our aim angle using the following variables:

  • Horizontal distance from barrel to target
  • Vertical delta between barrel height and target height
  • Projectile velocity and gravity constants

Arc height equations based on standard projectile motion physics give us the necessary vertical offset. From there we can use trigonometry again to calculate adjusted angles that will achieve an arcing ballistic trajectory to hit the designated location.


var theta = Math.atan((targetHeight - barrelHeight) / distance);
var xAngle = Math.cos(theta) * angle;
var yAngle = Math.sin(theta) * angle;

This computes the necessary angle adjustment theta by comparing heights over distance. We can then apply it to rotate our existing horizontal aim angle to compensate for bullet drop.

Implementing Predictive Aiming

When aiming at moving targets, leading the target can substantially improve accuracy. By prediciting where the target will be rather than where it currently is, our algorithms can automatically aim ahead to “lead” the target.

Here is sample code for a leading aim assist system:


var targetVelocity = collectVelocityVects(target);
var intercept = predictInterception(target, myBullet); 

var angle = calculateAimAngle(intercept);
moveCrosshair(angle);
fireBullet(angle); 

This acquires the target’s movement speed and trajectory, calculates an upcoming interception point for the projectile, then aims and fires at where that interception will occur. The result is effectively leading shots for moving targets.

Summary and Next Steps

In this article we covered core mathematical techniques for aiming systems:

  • Using trigonometric functions like sine, cosine, and tangent to translate locations into angles
  • Mapping those angles to cursor movement positions
  • Adjusting the angles for gravity over long distances
  • Leading moving targets with intercept predictions

With these foundations you can create advanced aiming behaviors in games. Some possible next topics include implementing acceleration, lag compensation, target prioritization, tracking flows, and other methods for taking gun dynamics from good to great.

Leave a Reply

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