ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

计算几何初步

2022-01-19 01:02:34  阅读:156  来源: 互联网

标签:cnt return point int cross 初步 dcmp 计算 几何


计算几何基础

1. 判断点是否在线段上

叉积必为 0 保证在延长线上,点积不大于 0 保证不会在线段的两侧.  

int Onsegment(point tmp, point a, point b) {  
	if(dcmp(cross(a - tmp, b - tmp)) == 0 && dcmp(dot(a - tmp, b - tmp)) <= 0)
		return 1;
	return 0; 
}

  

2. 判断两个线段是否有相交(不在端点处)

看 $\mathrm{(a,b)}$ 和 $\mathrm{(c,d)}$ 分别都在各自两侧.  

// 前面是线段上,后面是不在线段上相交.  
int Line_Intersect(point a, point b, point c, point d) {   
	double x1 = cross(b - a, c - a), y1 = cross(b - a, d - a);  
	double x2 = cross(d - c, a - c), y2 = cross(d - c, b - c);   
	if(!dcmp(x1) || !dcmp(x2) || !dcmp(y1) || !dcmp(y2)) {
		bool f1 = Onsegment(a, c, d); 
		bool f2 = Onsegment(b, c, d); 
		bool f3 = Onsegment(c, a, b); 
		bool f4 = Onsegment(d, a, b); 
		bool f = (f1 | f2 | f3 | f4); 
		return f;   
	}
	if(dcmp(x1) * dcmp(y1) < 0 && dcmp(x2) * dcmp(y2) < 0) 
		return 1; 
	return 0; 
}

  

3. 凸包

$\mathrm{Graham}$ 扫描法:

将 $\mathrm{y}$ 坐标最小的点作为基准给其他点按照角度逆时针排序. 

加入新点的时候看之前加的边是否在新加的边的左侧,如果是则弹掉.  

// b 在 a 的逆时针为正,夹角为 a 转到 b 的有向角度(sin)   
double cross(Vector a, Vector b) {
	return a.x * b.y - a.y * b.x; 
}              
int n ; 
point p[N], A[N]; 
bool cmp2(point i, point j) {
	int t = dcmp(cross(i - p[1], j - p[1]));    
	if(t != 0) 
		return t > 0; 
	else {
		return dis(i, p[1]) < dis(j, p[1]); 
	}   
}    
int main() {
	// setIO("input");   
	scanf("%d", &n); 
	for(int i = 1; i <= n ; ++ i) {
		scanf("%lf%lf", &p[i].x, &p[i].y); 
		// if(p[i].y < p[1].y) swap(p[i], p[1]); 
	}      
	sort(p + 1, p + 1 + n);   
	sort(p + 2, p + 1 + n, cmp2);  
	int cnt = 1; 
	A[1] = p[1]; 
	for(int i = 2; i <= n ; ++ i) {   
		while(cnt > 1 && dcmp(cross(A[cnt] - A[cnt - 1], p[i] - A[cnt])) != 1)        
			-- cnt ; 
		A[++ cnt] = p[i];       
	}
	A[++ cnt] = p[1];   
	double ans = 0.0;             
	for(int i = 1; i < cnt ; ++ i) 
		ans += dis(A[i], A[i + 1]);  
	printf("%.2f", ans); 
	return 0; 
}

  

 

标签:cnt,return,point,int,cross,初步,dcmp,计算,几何
来源: https://www.cnblogs.com/brady12/p/15820614.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有