我怎么知道一个点是否是三角形?

时间:2012-10-06 19:03:13

标签: c algorithm geometry pixel point

我有一个简单的2D三角形。我一直在寻找如何知道给定点是否属于那个三角形。这是算法(我在这里找到它:How to determine if a point is in a 2D triangle?),这是非常好的和快速的(根据其他人的说法):

float sign(int x0, int y0, int x1, int y1, int x2, int y2){
    return (x0 - x2) * (y1 - y2) - (x1 - x2) * (y0 - y2);
}

int ptintr(int sx, int sy, int x0, int y0, int x1, int y1, int x2, int y2){
    int b1, b2, b3;

    b1 = sign(sx, sy, x0, y0, x1, y1) < 0.0f ? 1 : 0;
    b2 = sign(sx, sy, x1, y1, x2, y2) < 0.0f ? 1 : 0;
    b3 = sign(sx, sy, x2, y2, x0, y0) < 0.0f ? 1 : 0;

    if((b1) == b2 && (b2 == b3))
        return 1;
    return 0;
}

我在draw_ftriangle()中调用此函数:

void draw_ftriangle(SDL_Surface * s, int x0, int y0, int x1, int y1, int x2, int y2, unsigned color){
    int ymin = min(y0, min(y1, y2));
    int xmin = min(x0, min(x1, x2));
    int ymax = max(y0, max(y1, y2));
    int xmax = max(x0, max(x1, x2));

    draw_line(s, x0, y0, x1, y1, color);
    draw_line(s, x1, y1, x2, y2, color);
    draw_line(s, x0, y0, x2, y2, color);

    for(; ymin < ymax; ymin++)
        for(; xmin < xmax; xmin++)
            if(ptintr(xmin, ymin, x0, y0, x1, y1, x2, y2))
                put_pixel(s, xmin, ymin, color);
}

这里sx和sy是给定点的坐标,x0,x1,x2,y0,y1,y2是三角形的点。但是这个算法不起作用。每当我给这个函数一个点的坐标和三角形点的坐标时,它总是返回false。谁能告诉我这个算法是否正确,或者我在这里留下了一些错误?

2 个答案:

答案 0 :(得分:1)

我用两个输入尝试了这个算法:

ptintr(3,2,1,1,3,4,4,1)) => returned 1

ptintr(2,3,1,1,3,4,4,1)) => returned 0

他们都是正确的。

我可能错了,但您正在测试从(x,y)池中采样的最小和最大坐标,这意味着它们都将位于三角形的轮廓上。该算法认为轮廓上的坐标不是它的一部分。

ptintr(3,1,1,1,3,4,4,1)) => returns 0因为点(3,1)在轮廓上。

尝试在功能<中将<=运算符更改为ptintr

答案 1 :(得分:1)

你的循环只占顶线,因为xmin没有重置。

换句话说,第一次通过内部x循环,你将增加xmin,直到它变为xmax。第二次执行内部x循环时,xmin已经是xmax,所以没有任何反应。

尝试

int x;
for(; ymin < ymax; ymin++)
    for(x=xmin; x < xmax; x++)
        if(ptintr(x, ymin, x0, y0, x1, y1, x2, y2))
            put_pixel(s, x, ymin, color);