2017-03-16 2 views
1

J'utilise cette fonction de détection de collision pour déterminer A) si un segment de droite est en intersection avec un cercle, et B) jusqu'à quelle distance du segment de ligne cette collision se produit. Je ne suis pas très bon en maths donc ce n'est pas une fonction que j'ai écrite moi-même, et ça semble fonctionner correctement pour détecter une collision, mais quand j'arrive aux points d'interception, j'obtiens des valeurs que je ne m'y attendais pas. J'essaie d'obtenir la distance le long de la ligne où la collision se produit en pourcentage, par exemple si le segment de ligne est 100px long, et le cercle est en collision avec 50px sur la ligne, je veux que la fonction retourne 50px, à partir de laquelle je peux facilement calculer le pourcentage.Comment puis-je obtenir le pourcentage le long d'une ligne où une collision se produit?

function interceptOnCircle(p1, p2, c, r) { 
    console.log(arguments); 
    //p1 is the first line point 
    //p2 is the second line point 
    //c is the circle's center 
    //r is the circle's radius 
    var p3 = { 
    x: p1.x - c.x, 
    y: p1.y - c.y 
    }; //shifted line points 
    var p4 = { 
    x: p2.x - c.x, 
    y: p2.y - c.y 
    }; 
    var m = (p4.y - p3.y)/(p4.x - p3.x); //slope of the line 
    var b = p3.y - m * p3.x; //y-intercept of line 
    var underRadical = Math.pow(r, 2) * Math.pow(m, 2) + Math.pow(r, 2) - Math.pow(b, 2); //the value under the square root sign 
    if (underRadical < 0) { 
    //line completely missed 
    return false; 
    } else { 
    var t1 = (-m * b + Math.sqrt(underRadical))/(Math.pow(m, 2) + 1); //one of the intercept x's 
    var t2 = (-m * b - Math.sqrt(underRadical))/(Math.pow(m, 2) + 1); //other intercept's x 
    var i1 = { 
     x: t1 + c.x, 
     y: m * t1 + b + c.y 
    }; //intercept point 1 
    var i2 = { 
     x: t2 + c.x, 
     y: m * t2 + b + c.y 
    }; //intercept point 2 
    console.log('Collision points: [' + i1.x + ', ' + i1.y + '], [' + i2.x + ', ' + i2.y + ']') 
    var distance = Math.hypot(p1.x - i2.x, p1.y - i2.y); 
    return distance; 
    } 
} 

Pour une collision entre une ligne qui est 50px long, je reçois ce journal:

Collision points: [111.91311159515845, 90.88529912057992], [92.30169719247377, 112.87385466298396] 

avec var distance = Math.hypot(p1.x - i2.x, p1.y - i2.y); donne une valeur plus longue que la ligne elle-même. Je m'attendrais à ce que la valeur distance soit entre 0 et 50. Comment puis-je obtenir le pourcentage le long d'une ligne (à partir de p1) qu'une collision se produit?

Edit: juste pour vérifier les lignes que je teste sont la bonne longueur, je l'ai testé avec console.log(Math.hypot(p1.x - p2.x, p1.y - p2.y)); //returns 49

Répondre

0

Je pense que le problème peut être que vous n'êtes pas limiter vos solutions à ceux entre les deux points d'origine .

Vous calculez l'intersection avec la ligne donnée par y = mx + cm est le gradient calculé à partir des deux points et c est un point, mais c'est une ligne de longueur infinie, de sorte que vous pouvez obtenir en dehors des deux intersections d'origine points. Le plus simple serait de calculer le pourcentage selon les besoins, et de conclure que tout ce qui est inférieur à 0 ou supérieur à 100% n'est pas réellement une intersection valide avec le segment de droite entre les deux points.

var length = Math.hypot(p1.x - p2.x, p1.y - p2.y); 
    var distance1 = Math.hypot(p1.x - i2.x, p1.y - i2.y); 
    var distance2 = Math.hypot(p1.x - i1.x, p1.y - i1.y); 
    var lowerBounds = Math.min(distance1, distance2); 
    if (lowerBounds < length) { 
    return lowerBounds; 
    } else { 
    return false; 
    } 
+0

Merci. Travaillé: proposé une modification à votre réponse avec le code. –