Алгоритм деления дуги - PullRequest
       18

Алгоритм деления дуги

1 голос
/ 17 января 2012

Я ищу образец текстуры вдоль дуги окружности в фрагментном шейдере.Такого рода исключаются рекурсивные методы, такие как this .

Я придумал несколько разных способов сделать это: два, которые кажутся наиболее разумными: (Учитывая начальную позицию p, центр c, радиус r = length(c-p), угол (степень дуги) theta в радианах и N позициях):

1) Поверните вектор pc вокруг c на theta/N, N раз: это требует построения матрицы вращения, которая будет многократно использоваться: стоимость- это две функции триггера, умножение матрицы N 2x2, N или около того векторных вычитаний

2) Найти длину хорды одного сегмента, проходящего через сектор: его длина равна 2*r*sin(theta/2).Получив первый вектор, я могу повернуть его и добавить в предыдущую позицию, чтобы «шагнуть» по моей дуге.Проблема этого метода в том, что я до сих пор не знаю выражения для получения ориентации моего вектора длины 2*r*sin(theta/2).Даже если бы я это сделал, мне, вероятно, понадобились бы тригонометрические функции для его построения.Мне все еще нужно повернуть его так, что мне может потребоваться построить матрицу вращения.Тьфу.

Могу ли я рассмотреть другие методы?

1 Ответ

3 голосов
/ 17 января 2012

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

void f(float cx, float cy, float px, float py, float theta, int N)
{
    float dx = px - cx;
    float dy = py - cy;
    float r2 = dx * dx + dy * dy;
    float r = sqrt(r2);
    float ctheta = cos(theta/(N-1));
    float stheta = sin(theta/(N-1));
    std::cout << cx + dx << "," << cy + dy << std::endl;
    for(int i = 1; i != N; ++i)
    {
        float dxtemp = ctheta * dx - stheta * dy;
        dy = stheta * dx + ctheta * dy;
        dx = dxtemp;
        std::cout << cx + dx << "," << cy + dy << std::endl;
    }
}

При больших N вы можете обнаружить, что здесь накапливаются некоторые ошибки.Учитывая некоторые предположения относительно N и theta, вы могли бы сделать небольшую аппроксимацию угла для трига.

Резюме: Если вы хотите указать указанное количество точек и используете дуги, я не могу видеть, чтовы действительно найдете способ сделать намного меньше вычислений, чем что-то близкое к варианту 1).

...