Skip to content

Instantly share code, notes, and snippets.

@HellGate94
Created October 21, 2017 11:05
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save HellGate94/3b3c4b0b26a9a467d5807be3af4a1a85 to your computer and use it in GitHub Desktop.
Save HellGate94/3b3c4b0b26a9a467d5807be3af4a1a85 to your computer and use it in GitHub Desktop.
public class Trajectory {
public class PredictionResult {
public bool InRange;
public Vector3[] ShotVelocity;
public float[] ShotImpactTime;
public Vector3[] ShotImpactLocation;
}
public static PredictionResult ShootAtTarget(Vector3 start, Vector3 target, Vector3 startVel, Vector3 targetVel, Vector3 bulletAccel, Vector3 targetAccel, float bulletSpeed) {
PredictionResult res = new PredictionResult();
Vector3 deltaPos = target - start;
Vector3 deltaVel = targetVel - startVel;
Vector3 deltaAccel = targetAccel - bulletAccel;
double[] impacts;
if (deltaAccel == Vector3.zero) {
double a = Vector3.Dot(deltaVel, deltaVel) - bulletSpeed * bulletSpeed;
double b = 2.0 * Vector3.Dot(deltaVel, deltaPos);
double c = Vector3.Dot(deltaPos, deltaPos);
impacts = Solver.SolveQuadric(a, b, c);
} else {
double a = Vector3.Dot(deltaAccel, deltaAccel) / 4.0;
double b = Vector3.Dot(deltaAccel, deltaVel);
double c = Vector3.Dot(deltaAccel, deltaPos) + Vector3.Dot(deltaVel, deltaVel) - bulletSpeed * bulletSpeed;
double d = 2.0 * Vector3.Dot(deltaVel, deltaPos);
double e = Vector3.Dot(deltaPos, deltaPos);
impacts = Solver.SolveQuartic(a, b, c, d, e);
}
if (impacts != null) {
Array.Sort(impacts);
int sol = 0;
for (int i = 0; i < impacts.Length; i++) {
if (impacts[i] > 0) {
sol++;
}
}
if (sol > 0) {
res.ShotImpactLocation = new Vector3[sol];
res.ShotImpactTime = new float[sol];
res.ShotVelocity = new Vector3[sol];
int answer = 0;
for (int i = 0; i < impacts.Length; i++) {
float imp = (float)impacts[i];
if (imp > 0) {
res.ShotImpactTime[answer] = imp;
Vector3 offsetHit = deltaPos + deltaVel * imp + (0.5f * targetAccel) * imp * imp;
res.ShotImpactLocation[answer] = start + offsetHit;
res.ShotVelocity[answer] = offsetHit / imp - (0.5f * bulletAccel) * imp;
answer++;
}
}
res.InRange = true;
} else {
res.InRange = false;
}
} else {
res.InRange = false;
}
return res;
}
}
@iluz0r
Copy link

iluz0r commented Oct 27, 2017

Shouldn't res.ShotImpactLocation[answer] be something like this?

res.ShotImpactLocation[answer] = start + startVel + offsetHit;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment