2013-10-07 3 views
7

Я искал, но, очевидно, не нашел алгоритм, который позволит мне подключить список координат x, y, которые, как известно, находятся вдоль кривой, чтобы получить 4 контрольных точки для кубического безье кривая выплюнула.Алгоритм получения контрольных точек кривой Безье из точек вдоль этой кривой?

Чтобы быть более точным, я ищу алгоритм, который даст мне две контрольные точки, необходимые для формирования кривой при вводе серии дискретных точек, включая две контрольные точки, которые определяют начало и конец кривой ,

Спасибо!

Редактировать: Хорошо, из-за математики, старого врага, мне нужно спросить кривую Безье, которая лучше всего подходит для полиномиальной функции.

ответ

9

Таким образом, я предполагаю, что конечные точки фиксированы, а затем у вас есть несколько (x, y) точек выборки, которые вы хотите поместить в кубический Безье.

Количество выборок, которые у вас есть, определит, какой подход принять. Давайте посмотрим через несколько случаев:

2 очка

2 точек выборки простейший случай. Это дает вам всего 4 балла, если вы считаете конечные точки. Это число CV в кубическом Безье. Чтобы решить эту проблему, вам нужно значение параметра (t) для обеих точек выборки. Тогда у вас есть система из двух уравнений и 2 точек, которые вам нужно решить, где уравнение является параметрическим уравнением кривой Безье по выбранным значениям t.

Значения t могут быть любыми, как вам нравится, но вы получите лучшие результаты, используя либо 1/3, либо 2/3, или глядя на относительные расстояния или относительные расстояния вдоль базовой линии, в зависимости от ваших данных.

1 точка

Это похоже на 2 очка, за исключением того, что у вас недостаточно информации, чтобы однозначно определить все степени свободы. Я бы предположил, что он должен соответствовать квадратичному Безье, а затем повысить степень. Я написал подробный пример квадратичного монтажа в this question.

Более 2 балла

В этом случае, существует не единственное решение. Я использовал аппроксимацию наименьших квадратов с хорошими результатами. Шаги:

  • Пика т значения для каждого образца
  • Построить систему уравнений в виде матрицы
  • По желанию добавить обтекатель или некоторые другие функции сглаживания
  • Решить матрицу с методом наименьших квадратов решателя

Существует хорошее описание этих шагов в этом free cagd textbook, глава 11. это говорит о установке би-сплайнов, а кубический Безье является разновидностью би-сплайн (узел вектор 0,0,0, 1,1,1 и имеет 4 балла).

+0

Спасибо за быстрый ответ. Я думал, что алгебра, вероятно, потребуется, но это может стать немного непристойным, если кривая может иметь тысячи очков. Я попытаюсь разбить большие кривые на более мелкие кривые и применить двухточечный метод. В случае, если это не сработает, я дам более двух пунктов попробовать попытку! – Everlag

+0

Если точность кривой не имеет особого значения, вы можете попробовать просто выбрать две точки и сделать метод с двумя точками .. :) – tfinniga

+0

Я стремлюсь к приличному отдыху ребер, изолированных с оператором sobel, поэтому точность была бы очень гораздо предпочтительнее. – Everlag

4

Допустим, у вас есть кривая у = Р (х)

Для определения кривой Безье вам нужно 4 очка, как: P1x, P1Y, P2X, P2Y, P3x, P3y и P4x и P4y

P1 и P4 вы являетесь начальными/конечными точками кривой. P2 и P3 - контрольные точки. Вы уже знаете, где начинаются и заканчиваются кривые. Вы должны вычислить P2 и P3. Координата x P2x и P3x проста, потому что вы просто выбираете их, выбирая t кривой, например, 1/3 и 2/3. Итак, у вас есть P2x и P3x . Тогда вы получите систему из двух уравнений и двух неизвестных (P2y и P3y). После хруст математикой вы в конечном итоге с чем-то вроде этого:

(. Мой е (х) был кубический многочлен, который также гарантирует, что я был бы в состоянии соответствовать один кубический кривую Безье к ней точно)

/** 
    @params {Object} firstPoint = {x:...,y...} 
    @params {Object} lastPoint = {x:...,y...} 
    @params {Object} cubicPoly Definition of a cubic polynomial in the form y=ax^3+bx^2+c. 
    Has a method EvaluateAt, which calculates y for a particular x 

*/ 
var CalcBezierControlPoints = function(firstPoint, lastPoint, cubicPoly) { 
    var xDiff = lastPoint.X - firstPoint.X; 
    var x1 = firstPoint.X + xDiff/3.0; 
    var x2 = firstPoint.X + 2.0 * xDiff/3.0; 

    var y1 = cubicPoly.EvaluateAt(x1); 
    var y2 = cubicPoly.EvaluateAt(x2); 

    var f1 = 0.296296296296296296296; // (1-1/3)^3 
    var f2 = 0.037037037037037037037; // (1-2/3)^3 
    var f3 = 0.296296296296296296296; // (2/3)^3 

    var b1 = y1 - firstPoint.Y * f1 - lastPoint.Y/27.0; 
    var b2 = y2 - firstPoint.Y * f2 - f3 * lastPoint.Y; 

    var c1 = (-2 * b1 + b2)/-0.666666666666666666; 
    var c2 = (b2 - 0.2222222222222 * c1)/0.44444444444444444; 

    var p2 = {}; 
    var p3 = {}; 
    p2.X = x1; 
    p2.Y = c1; 

    p3.X = x2; 
    p3.Y = c2; 

    return ([p2, p3]); 
} 
Смежные вопросы