弧细分算法

时间:2012-01-16 23:21:14

标签: graphics shader geometry

我希望从片段着色器中的圆弧纹理中进行采样。这种规则排除了诸如this之类的递归方法。

我想出了几种不同的方法来实现这一目标:两个似乎最合理的方法是(给定起始位置p,中心c,半径r = length(c-p),角度(弧线)范围)theta以弧度和N位置):

1)将矢量pc绕c旋转theta/NN次:这需要构造一个将重复使用的旋转矩阵:cost是两个trig函数,N 2x2矩阵乘以N左右的矢量减法

2)找到遍历扇区的一个段的和弦长度:其长度为2*r*sin(theta/2)。一旦我有第一个矢量,我就可以旋转它并将它添加到前一个位置以“沿着我的弧线”。这个方法的问题是我仍然不知道表达式来获取我的长2*r*sin(theta/2)向量的方向。即使我这样做,我也可能需要使用trig函数来构造它。我仍然需要旋转它,这可能需要我仍然构建一个旋转矩阵。啊。

我还可以考虑其他方法吗?

1 个答案:

答案 0 :(得分:3)

我认为一旦你开始使用圆圈和角度,你一定会有几个触发调用。 鉴于此,第一种方法似乎没问题。我只是注意到,如果迭代地对点进行迭代,我认为不需要2D矩阵乘法。

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,您可能会发现此处累积了一些错误。 考虑到Ntheta周围的一些假设,您可以对trig进行一些小角度近似。

总结:如果你想要指定的点数并且正在使用弧线,我看不出你真的会找到一种比接近选项1的方法更少计算的方法。