2017-01-22 76 views
1

現在,我知道有類似的問題。但沒有任何答案幫助我找到我需要的結果。處理:線和圓的交點距離

以下情況:

我們給出lxly用點的原產地(PO)的線路。我們還有一條angle,因爲它退出PO,0°意味着水平向右,正向意味着順時針。 angle位於[0;360[。此外,我們有線的長度,因爲它不是無限長的,因爲len

還有一個圓的給定中心點(CP),給定爲cx,cy。半徑給出爲cr

我現在需要一個函數,它將這些數字作爲參數,並返回線和圓之間最接近的交點到PO的距離,如果沒有交點發生,則返回-1。

我目前的做法是如下:

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; 
} 

但結果並不如所願。有時我會得到一個返回的距離,但這很少是正確的,通常甚至不會出現交叉點。儘管應該有一個,但大多數時候沒有交點。

任何幫助將不勝感激。

編輯:

我設法找到解決辦法由於MBO的答案。這是我完成getDistance(...) - 函數的內容 - 也許有人可以通過它來幫助:

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; 

回答

3

使用您的NLX,唯一一句,我們可以建立線段的參數方程

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

條件與圓周的交點:

(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 

所以我們有未知參數t的二次方程

a = 1 
b = 2*(nlx*dx + nly*dy) 
c = nlx^2+nly^2-cr^2 

求解二次方程,找出t是否在範圍0..len。