问题
I am trying to find the closest point on a parabola to an arbitrary point in 2d, for a DirectX pixel shader.
A great amount of googling has revealed to me that this is a common pre-calculus homework problem. Unfortunately, the hundreds of relevant answers all say things like "Once you have this equation, use your graphing calculator's minimum function and it will tell you the answer is 6."
I confess that I recall nothing of pre-calculus. I recognize that the equation I seek is probably sitting right there on wikipedia, but I can't figure out how to convert these greek symbols into an HLSL function. A solution in C, C++, C#, or any other language would also be greatly appreciated.
edit: Per a request to see the format of the input curve:
//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);
}
回答1:
You could make use of this:
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
You need to calculate the P(x) derivative, it's not that difficult. E.g.
If you get: P(x) = x^4 + 4x^2 - 3x + 10
the derivative would be:
P'(x) = 4x^3 + 8x - 3
I think you get how to calculate that. Then compare P'(x) to zero to find where it crossess an X-axis. You find an xmin from that and then you have ymin from:
y = a*x^2 + bx + c
That's it.
回答2:
I assume what you want is the point on a parabola that is closest to another point in the plane. Let's assume the parabola is given by y = a * x^2 + b * x + c
and that you want to find the point on it closest to the point A(xa, ya).
I would propose you use hill climbing. It finds a local minimum in a function with a logarithmic complexity. I will write example c++ code assuming there is a function h(x) that calculates the distance from A to the point with the point with x coordinate equal to x on the parabola.
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;
}
In most case you will have a single local mimimum that is the answer you need, but maybe there are cases where you have two(I believe they can not be more then 2). In these cases you need to start the function twice with different initial points.
Hope this helps.
来源:https://stackoverflow.com/questions/9800324/how-to-find-the-distance-between-a-point-and-a-parabola-in-code