如何在代码中找到点与抛物线之间的距离

时间:2012-03-21 07:33:40

标签: c# c++ math hlsl calculus

对于DirectX像素着色器,我试图在抛物线上找到2d中任意点的最近点。

大量的谷歌搜索告诉我,这是一个常见的前微积分作业问题。不幸的是,数百个相关的答案都说“一旦你有这个等式,使用你的图形计算器的最小函数,它会告诉你答案是6。”

我承认我没有回忆过前微积分。我认识到我寻找的等式可能就在维基百科上,但我无法弄清楚如何将这些希腊符号转换为HLSL函数。 C,C ++,C#或任何其他语言的解决方案也将受到高度赞赏。

编辑:根据请求查看输入曲线的格式:

//Equation of parabola being y = ax^2 + bx + c
//p is the arbitrary point we're trying to find the closest point on the parabola for.
float2 GetClosestPointOnParabola(float a, float b, float c, float2 p)
{
    //Something involving the distance formula...
    //Something involving "minimization"...
    return float2(x, y);
} 

2 个答案:

答案 0 :(得分:3)

你可以利用这个:

Pmin = (xmin, ymin) ~ point on a parabola
P = (px, py) ~ point in 2d    
y = a*x^2 + bx + c ~ parabola

P(x) = (x-px)^2 + (y-py)^2 = (x-px)^2 + (a*x^2 + bx + c - py)^2

你需要计算P(x)导数,这并不困难。例如。 如果你得到:P(x) = x^4 + 4x^2 - 3x + 10衍生物将是:

P'(x) = 4x^3 + 8x - 3

我想你得到了如何计算。然后将P'(x)与零进行比较,以找到它与X轴交叉的位置。你从中找到了一个xmin,然后你得到了ymin:

y = a*x^2 + bx + c

就是这样。

答案 1 :(得分:0)

我假设你想要的是抛物线上距离飞机中另一个点最近的点。让我们假设抛物线是由y = a * x^2 + b * x + c给出的,并且你想找到它最接近点A的点(x a ,y a )。 / p>

我建议你使用hill climbing。它在具有对数复杂度的函数中找到局部最小值。我将编写示例c ++代码,假设有一个函数h(x),它计算从A到抛物线上x坐标等于x的点的距离。

double minDist() {
  const double epsylon = 1e-9; // used to avoid double prescision errors
  double current = 0.0;
  double step = 1e+6;
  while (step > 1e-5) { // change this with the accuracy you need
    double left_neighbour = current - step;
    double right_neighbour = current + step;
    double cval = h(current);
    double lval = h(left_neighbour);
    double rval = h(right_neighbour);
    if (cval < rval + epsylon && cval < lval + epsylon) {
      step *= 0.5;
      continue;
    }
    if (lval < rval) {
      current = left_neighbour;
    } else {
      current = right_neighbour;
    }
  }
  return current;
}

在大多数情况下,您将拥有一个本地最小值,这是您需要的答案,但也许有两种情况(我相信它们不能超过2)。在这些情况下,您需要使用不同的初始点启动该函数两次。

希望这有帮助。