C++中在知道两条线段相交后,怎么判断它们的交点个数?求大神解救

水落 2014-03-20 11:42:40
指点一下详细的算法。。
如果有调用函数的代码就更好了。。。。
...全文
410 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
dbzhang800 2014-03-20
  • 打赏
  • 举报
回复
引用 2 楼 u013961718 的回复:
我在OJ上遇到一个题要求交点个数,0个,1个或多个。。。
两条线段相交,只可能有一个交点啊
水落 2014-03-20
  • 打赏
  • 举报
回复
我在OJ上遇到一个题要求交点个数,0个,1个或多个。。。
derekrose 2014-03-20
  • 打赏
  • 举报
回复
据我所知你只需要判断是否相交就行了
lm_whales 2014-03-20
  • 打赏
  • 举报
回复
重合线段,根据四个端点之间的距离的投影关系,就可以判断出来的。
赵4老师 2014-03-20
  • 打赏
  • 举报
回复
如果是判断表示两条线段的像素是否重叠,还可以参考一下这个: LineDDA The LineDDA function determines which pixels should be highlighted for a line defined by the specified starting and ending points. BOOL LineDDA( int nXStart, // x-coordinate of line's starting point int nYStart, // y-coordinate of line's starting point int nXEnd, // x-coordinate of line's ending point int nYEnd, // y-coordinate of line's ending point LINEDDAPROC lpLineFunc, // pointer to callback function LPARAM lpData // pointer to application-defined data ); Parameters nXStart Specifies the x-coordinate of the line's starting point. nYStart Specifies the y-coordinate of the line's starting point. nXEnd Specifies the x-coordinate of the line's ending point. nYEnd Specifies the y-coordinate of the line's ending point. lpLineFunc Pointer to an application-defined callback function. For more information, see the LineDDAProc callback function. lpData Pointer to the application-defined data. Return Values If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. Windows NT: To get extended error information, callGetLastError. Remarks The LineDDA function passes the coordinates for each point along the line, except for the line's ending point, to the application-defined callback function. In addition to passing the coordinates of a point, this function passes any existing application-defined data. The coordinates passed to the callback function match pixels on a video display only if the default transformations and mapping modes are used. QuickInfo Windows NT: Requires version 3.1 or later. Windows: Requires Windows 95 or later. Windows CE: Unsupported. Header: Declared in wingdi.h. Import Library: Use gdi32.lib. See Also Lines and Curves Overview, Line and Curve Functions, LineDDAProc
赵4老师 2014-03-20
  • 打赏
  • 举报
回复
引用 14 楼 u013961718 的回复:
请问各位大神,在判断出两条线段相交且线段长度不相等并且都在同一条直线上后,再判断其中一条线段的两个端点是否在另一条线段上(不包括该线段的端点),若只要其中一个端点在另一条线段上(不包括该线段的端点),即可得出有多个交点,反之若两个端点都不在另一条线段上(不包括该线段的端点)只有一个交点。。 不知道我的想法对不对?
参考一下这个?(可能有大炮打苍蝇之嫌)
//实现一个函数:求数轴上多个线段覆盖的区域对应的多个线段; 输入多个线段,求出被这些线段覆盖的所有区域(也用线段表示); 一条线段用两个值表示(x0,x1), 其中x1>x0;
//比如(1,3);(2,4);(5,6);结果为(1,4);(5,6);
//比如(1,3);(2,4);(5,6);(4,7);结果为(1,7);
#include <stdio.h>
#define MAXLINES 100
struct LINE {
    int x0;//左端
    int x1;//右端
} ls[MAXLINES];
int i,j,k,n,x0,x1,c;
void add() {
    if (0==n) {//加入第一对点
        ls[n].x0=x0;
        ls[n].x1=x1;
        n=1;
    } else {
        if (x1==ls[0].x0) {//右端=第一条线段的左端
            ls[0].x0=x0;//第一条线段的左端修改为左端
            return;
        }
        if (x1<ls[0].x0) {//右端<第一条线段的左端
            for (i=n-1;i>=0;i--) {//将所有线段往后移
                ls[i+1].x0=ls[i].x0;
                ls[i+1].x1=ls[i].x1;
            }
            ls[0].x0=x0;//新第一条线段为x0,x1
            ls[0].x1=x1;
            n++;
            return;
        }
        if (ls[n-1].x1<x0) {//左端>最后那条线段的右端
            ls[n].x0=x0;//新最后那条线段
            ls[n].x1=x1;
            n++;
            return;
        }
        if (x0<=ls[0].x0 && ls[n-1].x1<=x1) {//左端≤第一条线段的左端且最后那条线段的右端≤右端
            ls[0].x0=x0;//只剩这一条线段
            ls[0].x1=x1;
            n=1;
            return;
        }
        for (i=0;i<n;i++) {//从左到右依次检查每条线段
            if (ls[i].x0<=x0 && x0<=ls[i].x1) {//第i条线段的左端≤左端≤第i条线段的右端
                for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段
                    if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
                        ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端
                        for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
                            ls[i+k].x0=ls[j+k].x0;
                            ls[i+k].x1=ls[j+k].x1;
                        }
                        n-=j-i;
                        return;
                    }
                    if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
                        ls[i].x1=x1;//第i条线段的右端改为右端
                        for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
                            ls[i+k].x0=ls[j+k].x0;
                            ls[i+k].x1=ls[j+k].x1;
                        }
                        n-=j-i;
                        return;
                    }
                }
            }
            if (ls[i].x1<x0 && (i==n-1 || x0<ls[i+1].x0)) {//第i条线段的右端<左端<第i+1条线段的左端(如果有)
                if (i!=n-1 && x1<ls[i+1].x0) {//右端<第i+1条线段的左端(如果有)
                    for (k=n-1;k>=i+1;k--) {//将从第i+1条线段开始的所有线段往后移
                        ls[k+1].x0=ls[k].x0;
                        ls[k+1].x1=ls[k].x1;
                    }
                    ls[i+1].x0=x0;//新第i+1条线段为x0,x1
                    ls[i+1].x1=x1;
                    n++;
                    return;
                }
                for (j=i+1;j<n;j++) {//从第i+1条线段开始从左到右依次检查每条线段
                    if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
                        ls[i+1].x0=x0;//第i+1条线段的左端改为左端
                        ls[i+1].x1=ls[j].x1;//第i+1条线段的右端改为第j条线段的右端
                        for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
                            ls[i+1+k].x0=ls[j+k].x0;
                            ls[i+1+k].x1=ls[j+k].x1;
                        }
                        n-=j-i-1;
                        return;
                    }
                    if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
                        ls[i+1].x0=x0;//第i+1条线段的左端改为左端
                        ls[i+1].x1=x1;//第i+1条线段的右端改为右端
                        for (k=1;k<n-j-1;k++) {//将剩余线段往前移
                            ls[i+k].x0=ls[j+k].x0;
                            ls[i+k].x1=ls[j+k].x1;
                        }
                        n-=j-i-1;
                        return;
                    }
                }
            }
            if (x0<ls[i].x0) {//左端<第i条线段的左端
                for (j=i;j<n;j++) {//从第i条线段开始从左到右依次检查每条线段
                    if (ls[j].x0<=x1 && x1<=ls[j].x1) {//第j条线段的左端≤右端≤第j条线段的右端
                        ls[i].x0=x0;//第i条线段的左端改为左端
                        ls[i].x1=ls[j].x1;//第i条线段的右端改为第j条线段的右端
                        for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
                            ls[i+k].x0=ls[j+k].x0;
                            ls[i+k].x1=ls[j+k].x1;
                        }
                        n-=j-i;
                        return;
                    }
                    if (ls[j].x1<x1 && (j==n-1 || x1<ls[j+1].x0)) {//第j条线段的右端<右端<第j+1条线段的左端(如果有)
                        ls[i].x0=x0;//第i条线段的左端改为左端
                        ls[i].x1=x1;//第i条线段的右端改为右端
                        for (k=1;k<=n-j-1;k++) {//将剩余线段往前移
                            ls[i+k].x0=ls[j+k].x0;
                            ls[i+k].x1=ls[j+k].x1;
                        }
                        n-=j-i;
                        return;
                    }
                }
            }
        }
    }
}
void show() {
    for (i=0;i<n;i++) {
        printf("(%d,%d);",ls[i].x0,ls[i].x1);
    }
    printf("\n");
}
void main() {
    n=0;
    c=0;
    while (1) {
        printf("Input x0,x1(x0<x1;0,0 to exit):");
        fflush(stdout);
        rewind(stdin);
        if (2==scanf("%d,%d",&x0,&x1)) {
            if (0==x0&&0==x1) break;
            if (x1>x0) {
                c++;
                if (c>=MAXLINES) {
                    printf("Up to %d!\n",MAXLINES);
                    break;
                }
                add();
                show();
            }
        }
    }
}
水落 2014-03-20
  • 打赏
  • 举报
回复
请问各位大神,在判断出两条线段相交且线段长度不相等并且都在同一条直线上后,再判断其中一条线段的两个端点是否在另一条线段上(不包括该线段的端点),若只要其中一个端点在另一条线段上(不包括该线段的端点),即可得出有多个交点,反之若两个端点都不在另一条线段上(不包括该线段的端点)只有一个交点。。 不知道我的想法对不对?
水落 2014-03-20
  • 打赏
  • 举报
回复
请问各位大神,在判断出两条线段相交且线段长度不相等并且都在同一条直线上后,再判断其中一条线段的两个端点是否在另一条线段上(非端点),若在另一条线段上(非端点),即可得出有多个交点,反之只有一个交点。。 不知道我的想法对不对?
movsd 2014-03-20
  • 打赏
  • 举报
回复
说反了,若tA>1,交点位于线段A的(x1,y1)外侧,若tA<0,交点位于线段A的(x2,y2)外侧
movsd 2014-03-20
  • 打赏
  • 举报
回复
线段A: (x1,y1)-(x2,y2),线段B: (x3,y3)-(x4,y4) 线段A上的点可表示为(x1*tA+x2*(1-tA),y1*tA+y2*(1-tA)), 0<=tA<=1 线段B上的点可表示为(x3*tB+x4*(1-tB),y3*tB+y4*(1-tB)), 0<=tB<=1 求交点,解方程组 x1*tA+x2*(1-tA)=x3*tB+x4*(1-tB) y1*tA+y2*(1-tA)=y3*tB+y4*(1-tB) 若满足0<=tA<=1, 0<=tB<=1, 两线段有交点。 若tA<0,交点位于线段A的(x1,y1)外侧,若tA>1,交点位于线段A的(x2,y2)外侧,线段B同理。
赵4老师 2014-03-20
  • 打赏
  • 举报
回复
《算法精解(C语言实现)》 里面似乎有现成的代码。
水落 2014-03-20
  • 打赏
  • 举报
回复
这个题本来是求两条线段的交点个数,我知道怎么判断这两条线段是否相交,却不知道怎么判断它们的交点个数。。。
赵4老师 2014-03-20
  • 打赏
  • 举报
回复
两条线段所在直线重合时,这两条线段可能: ◆没有公共点 ◆有一个公共点 ◆有无穷多个公共点
dbzhang800 2014-03-20
  • 打赏
  • 举报
回复
平行、相交、重合: 是平面几何中直线的3种位置关系吧,相交和重合 应该是并列关系
derekrose 2014-03-20
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
[quote=引用 3 楼 dbzhang800 的回复:] [quote=引用 2 楼 u013961718 的回复:] 我在OJ上遇到一个题要求交点个数,0个,1个或多个。。。
两条线段相交,只可能有一个交点啊[/quote] 万一重合呢?[/quote] good case!
赵4老师 2014-03-20
  • 打赏
  • 举报
回复
引用 3 楼 dbzhang800 的回复:
[quote=引用 2 楼 u013961718 的回复:] 我在OJ上遇到一个题要求交点个数,0个,1个或多个。。。
两条线段相交,只可能有一个交点啊[/quote] 万一重合呢?
心是菩提树 2014-03-20
  • 打赏
  • 举报
回复
我也很不解啊,最多只有一个焦点啊,除非这两条线段有重叠部分,那得看怎么分的点了

5,529

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