2013-03-23 4 views
2

За исключением использования справочных таблиц, есть ли другой способ оптимизировать алгоритм параметризации кубической кривой Безье как это? (5000 шагов для хорошей параметризации просто слишком много для более медленного компьютера, как мне нужно, чтобы вызвать эту функцию много раз в 1 секунду):Оптимизация алгоритма параметризации кубической кривой безье

function parameterizeCurve(path, partArc, initialT) 
{ 
    // curve length is already known and globally defined 
    // brute force 
    var STEPS = 5000; // > precision 
    var t = 1/STEPS; 
    var aX=0; 
    var aY=0; 
    var bX=path[0], bY=path[1]; 
    var dX=0, dY=0; 
    var dS = 0; 
    var sumArc = 0; 
    var arrT = new Array(Math.round(partArc)); 
    var z = 1; 
    arrT[0] = -1; 

    var oldpartArc = partArc; 
    partArc = partArc - initialT; 

    var j = 0; 

    for (var i=0; i<STEPS; j = j + t) { 
     aX = bezierPoint(j, path[0], path[2], path[4], path[6]); 
     aY = bezierPoint(j, path[1], path[3], path[5], path[7]); 

     dX = aX - bX; 
     dY = aY - bY; 
     // deltaS. Pitagora 
     dS = Math.sqrt((dX * dX) + (dY * dY)); 
     sumArc = sumArc + dS; 
     if (sumArc >= partArc) { 
     arrT[z] = j; // save current t 
     z++; 
     sumArc = 0; 
     partArc = oldpartArc; 
     } 
     bX = aX; 
     bY = aY; 
     i++; 
    } 

    return arrT; 
} 


    function bezierPoint(t, o1, c1, c2, e1) { 
     var C1 = (e1 - (3.0 * c2) + (3.0 * c1) - o1); 
     var C2 = ((3.0 * c2) - (6.0 * c1) + (3.0 * o1)); 
     var C3 = ((3.0 * c1) - (3.0 * o1)); 
     var C4 = (o1); 

     return ((C1*t*t*t) + (C2*t*t) + (C3*t) + C4) 
    } 
+0

Что такое ввод? Что вы оптимизируете? Похоже, вы пытаетесь максимизировать какое-то расстояние. – Joni

+0

Параметризация - это хорошо известный вопрос в математике. Мне нужно разместить эквидистантные элементы на кривой. –

+0

Как определяется кривая? Это кусочная кривая безземельной 3-й степени или что-то еще? У меня есть степень магистра по математике btw – Joni

ответ

1

Если я угадал, что вы пытаетесь прийти с кубической параметризацией кривой Безье, которая движется с постоянной скоростью вдоль кривой.

Итак, зачем вам 5000 шагов? Минимальный ход по кривой - один пиксель. Безье остается в выпуклой оболочке четырех контрольных точек, поэтому длина кривой будет меньше длины полилинии P0 -> P1 -> P2 -> P3. Поэтому найдите эту длину в пикселях и используйте ее (вместо 5000).

Сообщите мне, если это ускоряет работу.

+0

Я не понимал, но то, что я пытаюсь достичь, - это разместить на кривой некоторые элементы, которые должны быть одинаково отдалены друг от друга. Я делаю это очень часто, потому что кривая меняется. Поэтому мне нужно, чтобы предметы на кривой находились в очень точном месте. Если я делаю менее 5000 циклов, вся анимация (элементы) начинает немного танцевать по кривой, потому что параметризация не так точна ... и этого эффекта следует избегать, и это должно быть не так дорого. –

+0

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

+0

То, что я делаю, просто повторяется через t кривой 5000 раз до конца кривая. Так как плотность t не одинакова на каждом месте (например, в самом изогнутом месте дуга между тем же t различна, то на более прямом месте кривой), мне нужно пройти через всю кривую. Поэтому, если я помещаю туда длину кривой вместо 5000, выходные номера не так точны, и я получаю элементы, танцующие на кривой, поскольку кривая изменяет его контрольные точки. –