Вы можете сделать это аналитически, но нужна небольшая математика.
Кривая Безье может быть выражена через Базис Бернштейна .Здесь я буду использовать Mathematica , которая обеспечивает хорошую поддержку математики.
Так что, если у вас есть очки:
pts = {{0, -1}, {1, 1}, {2, -1}, {3, 1}};
Уравнение.для кривой Безье:
f[t_] := Sum[pts[[i + 1]] BernsteinBasis[3, i, t], {i, 0, 3}];
Имейте в виду, что для удобства я использую базис Бернштейна, но ЛЮБОЕ параметрическое представление кривой Безье подойдет.
Что дает:
Теперь, чтобы найти минимальное расстояние до точки (скажем, {3, -1}, например), вы должны свернуть функцию:
d[t_] := Norm[{3, -1} - f[t]];
Для этого вам нужен алгоритм минимизации.У меня есть одна удобная вещь, поэтому:
NMinimize[{d[t], 0 <= t <= 1}, t]
дает:
{1.3475, {t -> 0.771653}}
И это все.
HTH!
Править Относительно вашего редактирования "B-сплайн, состоящий из (n − 1) / 3 кубических кривых Безье."
Если вы построили кусочно-B-сплайн-представление, вы должны выполнить итерацию по всем сегментам, чтобы найти минимумы.Если вы объединили фигуры по непрерывному параметру, то подойдет тот же подход.
Редактировать
Решение вашей кривой.Я игнорирую первый пункт, потому что я действительно не понимал, что это такое.
Для ясности я решил это с помощью стандартных Bsplines вместо функций mathematica.
Clear["Global`*"];
(*first define the points *)
pts = {{
29.124, 284.61}, {
25.066, 258.56}, {
20.926, 212.47}, {
34, 176}, {
38.706, 162.87}, {
46.556, 149.82}, {
54.393, 138.78}};
(*define a bspline template function *)
b[t_, p0_, p1_, p2_, p3_] :=
(1-t)^3 p0 + 3 (1-t)^2 t p1 + 3 (1-t) t^2 p2 + t^3 p3;
(* define two bsplines *)
b1[t_] := b[t, pts[[1]], pts[[2]], pts[[3]], pts[[4]]];
b2[t_] := b[t, pts[[4]], pts[[5]], pts[[6]], pts[[7]]];
(* Lets see the curve *)
Show[Graphics[{Red, Point[pts], Green, Line[pts]}, Axes -> True],
ParametricPlot[BSplineFunction[pts][t], {t, 0, 1}]]
.(Повернуто! Для экономии места на экране)
(*Now define the distance from any point u to a point in our Bezier*)
d[u_, t_] := If[(0 <= t <= 1), Norm[u - b1[t]], Norm[u - b2[t - 1]]];
(*Define a function that find the minimum distance from any point u \
to our curve*)
h[u_] := NMinimize[{d[u, t], 0.0001 <= t <= 1.9999}, t];
(*Lets test it ! *)
Plot3D[h[{x, y}][[1]], {x, 20, 55}, {y, 130, 300}]
Этот график представляет собой (минимальное) расстояние от любой точки пространства до нашей кривой (конечно, значение по кривойноль):