{GIS算法}计算几何基础-c语言伪代码

12 篇文章 9 订阅
6 篇文章 3 订阅

#####网上相关的原理解析很多,看不懂的可以自己搜索,也可以对比汤国安老师的书《地理信息系统算法基础》来看,这里只贴上代码和部分注释

/*定义点的结构*/
struct point
{
	int x;
	int y;
}
/*定义线段的结构*/
struct line
{
	point start;	//开始结点
	point end;	//结束结点
}
/*计算两条直线的叉积*/
int crossProduct(line *l1,line *l2)	//将直线v1v2转变成从原点出发的直线vt1vt2的叉乘
{
	line l1,l2;
	int result = 0;
	
	lt1.start.x = 0;
	lt1.start.y = 0;
	lt1.end.x = l1->end.x - l1->start.x;
	lt1.end.y = l1->end.y - l1->start.y;
	
	lt2.start.x = 0;
	lt2.start.y = 0;
	lt2.end.x = l2->end.x - l2->start.x;
	lt2.end.y = l2->end.y - l2->start.y;
	
	result = lt1.end.x * lt2.end.y - lt2.end.x * lt1.end.y;
	
	return result;
}
/*折线段的拐向判断*/
int segmentTurn(point p0,point p1,point p2)
{
	int result = 0;
	point pt1,pt2;
	
	pt1.x = p1->x - p0->x;
	pt1.y = p1->y - p0->y;
	pt2.x = p2->x - p0->x;
	pt2.y = p2->y - p0->y;
	
	result = pt2.x * pt1.y - pt1.x * pt2.y;
	
	if (result > 0)
		return 1;
	else if (result < 0)
		return -1;
	else
		return 0;
}
/*判断两直线是否相交*/
//可直接调用叉乘的代码,计算两个向量的叉积,如果为0,则是平行或者重合的,否则两直线相交。
/*判断点是否在线段上*/
int isPointOnSegment(point p,point q1,point q2)
{
	if(segmentTurn(q1,p,q2) == 0)
	{
		if((min(q1->x,q2->x) <= p->x <= max(q1->x,q2->x)) &&
			(min(q1->y,q2->y) <= p->y <= max(q1->y,q2->y))
			return 1;
		else
			return 0;
	}
}
/*判断矩形是否包含点*/
int pointInRectangle(point p,point q1,point q2)	//输入点和矩形主对角线的两个端点
{
	if((min(q1->x,q2->x) <= p->x <= max(q1->x,q2->x) && 
		min(q1->y,q2->y) <= p->y <= max(q1->y,q2->y))
		return 1;
	else
		return 0;
}
/*判断两线段是否相交*/
int segmentIntersec(point q1,point q2,point p1,point p2)
{
	//快速排斥实验
	if(pointInRectangle(p1,q1,q2) || pointInRectangle(p2,q1,q2))
	{
		//跨立实验
		int d1 = segmentTurn(q1,q2,p1);
		int d2 = segmentTurn(q1,q2,p2);
		int d3 = segmentTurn(p1,p2,q1);
		int d4 = segmentTurn(p1,p2,q2);
		
		if(d1 * d2 < 0 && d3 * d4 < 0)
			return 1;
		else if(!d1 && pointOnSegment(p1,q1,q2)
			return 1;
		else if(!d2 && pointOnSegment(p2,q1,q2)
			return 1;
		else if(!d3 && pointOnSegment(q1,p1,p2)
			return 1;
		else if(!d4 && pointOnSegment(q2,p1,p2)
			return 1;
		else
			return 0;
	}
}
/*判断圆是否在矩形内*/
int circleInRectangle(point center,int radius,point r1,point r2)	//输入圆心、半径和矩形主对角线的两个端点
{
	if(pointInRectangle(center,r1,r2))
	{
		int d1 = abs(r1->x - center->x);
		int d2 = abs(r2->x - center->x);
		int d3 = abs(r1->y - center->y);
		int d4 = abs(r2->y - center->y);
		
		if(min(d1,d2,d3,d4) >= radius)
			return 1;
	}
	
	return 0;
}
/*判断点是否在多边形内*/
int isPointInPolygon(point p,point *ch,int n)	//转角法
{
	int wn = 0;
	
	for(int i = 0;i < n;++i)
	{
		if(isPointOnSegment(p,ch[i],ch[(i+1)%n]))
			return -1;	//在边上
		int k = segmentTurn(ch[i],p,ch[(i+1)%n]);
		int d1 = ch[i].y - p.y;
		int d2 = ch[(i+1)%n].y - p.y;
		if(k > 0 && d1 <= 0 && d2 > 0)
			wn++;
		if(k < 0 && d2 <= 0 && d1 > 0)
			wn--;
	}
	
	if(wn != 0)
		return 1;	//在多边形内
	return 0;	//在多边形外
}
/*点集的冒泡排序算法*/
void BubbleSort(point pointSet[],int n)
{	//x坐标小的排在前面;x坐标相同的,y坐标小的排在前面;
	int i,j,flag;
	point temp;
	
	for(i = n -1;i >= 1;--i)
	{
		flag = 0;
		for(j = 1;j <= i;++j)
			if(pointSet[j - 1].x > pointSet[j].x)
			{
				temp = pointSet[j];
				pointSet[j] = pointSet[j - 1];
				pointSet[j - 1] = temp;
				flag = 1;
			}
			else if(pointSet[j - 1].x == pointSet[j].x && pointSet[j - 1].y > pointSet[j].y)
			{
				temp = pointSet[j];
				pointSet[j] = pointSet[j - 1];
				pointSet[j - 1] = temp;
				flag = 1;
			}
		if(flag == 0)
			return;
	}
}
/*判断线段是否在多边形内*/
int isSegmentInPolygon(point p1,point p2,point *ch,int n)
{
	//先判断线段的两个端点是否在多边形内。
	//如果两个端点不全在多边形内,则线段肯定是不在多边形内。
	if(isPointInPolygon(p1,ch,n) && isPointInPolygon(p2,ch,n))	//线段PQ的端点不都在多边形内
		return 0;
	
	//其次,如果线段和多边形的某条边内交(两线段内交是指两线段相交且交点不在两线段的端点),则线段肯定不在多边形内。
	point pointSet[n];	//点集pointSet初始化为空;
	for(int i = 0,j = -1;i < n;++i)
	{
		if(isPointOnSegment(p1,ch[i],ch[(i+1)%n]))	//线段的某个端点在S上
			pointSet[++j] = p1;
		else if(isPointOnSegment(p2,ch[i],ch[(i+1)%n]))
			pointSet[++j] = p2;
		else if(ch[i],p1,p2)	//S的某个端点在线段PQ上
			pointSet[++j] = ch[i];
		else if(segmentIntersec(p1,p2,ch[i],ch[(i+1)%n]))	//线段PQ与S相交
			return 0;	//此时可以判断是内交了  
	}
	
	//如果多边形的某个顶点和线段相交,则必须判断两相交交点之间的线段是否包含于多边形内。
	//将pointSet中的点按照X-Y坐标排序;
	//根据实际情况选择合适的排序方法
	BubbleSort(pointSet[],j);	//冒泡排序
	point p0;	//pointSet中每两个相邻点的中点
	for(int i = 0;i < n-1;++i)
	{
		p0.x = (pointSet[i].x + pointSet[i+1].x) / 2;
		p0.y = (pointSet[i].y + pointSet[i+1].y) / 2;
		if(isPointInPolygon(p0,ch,n) != 1)	//p0不在多边形中
			teturn 0;
	}
	
	return 1;
}

//to be continue…

####参考文章
计算几何的基本代码模板
{计算几何}怎样判断线段相交
判断点及线段是否在多边形内

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

撼沧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值