Created
January 23, 2022 18:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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