处理:线与圆之间的交点距离

时间:2017-01-22 13:33:48

标签: geometry processing distance intersection equation

现在,我知道有类似的问题。但没有一个答案帮助我找到了我需要的结果。

以下情况:

我们有一条原点(PO),以lxly给出。我们还有一个angle行,它退出PO,其中0°表示水平向右,正度表示顺时针。 angle位于[0;360[。另外,我们有行的长度,因为它不是无限长,如len

还有一个给定中心点(CP)的圆圈,以cxcy给出。半径为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;

1 个答案:

答案 0 :(得分: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范围内。