Алгоритм деления дуги
Я ищу образец текстуры вдоль дуги окружности в фрагментном шейдере. Такого рода исключаются рекурсивные методы, такие как этот.
Я придумал несколько разных способов сделать это: два, которые кажутся наиболее разумными: (Учитывая стартовую позицию p
, центр c
радиус r = length(c-p)
, угол (степень дуги) theta
в радианах и N
позиции):
1) Поверните вектор pc относительно c на theta/N
, N
времена: Это требует построения матрицы вращения, которая будет многократно использоваться: стоимость составляет две функции триггера, N
Матричное умножение 2х2, N
или так векторные вычитания
2) Найдите длину хорды одного сегмента, проходящего через сектор: его длина 2*r*sin(theta/2)
, Получив первый вектор, я могу повернуть его и добавить в предыдущую позицию, чтобы "шагнуть" по моей дуге. Проблема с этим методом в том, что я до сих пор не знаю выражения, чтобы получить ориентацию моей длины 2*r*sin(theta/2)
вектор. Даже если бы я это сделал, мне, вероятно, понадобились бы тригонометрические функции для его построения. Мне все еще нужно повернуть его так, что мне может потребоваться построить матрицу вращения. Тьфу.
Есть ли другие методы, которые я мог бы рассмотреть?
1 ответ
Я думаю, что как только вы начнете использовать круги и углы, у вас обязательно будет пара триггеров. Учитывая это, первый метод кажется нормальным. Отмечу только, что я не вижу необходимости в умножении двумерных матриц как таковых, если они действуют итерационно на точках.
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).