Skip to content

Instantly share code, notes, and snippets.

@Lyokolux
Created January 23, 2022 18:29
Show Gist options
  • Save Lyokolux/64def5f001237315a37fe160074a1fe8 to your computer and use it in GitHub Desktop.
Save Lyokolux/64def5f001237315a37fe160074a1fe8 to your computer and use it in GitHub Desktop.
Collision calculation for a ball on a curve. It finds the closest point to the ball on the curve and checks if there is a collision between between them.
public static double curveCollision(Vecteur ballPosition, double ballRadius, Vecteur vitesse, final Vecteur startPoint, final Vecteur controlPoint, final Vecteur endPoint) {
Vecteur closestPointToBall = getClosestPointToCubicBezier(
ballPosition, startPoint, controlPoint, endPoint
);
double distanceWithBall = Math.sqrt((ballPosition.x - closestPointToBall.x) * (ballPosition.x - closestPointToBall.x) + (ballPosition.y - closestPointToBall.y) * (ballPosition.y - closestPointToBall.y));
if (distanceWithBall > ballRadius + 10) {
return 0;
} else {
// why such points are colliding with the ball ??? Vecteur(48, 30)
Vecteur[] base = Geop.base( startPoint, endPoint);
Vecteur N = base[1];
double vN = vitesse.produitScalaire(N);
Vecteur deltaV = N.produit(-3*vN); // calcul du changement de trajectoire
vitesse.ajoute(deltaV); // la bille rebondit
return vN; // HERE WAS RETURN TRUE BEFORE
}
}
/** helper function for curveCollision() **/
private static Vecteur getClosestPointToCubicBezier(Vecteur base, Vecteur startPoint, Vecteur controlPoint, Vecteur endPoint) {
double curveDistanceEstimation = controlPoint.somme(startPoint).somme(endPoint).norme();
long slices = Math.round(curveDistanceEstimation * CURVE_PRECISION_COEF);
double tick = 1d / (double) slices;
double x;
double y;
double t;
Vecteur best = new Vecteur(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
double bestDistance = Double.POSITIVE_INFINITY;
double currentDistance;
for (int i = 0; i <= slices; i++) {
t = i * tick;
x = (1 - t) * (1 - t) * startPoint.x + 2 * (1 - t) * t * controlPoint.x + t * t * endPoint.x;
y = (1 - t) * (1 - t) * startPoint.y + 2 * (1 - t) * t * controlPoint.y + t * t * endPoint.y;
currentDistance = Math.sqrt((base.x-x)*(base.x-x) + (base.y-y)*(base.y-y));
if (currentDistance < bestDistance) {
bestDistance = currentDistance;
best.x = x;
best.y = y;
}
}
return best;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment