C 如何知道点是否在三角形中?

C 如何知道点是否在三角形中?,c,algorithm,geometry,pixel,point,C,Algorithm,Geometry,Pixel,Point,我有一个简单的二维三角形。我一直在寻找如何知道一个给定的点是否属于那个三角形。下面是算法(我在这里找到了:),它非常好而且快速(据其他人说): 浮点数(整数x0、整数y0、整数x1、整数y1、整数x2、整数y2){ 返回(x0-x2)*(y1-y2)-(x1-x2)*(y0-y2); } intpIntr(intsx,intsy,intx0,inty0,intx1,inty1,intx2,inty2){ int b1、b2、b3; b1=符号(sx,sy,x0,y0,x1,y1)

我有一个简单的二维三角形。我一直在寻找如何知道一个给定的点是否属于那个三角形。下面是算法(我在这里找到了:),它非常好而且快速(据其他人说):

浮点数(整数x0、整数y0、整数x1、整数y1、整数x2、整数y2){
返回(x0-x2)*(y1-y2)-(x1-x2)*(y0-y2);
}
intpIntr(intsx,intsy,intx0,inty0,intx1,inty1,intx2,inty2){
int b1、b2、b3;
b1=符号(sx,sy,x0,y0,x1,y1)<0.0f?1:0;
b2=符号(sx,sy,x1,y1,x2,y2)<0.0f?1:0;
b3=符号(sx,sy,x2,y2,x0,y0)<0.0f?1:0;
如果((b1)=b2&(b2==b3))
返回1;
返回0;
}
我在draw_ftriangle()中调用此函数:

void draw_ftriangle(SDL_曲面*s,int x0,int y0,int x1,int y1,int x2,int y2,无符号颜色){
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));
画线(s,x0,y0,x1,y1,颜色);
画线(s,x1,y1,x2,y2,颜色);
画线(s,x0,y0,x2,y2,颜色);
对于(;ymin

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

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

ptintr(3,2,1,1,3,4,4,1))=>返回1

ptintr(2,3,1,1,3,4,4,1))=>返回0

他们都是对的

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

ptintr(3,1,1,3,4,4,1))=>返回0
,因为点(3,1)位于轮廓上


尝试更改
您的循环只执行顶行,因为xmin没有重置

换句话说,第一次通过内部x循环时,您将增加xmin,直到它变成xmax。第二次执行内部x循环时,xmin已经是xmax,因此不会发生任何事情

试一试

intx;
对于(;ymin
出于好奇,如果将“
<0.0f
”更改为“
,会发生什么情况?您还没有演示如何调用这些函数。假设此代码是正确的(我个人不知道任何一种方式),可能是您调用函数不正确。我用ptintr(0,0,0,0,1,0,1)尝试了它它为我返回了1。也许你可以提供一个失败的例子?我建议学习一点向量演算……这是最简单的问题之一。点在三角形中,如果mysign(t1,p,t2),mysign(p,t3,t2)和mysign(t1,t3,p)都是正的。mysign(a,b,c)是(b-a,c-a)矩阵的行列式。a(V,W)的行列式矩阵是V.xW.y-V.yW.x。一旦所有关于在三角形中包含一个点的2D内容都讲完了,这将不是一个像素一个像素地给三角形着色的最有效的方法:你可以根据三角形区域中像素的顺序来决定,这样就足够麻烦处理其周长上的像素了d xmin在x轴上保持最左边的值。然后在y轴上向下,在x轴上向右,所以不是所有的点都在三角形的轮廓上,有些点应该在三角形内。@Arnas然后给我们找到一个代码不起作用的情况。向我们报告不起作用的确切值。我测试了多次,结果是Works正确。问题在于你的xmin是递增的,但没有重置。你再也不会进入第二个for循环,因为xmin已经在xmax。谢谢!捕捉得很好。这个对我很好!再次感谢。
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;
}
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);
}
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);