2017-01-22 2 views
1

Maintenant, je sais que des questions similaires ont été posées. Mais aucune des réponses ne m'a aidé à trouver le résultat dont j'ai besoin.Traitement: Distance d'intersection entre la ligne et le cercle

situation suivante:

Nous avons une ligne avec un, étant donné que lx, ly point d'origine (PO). Nous avons également un angle pour la ligne en ce qu'il sort PO, où 0 ° signifie horizontalement vers la droite, les degrés positifs dans le sens des aiguilles d'une montre. Le angle est dans [0;360[. De plus, nous avons la longueur de la ligne, car elle n'est pas infiniment longue, comme len.

Il existe également un cercle avec le point central donné (CP), donné cx, cy. Le rayon est donné comme cr.

J'ai maintenant besoin d'une fonction qui prend ces nombres comme paramètres et renvoie la distance de l'intersection la plus proche entre ligne et cercle au PO, ou -1 si aucune intersection n'apparaît.

Mon approche actuelle est suivante:

float getDistance(float lx, float ly, float angle, float len, float cx, float cy, float cr) { 
    float nlx = lx - cx; 
    float nly = ly - cy; 
    float m = tan(angle); 
    float b = (-lx) * m; 

    // a = m^2 + 1 
    // b = 2 * m * b 
    // c = b^2 - cr^2 
    float[] x_12 = quadraticFormula(sq(m) + 1, 2*m*b, sq(b) - sq(cr)); 

    // if no intersections 
    if (Float.isNaN(x_12[0]) && Float.isNaN(x_12[1])) 
    return -1; 

    float distance; 
    if (Float.isNaN(x_12[0])) { 
    distance = (x_12[1] - nlx)/cos(angle); 
    } else { 
    distance = (x_12[0] - nlx)/cos(angle); 
    } 

    if (distance <= len) { 
    return distance; 
    } 

    return -1; 
} 

// solves for x 
float[] quadraticFormula(float a, float b, float c) { 
    float[] results = new float[2]; 
    results[0] = (-b + sqrt(sq(b) - 4 * a * c))/(2*a); 
    results[1] = (-b - sqrt(sq(b) - 4 * a * c))/(2*a); 
    return results; 
} 

Mais le résultat est pas souhaité. Parfois, je récupère une distance, mais c'est rarement correct, il n'y a même pas d'intersection. La plupart du temps, aucune intersection n'est renvoyée, bien qu'il devrait y en avoir une.

Toute aide serait grandement appréciée.

EDIT:

j'ai réussi à trouver la solution grâce à la réponse de Mbo. Voici le contenu de mon fini getDistance(...) -fonction - peut-être que quelqu'un peut être aidé par elle:

float nlx = lx - cx; 
float nly = ly - cy; 

float dx = cos(angle); 
float dy = sin(angle); 

float[] results = quadraticFormula(1, 2*(nlx*dx + nly*dy), sq(nlx)+sq(nly)-sq(cr)); 

float dist = -1; 

if (results[0] >= 0 && results[0] <= len) 
    dist = results[0]; 
if (results[1] >= 0 && results[1] <= len && results[1] < results[0]) 
    dist = results[1]; 

return dist; 

Répondre

3

Utilisation de votre nlx, eul, nous pouvons construire l'équation paramétrique du segment de droite

dx = Cos(angle) 
dy = Sin(Angle) 
x = nlx + t * dx 
y = nly + t * dy 

Condition d'intersection avec la circonférence:

(nlx + t * dx)^2 + (nly + t * dy)^2 = cr^2 
t^2 * (dx^2 + dy^2) + t * (2*nlx*dx + 2*nly*dy) + nlx^2+nly^2-cr^2 = 0 

nous avons donc équation du second degré pour le paramètre inconnu t avec 01.230.473 Résoudre l'équation quadratique, trouver si t se trouve dans l'intervalle 0..len.