C语言判断点面位置关系系统.docx
- 文档编号:18003082
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:18
- 大小:65.41KB
C语言判断点面位置关系系统.docx
《C语言判断点面位置关系系统.docx》由会员分享,可在线阅读,更多相关《C语言判断点面位置关系系统.docx(18页珍藏版)》请在冰点文库上搜索。
C语言判断点面位置关系系统
C语言判断点面位置关系系统
一:
程序
/*此程序适用于任意复杂程度的单连通和复连通多边形区域*/
#include
#include
#defineM36/*给定多边形边数*/
floatX[M],Y[M];
floatx,y,t,s,Ymin,Ymax,C,D,sn=0,sp=0,xp,yp,l;
inti,j=0,k=1;
charch[2];
voidinput()/*定义输入坐标函数*/
{
printf("Pleaseinputpointsmadeofarea:
\n");
for(i=0;i { scanf("%f,%f",&X[i],&Y[i]);/*从键盘输入围成多边形的顶点坐标*/ } printf("Pleaseinputonepoint: "); scanf("%f,%f",&x,&y);/*从键盘任意输入一点*/ } floatfunc(floatn)/*定义求绝对值的函数*/ { if(n>0) { returnn; } else { return(-n); } } floatMin(floatm,floatn)/*定义求最小值的函数*/ { if(m<=n) { returnm; } else { returnn; } } floatMax(floatm,floatn)/*定义求最大值的函数*/ { if(m>=n) { returnm; } else { returnn; } } voidsimplefun()/*定义判断点是否在凸多边形上、内、外函数*/ { xp=(X[0]+X[2])/2;/*起点与第三点的中点横坐标*/ yp=(Y[0]+Y[2])/2;/*起点与第三点的中点纵坐标*/ printf("xp=%f\typ=%f\n",xp,yp); for(i=0;i { t=((X[i]-xp)*(Y[i+1]-yp)-(Y[i]-yp)*(X[i+1]-xp))/2; t=func(t); sn=sn+t; if(i==M-2) { sn=sn+func(((X[0]-xp)*(Y[M-1]-yp)-(Y[0]-yp)*(X[M-1]-xp))/2);/*求出凸多边形的总面积并输出*/ } } printf("sn=%f\n",sn); for(i=0;i { t=((X[i]-x)*(Y[i+1]-y)-(Y[i]-y)*(X[i+1]-x))/2; t=func(t); if(t==0) { if((X[i]>X[i+1]&&x>X[i+1]&&x { sp=0;/*如果给定点的横坐标在相邻两点横坐标之间, 则给定点与各个相邻顶点依次围成的面积之和sp赋值为0,并跳出循环*/ break; } elseif((X[i]==X[i+1])&&((Y[i] { sp=0;/*如果给定点的纵坐标在相邻两点纵坐标之间,并且相邻两点横坐标相等 则sp=0,并跳出循环*/ break; } elseif(x==X[i]&&y==Y[i]||x==X[i+1]&&y==Y[i+1]) { sp=0;/*如果给定点的坐标等于相邻两点任意一点的坐标,则sp=0,并跳出循环*/ break; } } sp=sp+t; if(i==M-2)/*最后一点的情况必须单独讨论,同上*/ { l=func(((X[0]-x)*(Y[M-1]-y)-(Y[0]-y)*(X[M-1]-x))/2); if(l==0) { if((X[0]>X[M-1]&&x>X[M-1]&&x { sp=0; break; } elseif((X[0]==X[M-1])&&((Y[0] { sp=0; break; } elseif(x==X[0]&&y==Y[0]||x==X[M-1]&&y==Y[M-1]) { sp=0; break; } } sp=sp+l;/*若前面的if都不执行,则sp就是给定点与各个相邻顶点依次围成的真实的面积之和*/ } } /*最终得出结论*/ if(sp>sn) { printf("Thispoint(%f,%f)isoutoftheregion\n",x,y); } elseif(sp==sn) { printf("Thispoint(%f,%f)isintheregion\n",x,y); } else { printf("Thispoint(%f,%f)isontheedgeoftheregion\n",x,y); } printf("Whethertocontinuetoinputonepoint "); scanf("%s",ch); if(strcmp(ch,"y")==0)/*若输入的字符串为y,则递归调用自身,并将sn,sp赋0,清楚以前的记录重新开始。 区域保持不变,然后又重新输入一个点。 若不为y,则不执行递归调用*/ { sn=0;/*变量初始化*/ sp=0;/*变量初始化*/ printf("Pleasecontinuetoinputonepoint: "); scanf("%f,%f",&x,&y); simplefun(); } } voidonfun()/*定义判断任意给定点与任意复杂程度的单连通域是否在边上、顶点的函数*/ { for(i=0;i { t=((X[i]-x)*(Y[i+1]-y)-(Y[i]-y)*(X[i+1]-x))/2; s=func(t); if(s==0)/*给定点与相邻两点围成的面积为0*/ { if((X[i]>X[i+1]&&(x>X[i+1]&&x { printf("Thepointisontheedgeoftheregion\n"); k=0;/*给定点横坐标x在相邻两点横坐标之间,则将k赋值为0,并跳出循环*/ break; } elseif((X[i]==X[i+1])&&((Y[i] { printf("Thepointisontheedgeoftheregion\n"); k=0;/*相邻两点横坐标相等,并且给定点纵坐标y在相邻两点纵坐标之间,则将k赋值为0,并跳出循环*/ break; } elseif(x==X[i]&&y==Y[i]||x==X[i+1]&&y==Y[i+1]) { printf("Thepointisonthepointoftheregion\n"); k=0;/*给定点坐标与相邻两点任意一点坐标相同,则将k赋值为0,并跳出循环*/ break; } } if(i==M-2)/*最后一点的情况要单独讨论,与上面同理*/ { t=((X[M-1]-x)*(Y[0]-y)-(Y[M-1]-y)*(X[0]-x))/2; s=func(t); if(s==0) { if((X[0]>X[M-1]&&(x>X[M-1]&&x { printf("Thepointisontheedgeoftheregion\n"); k=0; break; } elseif((X[0]==X[M-1])&&((Y[0] { printf("Thepointisontheedgeoftheregion\n"); k=0; break; } elseif(x==X[0]&&y==Y[0]||x==X[M-1]&&y==Y[M-1]) { printf("Thepointisonthepointoftheregion\n"); k=0; break; } } } } } voidout_incarefulfun()/*定义判断给定一点是否在任意单连通区域内、外的函数*/ { Ymin=Y[0]; Ymax=Y[0]; for(i=1;i { Ymin=Min(Ymin,Y[i]);/*找出构成区域的点中的最大和最小的纵坐标*/ Ymax=Max(Ymax,Y[i]); } if(k)/*k为1则执行*/ { for(i=0;i { if(Y[i] { C=(Y[i+1]-y)*X[i]-(Y[i]-y)*X[i+1]; D=Y[i+1]-Y[i]; if(D*(C-D*x)>0)/*过给定点(x,y)的水平线与相邻两点连线的交点横坐标在x的右侧,下同*/ { j++; } } elseif(i>0&&Y[i]==y&&X[i]>x&&(Y[i]! =Ymin&&Y[i]! =Ymax)&&(Y[i-1] { j++;/*过给定点(x,y)的水平线与相邻两点连线的交点就为顶点,并且上相邻点与下相邻点在顶点的两侧,则j=j+1*/ } elseif(i>0&&i =Ymin&&Y[i]! =Ymax)&&Y[i+1]==y)/*给定点与相邻两点三点一线的情况*/ { if(Y[i-1]>Y[i]&&Y[i+1]>Y[i+2]||Y[i-1] { j++; } } elseif(Ymin==y||Ymax==y)/*y为最大纵坐标或最小纵坐标则在面外,直接break*/ { printf("Thepointisoutoftheregion\n"); break; } if(i==M-2)/*最后一点的情况要单独讨论,与上面同理*/ { if(Y[0]==y&&X[0]>x&&(Y[0]! =Ymin&&Y[0]! =Ymax)&&(Y[1] { j++;/*1中i=M-1的情况单独讨论*/ } if(Y[0]==y&&X[0]>x&&(Y[0]! =Ymin&&Y[0]! =Ymax)&&Y[1]==y) { if(Y[M-1]>Y[0]&&Y[1]>Y[2]||Y[M-1] { j++;/*4,5中i=0的情况单独讨论*/ } } if(Y[0] { C=(Y[M-1]-y)*X[0]-(Y[0]-y)*X[M-1]; D=Y[M-1]-Y[0]; if(D*(C-D*x)>0) { j++;/*1中i=M-1的情况单独讨论*/ } } elseif(Y[M-1]==y&&X[M-1]>x&&(Y[M-1]! =Ymin&&Y[M-1]! =Ymax)&&(Y[M-2] { j++;/*2,3中i=M-1的情况单独讨论*/ } elseif(Y[M-2]==y&&X[M-2]>x&&(Y[M-2]! =Ymin&&Y[M-2]! =Ymax)&&Y[M-1]==y) { if(Y[M-3]>Y[M-2]&&Y[M-1]>Y[0]||Y[M-3] { j++;/*4,5中i=M-2的情况单独讨论*/ } } elseif(Y[M-1]==y&&X[M-1]>x&&(Y[M-1]! =Ymin&&Y[M-1]! =Ymax)&&Y[0]==y) { if(Y[M-2]>Y[M-1]&&Y[0]>Y[1]||Y[M-2] { j++;/*4,5中i=M-1的情况单独讨论*/ } } } } printf("j=%d\n",j); if(j%2==0)/*判断j是否为奇数*/ { printf("Thepointisoutoftheregion\n"); } else { printf("Thepointisintheregion\n"); } } } voidcontinue_fun()/*定义询问是否循环判断不同给定点的函数*/ { onfun(); out_incarefulfun(); printf("Whethertocontinuetoinputonepoint "); scanf("%s",ch); if(strcmp(ch,"y")==0)/*若输入y则递归调用,否则不执行*/ { j=0,k=1;/*变量初始化*/ printf("Pleasecontinuetoinputonepoint: "); scanf("%f,%f",&x,&y); continue_fun(); } } voidmenu()/*定义菜单界面函数*/ { printf("\n\n\n\n\n"); printf("\t\t|-------------------POSITION--------------------|\n"); printf("\t\t|\t0.exit|\n"); printf("\t\t|\t|\n"); printf("\t\t|\t1.simplepolygon|\n"); printf("\t\t|\t|\n"); printf("\t\t|\t2.complexpolygon|\n"); printf("\t\t|-----------------------------------------------|\n\n"); printf("\t\t\tchoose(0-2): ");/*输入0则结束程序并退出;输入1则选择凸多边形区域;输入2则选择任意单连通区域*/ } voidmain() { intn; menu(); scanf("%d",&n); while(n) { switch(n) { case1: /*1则判断凸多边形区域*/ { input(); simplefun(); break; } case2: /*2则判断任意单连通区域*/ { input(); continue_fun(); break; } } sn=0;/*变量初始化。 下同*/ sp=0; j=0; k=1; menu();/*调用菜单界面函数*/ scanf("%i",&n);/*输入n重新确定图形类型*/ } } 二: 点面位置关系系统使用说明书 使用说明 运行程序时,首先进入到菜单部分,菜单部分提供了菜单显示和输入功能部分。 其运行效果如图下图所示。 在主界面上输入0——2内的数字,实现相应的功能。 图1点面位置关系系统主界面 主界面输入1时,进入凸多边形类型区域的界面,主界面输入2时,进入任意复杂程度的单连通和复连通类型区域(当然包含凸多边形和凹多边形)的界面。 选择好类型后则提示请输入构成多边形的各个顶点坐标,完成后回车,继续输入判断点回车,给出点面关系。 运行效果如下。 图2输入点、面信息 判断完成后会询问是否继续输入一点进行判断,若输入是则执行刚才的程序;若不是,则返回菜单主界面重新选择区域类型。 运行效果如图。 图3选择是否继续进行 执行完后,输入0结束程序并退出系统。 运行效果如图。 图4退出系统 系统原理 1.判断点与凸多边形的位置关系方法较多,这里我用的是三角形面积法。 如图(这里以7边形为例)。 点在边上或顶点最好判断,只要有一个小三角形面积为零并且给定点坐标x在相邻两点之间或y在相邻两点之间即可。 先计算多边形的面积,方法是找到第一点与低三点连线中点,而后化为多个小三角形求面积之和即可。 再用给定点用同样的方法求面积,若相等则在面内,大于真实面积则在面外。 2.判断点与任意复杂程度的多边形的位置关系,这里我用的是射线法。 若经过给定点的射线(任意方向)穿过奇数条边,则点在面内;穿过偶数条边,则点在面外。 为了便于计算,这里取经过给定点的水平射线。 共分5种情况讨论。 如下图(倾斜方向可能有区别,但不影响判断)。 程序中的例子为一36边形,它包含了以上所有的情况,如图。 注: 1.输入区域坐标时,应按顺时针或逆时针方向连续输入; 2.按上述理论显然也适用于复连通域; 3.若要改变区域边数,可以在宏名M处进行修改,以便判断点与任意边数的多边形位置关系;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 判断 位置 关系 系统