速求 c语言编程 给定n个点的坐标,这n个点依次围成一闭合多边形,再给一点(x,y),判断它是否在多边形中

如题所述

程序代码如下(直接套用函数pnpoly):

int pnpoly(int nvert, float *vertx, float *verty, float testx, float testy)

{

int i, j, c = 0;

for (i = 0, j = nvert-1; i < nvert; j = i++) {

if ( ((verty[i]>testy) != (verty[j]>testy)) &&

(testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )

c = !c;

}

return c;

}

参数说明:

nvert: 多边形的顶点数

vertx, verty: 顶点X坐标和Y坐标分别组成的数组

testx, testy: 需要测试的点的X坐标和Y坐标

扩展资料:

判定一个点是否在多边形内部最简单的方法是使用射线法,因为它能适用于所有类型的多边形,不用考虑特殊的情况而且速度也比较快。

该算法的思想很简单:在多边形外面任意一点画一条虚拟的射线到p(x,y)然后计算该射线与多边形上的边相交的次数。如果该次数是偶数,说明p(x,y)在多边形外,如果是奇数,则在多边形内。

温馨提示:内容为网友见解,仅供参考
第1个回答  推荐于2017-12-16
#include<stdio.h>
#include<math.h>
#include<string.h>
#define esp 1e-8
#define N 30
int dy(double x,double y) { return x > y + esp;}// x > y
int xy(double x,double y) { return x < y - esp;}// x < y
int dyd(double x,double y) { return x > y - esp;}// x >= y
int xyd(double x,double y) { return x < y + esp;}// x <= y
int dd(double x,double y) { return fabs( x - y ) < esp;}// x == y
double max(double x,double y)
{
if(dy(x,y))return x;
return y;
}
double min(double x,double y)
{
if(xy(x,y))return x;
return y;
}
struct point
{
double x,y;
};

double xmult(point a,point b,point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}

int onSegment(point a,point b,point c)
{
if(dd(xmult(a,b,c),0.0)&& dyd(c.x,min(a.x,b.x)) && xyd(c.x,max(a.x,b.x)) &&
dyd(c.y,min(a.y,b.y)) && xyd(c.y,max(a.y,b.y)))
return 1;
return 0;
}

int is_Cross(point a,point b,point c,point d)
{
double d1=xmult(c,d,a);
double d2=xmult(c,d,b);
double d3=xmult(a,b,c);
double d4=xmult(a,b,d);
if(xy(d1*d2,0.0) && xy(d3*d4,0.0))return 1;
if(dd(d1,0.0) && onSegment(c,d,a) || dd(d2,0.0) && onSegment(c,d,b)
|| dd(d3,0.0) && onSegment(a,b,c) || dd(d4,0.0) && onSegment(a,b,d) )
return 1;
return 0;
}

int point_inPolygon(point po,point p[],int n)
{
point a=po,b;
b.x=1e20; b.y=po.y;
p[n]=p[0];
int i,cnt=0;
for(i=0;i<n;i++)
{
//点 po 在多边形某条边上
if(onSegment(p[i],p[i+1],po)) return 1;
//点 po 不在多边形边上
if( !dd(p[i].y,p[i+1].y) )//平行的边不考虑
{
//判断 p[i],p[i+1]两点是否在a,b上
int tmp=-1;
if( onSegment(a,b,p[i]) ) tmp=i;
else if( onSegment(a,b,p[i+1]) ) tmp=i+1;

//对于多边形的顶点和射线a,b相交的情况,如果该顶点是其所属的边上纵坐标较大的顶点,则计数,否则忽略
if( tmp!=-1 && dd(p[tmp].y,max(p[i].y,p[i+1].y)) || tmp==-1 && is_Cross(p[i],p[i+1],a,b) )
cnt++;
}
}
return cnt%2==1;
}
int main()
{
int i,n,m,time=1,blank=0;
point po,p[N];
while(scanf("%d",&n),n)
{
scanf("%d",&m);
memset(p,0,sizeof(p));
for(i=0;i<n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);

if(!blank) blank=1;
else puts("");

printf("Problem %d:\n",time++);
for(i=1;i<=m;i++)
{
scanf("%lf%lf",&po.x,&po.y);
if( point_inPolygon(po,p,n) ) printf("Within\n");
else printf("Outside\n");
}
}
return 0;
}本回答被提问者采纳
第2个回答  2012-02-26
#include <stdio.h>
#include <stdlib.h>
#define MAX_POINT 100

double px[MAX_POINT], py[MAX_POINT]; //n个点的坐标
int n;

double x, y;

//输入n个点和,x,y
void input()
{
int i;
printf("Input n: \n");
scanf("%d", &n);
printf("Input %d points's coordinate: \n", n);
for (i = 0; i < n; i++)
scanf("%lf %lf", px + i, py + i);
printf("Input the point's x and y:\n");
scanf("%lf %lf", &x, &y);
}

//计算两个向量(a,b),(c,d)的叉乘
double muti(double a, double b, double c, double d)
{
return b * c - a * d;
}

int judge()
{
int flag; //判断该点在边的左端还是右端
int tmp, i;

tmp = muti(px[1] - px[0], py[1] - py[0], x - px[0], y - py[0]);
if (tmp > 0) flag = 1;
else if (tmp < 0) flag = -1;
else return 0;

for (i = 2; i < n; i++)
{
tmp = muti(px[i] - px[i - 1], py[i] - py[i - 1],
x - px[i - 1], y - py[i - 1]);
tmp *= flag;
if (tmp <= 0) return 0;
}

return 1;
}

int main()
{
input();
if (judge())
printf("Yes.\n");
else printf("No.\n");
return 0;
}

这个代码的主要大意就是,如果这个点在多边形里面,那么沿着多边形走,这个点一直会在左边或一直在右边。2个向量的叉乘就是计算向量的位置是在左边还是右边。输入有要求,即:1、n至少为3,至少得为三角形吧,2、这n个点必须按多边形顺时针或逆时针依次输入,3、这个多边形必须是凸多边形。本人由于做过和这类似的acm题目,因此此题不是问题。

示例输入:

Input n:
5
Input 5 points's coordinate:
1 2
2 1
3 1
4 2
3 3
Input the point's x and y:
1 1
No.
Hit any key to close this window...
第3个回答  2012-02-25
不知道有没有这个定理,画图看出来的? 由n个点确定的n边型,将x,y代入每条边的方程,1)点不在线上时,如果fn(x,y)>0的真值为偶数,则点在多边形内。2)点在线上时点必在多边形上。
第4个回答  2012-02-24
代码就不写了,我说下自己的思路吧:
可以定好3个点得坐标(因为要构成闭合的图形,至少得3个点才行)
分别计算出每两个点的直线方程,如果点得个数大于3,则根据每两个相距最近的点连成直线
然后还是求出该直线方程
判断要判断的点是否在线上,还是左右侧等……
根据这个去编程写代码,我觉得是可以实现的,还有就是n个点的个数,可以先定下来,当然也可以先初始化一个值,然后递增。

