2017-01-22 75 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。