Рассмотрим точку $%M(x_0, y_0)$% и произвольную функцию $%y = f(x)$%. Тогда назовем расстоянием от точки $%M$% до функции $%y=f(x)$% некоторый отрезок $%MK$%, где $%K = (x_1, f(x_1))$%. Наименьшим расстоянием — такое расстояние, для которого $%|MK|$% наименьший. Тогда, если мы хотим минимизировать $%|MK|$%, мы можем минимизировать $%p = |MK|^2 = (x_1 — x_0)^2 + (f(x_1) — y_0)^2$%. Это несложно сделать, просто взяв производную и найдя минимум данной функции, зависящей только от параметра $%x_1$%.
Покажу на примере:
$%y = sqrt{x}$%, $%M(2;0)$%. Рассмотрим $%p = (x-2)^2 + (sqrt{x})^2 = x^2-4x+4+x=x^2-3x+4$%. Понятно, что минимум данной функции находится в точке $%x_1 = frac{3}{2}$%. Соответственно, наиболее близкая точка на графике данной функции к точке $%M$% будет точка $%(frac{3}{2}; sqrt{frac{3}{2}})$%.
.net 4
vs2010
winform
c#
added some points using
chart1.Series[0].Points.AddXY(x,y);
when I click on the chart, the cursor may not fall on any points.
Are there any functions to return the nearest point? (forget y, just x distance.)
Or I have to write my own binary search function?
John Saunders
160k26 gold badges247 silver badges396 bronze badges
asked Jan 22, 2013 at 9:34
private void Chart_MouseClick(object sender, MouseButtonEventArgs e)
{
LineSeries line = (LineSeries)mychart.Series[0];
Point point = e.GetPosition(line);
Int32? selectIndex = FindNearestPointIndex(line.Points, point);
// ...
}
private Int32? FindNearestPointIndex(PointCollection points, Point point)
{
if ((points == null || (points.Count == 0))
return null;
Func<Point, Point, Double> getLength = (p1, p2) => Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2)); // C^2 = A^2 + B^2
List<Points> results = points.Select((p,i) => new { Point = p, Length = getLength(p, point), Index = i }).ToList();
Int32 minLength = results.Min(i => i.Length);
return results.First(i => (i.Length == minLength)).Index;
}
answered Jan 22, 2013 at 9:40
Tommaso BelluzzoTommaso Belluzzo
23.1k8 gold badges71 silver badges97 bronze badges
3
To find the nearest point in a set of unordered points, you have to iterate through them all and keep track of the minimum distance. This has a time complexity of O(n).
You could significantly improve this by maintaining the points in a more organized data structure (such as an R-tree). There are third-party libraries available if you’d rather not implement your own. Many databases already support the R-tree for spatial indices.
If you really want to only search for the point with the nearest X-coordinate, this could be further simplified by storing the points in a sorted collection (such as a SortedList<TKey, TValue>
) and performing a binary search (which SortedList<TKey, TValue>.IndexOfKey
already implements).
answered Jan 22, 2013 at 19:58
JosephHirnJosephHirn
7203 silver badges9 bronze badges
/*My Fuzzy Binary Search*/
private int FindNearestId(System.Windows.Forms.DataVisualization.Charting.DataPointCollection p, uint ClickedX)
{
int ret = 0;
int low = 0;
int high = p.Count - 1;
bool bLoop = true;
while (bLoop)
{
ret = (low + high) / 2;
switch (FindNearestId_Match(p, ClickedX, ret))
{
case 0:
high = ret+1;
break;
case 1:
bLoop = false;
break;
case 2:
low = ret-1;
break;
}
}
return ret+1;
}
private int FindNearestId_Match(System.Windows.Forms.DataVisualization.Charting.DataPointCollection p, uint ClickedX, int id)
{
uint id0 = Convert.ToUInt32(p[id].XValue);
uint id1 = Convert.ToUInt32(p[id+1].XValue);
if ( (id0 <= ClickedX) && (ClickedX < id1) )
{
return 1;
}
else if ((id0 < ClickedX) && (ClickedX > id1))
{
return 2;
}
else
{
return 0;
}
}
answered Jan 22, 2013 at 12:04
aihenry2980aihenry2980
3292 gold badges7 silver badges18 bronze badges
Soultion can be more clear.
( as above you should use log complexity for accessing item )
double x-values solution:
double FindNearestPointYValueInSeries( System::Windows::Forms::DataVisualization::Charting::Series ^pxSeries, double dSearchedPosition )
{
int i_min = 0;
int i_max = pxSeries->Points->Count - 1;
int i_mean = 0;
double d ;
if ( i_max < 0 ) // not defined - minimum one point required
return Double::NaN;
while ( i_min <= i_max )
{
i_mean = (i_max + i_min ) / 2; // index of compared value in series
d = pxSeries->Points[ i_mean ]->XValue; // compared value
if ( d > dSearchedPosition ) // greater - search in right part
i_max = i_mean - 1;
else if ( d < dSearchedPosition ) // lower - search in left part
i_min = i_mean + 1;
else // equal ?
return d;
}
// delta is dSearchedPosition - pxSeries->Points[ i_mean ]->YValues[0]
// get Y value ( on index 0 )
return pxSeries->Points[ i_mean ]->YValues[0];
}
answered Nov 26, 2014 at 16:26
7 / 7 / 0 Регистрация: 11.01.2012 Сообщений: 240 |
|
1 |
|
Найти точку ближайшую к началу координат.24.01.2012, 19:38. Показов 8654. Ответов 3
На правой ветви квадратичной гиперболы
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
24.01.2012, 19:38 |
Ответы с готовыми решениями: Найти точку ближайшую к началу координат Найти ближайшую к началу координат точку
3 |
4652 / 3404 / 361 Регистрация: 11.11.2010 Сообщений: 6,205 Записей в блоге: 2 |
|
24.01.2012, 20:03 |
2 |
Пусть
1 |
7 / 7 / 0 Регистрация: 11.01.2012 Сообщений: 240 |
|
24.01.2012, 20:04 [ТС] |
3 |
Спасибо
0 |
51 / 62 / 16 Регистрация: 18.10.2010 Сообщений: 240 |
|
24.01.2012, 20:04 |
4 |
Расстояние от точки до начала координат задаётся уравнением: Дальше тебе надо взять производную от f и приравнять к нулю.
1 |
IT_Exp Эксперт 87844 / 49110 / 22898 Регистрация: 17.06.2006 Сообщений: 92,604 |
24.01.2012, 20:04 |
4 |
ответы
ваш ответ
Можно ввести 4000 cимволов
отправить
дежурный
Нажимая кнопку «отправить», вы принимаете условия пользовательского соглашения
похожие темы
похожие вопросы 5
На плоскости расстояние между точками (x,y) и (x0,y0) выражается как d^2=(x-x0)^2+(y-y0)^2
В данном случае y=x^2 (уравнение параболы).
А x0=2, y0=0.5 (точка на плоскости)
Тогда функция, выражающая расстояние между данной точкой и любой точкой параболы будет d=sqrt((x-x0)^2+(y-y0)^2)=sqrt((x-2)^2+(x^2-0.5)^2)
Теперь надо найти минимум этой функции. Мы знаем, что функция возрастает если производная(первая) больше нуля, убывает — если меньше, и имеет екстремум — если производная равна нулю. Этот экстремум, в даном случае, есть минимум, так как расстояние между точкой на параболе и точкой А убывает, а потом возрастает.
Решаем уравнение d´=0, находим из него х(абсциса искомой точки).
Подставляем х в уравнение параболы y=x^2 и находим y(ордината искомой точки).Усе.
Код: Выделить всё
> d:=(sqrt((x-2)^2+(x^2-0.5)^2));
2 2 2 1/2
d := ((x - 2) + (x - 0.5) )
> diff(d,x);
2
2 x - 4 + 4 (x - 0.5) x
-----------------------------
2 2 2 1/2
2 ((x - 2) + (x - 0.5) )
> solve(%,x);
1., -0.5000000000 + 0.8660254038 I, -0.5000000000 - 0.8660254038 I
> x:=1;
x := 1
> solve(y=x^2,y);
1
>
d’- производная d по x.