速求c语言编程 给定n个点的坐标,这n个点依次围成一闭合多边形,再给一 ...
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } int onSegment(point a,point b,point c) { if(dd(xmult(a,b,c),0.0)&& dyd(c.x,min(a.x,b.x)) && xyd(c.x,max(a.x,b.x)) && dyd(c.y,min(a.y,b.y)) && xyd(c.y,max(a.y,b.y))) return...

速求c语言编程 给定n个点的坐标,这n个点依次围成一闭合多边形,再给一 ...
c = !c;} return c;} 参数说明:nvert: 多边形的顶点数 vertx, verty: 顶点X坐标和Y坐标分别组成的数组 testx, testy: 需要测试的点的X坐标和Y坐标

C语言程序,输入N个点的坐标,判断能否构成凸多边形
若多边形的边之间除了连接顶点外没有别的公共点,则称该多边形为简单多边形。一个简单多边形将平面分为3个部分:被包围在多边形内的所有点构成了多边形的内部;多边形本身构成多边形的边界;而平面上其余的点构成了多边形的外部。当一个简单多边形及其内部构成一个闭凸集时,称该简单多边形为凸多边形。也就是说凸多边形边界...

...外接圆的圆心,半径。 已知多边形各点的坐标。 “代码好”的同学再...
我觉得只要画圆就可以了,只不过有俩个是半圆,其他的都是些圆的作和.

如果定义f(n)为在c语言编程系统中输入n个字符(不包括空格)能输出的最大...
c++里面从1到50个亿一秒能跑完

c语言(或伪代码)怎样画椭圆(获得椭圆每点的坐标值)?
选取N个点,这N个点的横坐标的取值范围可以根据长轴端点和短轴端点坐标来确定,设N(x,y),根据N到两个焦点的距离之和是2a可列出关于x和y的方程,今儿求出y关于x的函数,由于椭圆是对称的所以这样的函数有两个,分别在x的范围之内找一定量的N的横坐标x,再把x代入上面的函数,就可求出y,把(x...

一百行简单C语言编程,要有解析的啊,速求啊,
printf("%c%c\\n", c2, c1); \/\/ 如只是简单输出 x = (c1 - '0') + (c2 - '0') * 10; \/\/ 转换成数值 printf("%d\\n", x); \/\/ 输出数值 return 0;} \/ \/\/\/输入数字字符串,使得输入的数字第一个输入的排到最后一位,依次排列,最后一个输入的排到第一位 \/ include <stdio...

...的牛顿拉夫逊法的分析!要一个简单的,有具体过程和编程!
平衡节点的电压大小与相位是给定的,通常以它的相角为参考量,即取其电压相角为0。一个独立的电力网中只设一个平衡点。2.5.1.3 高斯迭代法2.5.2 牛顿-拉夫逊法2.5.2.1 原理2.5.2.2 基本步骤基本步骤: (1)形成节点导纳矩阵 (2)将各节点电压设初值U, (3)将节点初值代入相关求式,求出修正方程式的常数项向量 ...

C语言编程题:输入4个整数,要求按由小到大顺序输出怎么编啊?_百度知 ...
利用函数的模块化设计。1、完成整体函数格局,输入、排序、输出。2、输入函数代码如下:3、排序函数代码如下:4、输出函数代码如下:5、执行结果:

用C语言程序编辑对于一次考试成绩进行统计,考M科,有N人(如10人)参加...
{ double N[50][5],M[5]={0},R[50]={0};int i,j,p;for(i=0;i<n;i++)for(j=0;j<m;j++)scanf("%lf",&N[i][j]);for(i=0;i<n;i++){ for(j=0;j<m;j++)R[i]=R[i]+N[i][j];R[i]=(double)R[i]\/j;} for(j=0;j<m;j++){ for(i=0;i<n;i+...

相似回答