Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Following is polar coordinate based aiming code in C++.</p> <p>To use with rectangular coordinates you would need to first convert the targets relative coordinate to angle/distance, and the targets x/y velocity to angle/speed.</p> <p>The "speed" input is the speed of the projectile. The units of the speed and targetSpeed are irrelevent, as only the ratio of the speeds are used in the calculation. The output is the angle the projectile should be fired at and the distance to the collision point.</p> <p>The algorithm is from source code available at <a href="http://www.turtlewar.org/" rel="nofollow noreferrer">http://www.turtlewar.org/</a> .</p> <pre><code> // C++ static const double pi = 3.14159265358979323846; inline double Sin(double a) { return sin(a*(pi/180)); } inline double Asin(double y) { return asin(y)*(180/pi); } bool/*ok*/ Rendezvous(double speed,double targetAngle,double targetRange, double targetDirection,double targetSpeed,double* courseAngle, double* courseRange) { // Use trig to calculate coordinate of future collision with target. // c // // B A // // a C b // // Known: // C = distance to target // b = direction of target travel, relative to it's coordinate // A/B = ratio of speed and target speed // // Use rule of sines to find unknowns. // sin(a)/A = sin(b)/B = sin(c)/C // // a = asin((A/B)*sin(b)) // c = 180-a-b // B = C*(sin(b)/sin(c)) bool ok = 0; double b = 180-(targetDirection-targetAngle); double A_div_B = targetSpeed/speed; double C = targetRange; double sin_b = Sin(b); double sin_a = A_div_B*sin_b; // If sin of a is greater than one it means a triangle cannot be // constructed with the given angles that have sides with the given // ratio. if(fabs(sin_a) &lt;= 1) { double a = Asin(sin_a); double c = 180-a-b; double sin_c = Sin(c); double B; if(fabs(sin_c) &gt; .0001) { B = C*(sin_b/sin_c); } else { // Sin of small angles approach zero causing overflow in // calculation. For nearly flat triangles just treat as // flat. B = C/(A_div_B+1); } // double A = C*(sin_a/sin_c); ok = 1; *courseAngle = targetAngle+a; *courseRange = B; } return ok; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload