对于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);
}
答案 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)。在这些情况下,您需要使用不同的初始点启动该函数两次。
希望这有帮助。