判断一个多边形是否是凸多边形

本文探讨了一种通过计算向量叉积来判断多边形是否为凸多边形的方法,并给出了具体的C++实现代码。文章详细解释了算法的逻辑,并分享了调试过程中遇到的问题及解决方案。

一个很简单的问题看了好久,但就是提交不过,也看不出是哪出了问题

问题为:判断一个多边形是否是凸多边形

我的思路是这样的:
建立x[],y[]这两个数组用来存放坐标,计算两个向量,然后让计算它们的叉积,如果叉积小于零,说明后一个向量在前一个向量的右侧,即顺时针方向,只要有一个是这样的情况,则不符合条件。然后就是叉积大于零,符合条件,计数加一。等于零共线,直接跳过。最后,要是计数大于3,就说明是凸边形,因为三角形肯定是凸边形。

我觉得思路没啥问题呀,想不通

以下代码:
 

#include<iostream>
#include <cmath>
using namespace std;
double eps = 1e-10;
int main(){
    int n;
	while(cin>>n){
		if(n==0){
			break;
		}
	
		double x[10000],y[10000];
		for(int i=1;i<=n;i++){
			cin>>x[i]>>y[i];
		}	
		if(n==1||n==2){
			cout<<"concave"<<endl;
			continue;
		}
		x[n+1]=x[1];
		y[n+1]=y[1];
		x[n+2]=x[2];
		y[n+2]=y[2];
		int num=0;
		for(int i=1;i<=n;i++){
			if((x[i+1]-x[i])*(y[i+2]-y[i+1])-(x[i+2]-x[i+1])*(y[i+1]-y[i])>0){
				num++;
			//	cout<<num<<'*'<<endl;
				
				continue;
			}else if(fabs((x[i+1]-x[i])*(y[i+2]-y[i+1])-(y[i+1]-y[i])*(x[i+2]-x[i+1]))<eps){
			    continue;
			}else{
				cout<<"concave"<<endl;
				break;
			}
			
		}
		if(num>=3){
			cout<<"convex"<<endl;
		}
	}
	
}

终于想通了,哇哇哇哇哇哇,笨死

#include<iostream>
#include <cmath>
using namespace std;
double eps = 1e-10;
int main(){
    int n;
	while(cin>>n){
		if(n==0){
			break;
		}
	
		double x[10000],y[10000];
		for(int i=1;i<=n;i++){
			cin>>x[i]>>y[i];
		}	
		if(n==1||n==2){
			cout<<"concave"<<endl;
			continue;
		}
		x[n+1]=x[1];
		y[n+1]=y[1];
		x[n+2]=x[2];
		y[n+2]=y[2];
		int num=0;
		for(int i=1;i<=n;i++){
			if((x[i+1]-x[i])*(y[i+2]-y[i+1])-(x[i+2]-x[i+1])*(y[i+1]-y[i])>0){
				num++;
			//	cout<<num<<'*'<<endl;
			}else if(fabs((x[i+1]-x[i])*(y[i+2]-y[i+1])-(y[i+1]-y[i])*(x[i+2]-x[i+1]))<eps){
			    num==num;
			}else{
				cout<<"concave"<<endl;
				break;
			}
			if(num>=3&&i==n){
				cout<<"convex"<<endl;
			}
		}
	
	}
	
}

 

### 判断多边形凸多边形还是凹多边形的 C++ 实现 为了判断一个多边形凸多边形还是凹多边形,可以利用向量叉积的概念。具体来说,可以通过计算每条边与其下一条边之间的转向(顺时针或逆时针),并观察这些转向是否一致来实现这一目标。 #### 基本原理 对于一个简单多边形(不自交或多边形顶点按顺序排列),如果所有的连续边对都具有相同的转向,则该多边形凸多边形;否则为凹多边形。通过计算相邻边的叉积方向,可以确定其转向[^3]。 以下是具体的 C++ 实现: ```cpp #include <iostream> #include <vector> #include <cmath> using namespace std; // 定义点结构体 struct Point { double x, y; }; // 计算两向量的叉积 double crossProduct(const Point& A, const Point& B, const Point& C) { return (B.x - A.x) * (C.y - A.y) - (B.y - A.y) * (C.x - A.x); } // 判断多边形是否凸多边形 bool isConvexPolygon(const vector<Point>& points) { int n = points.size(); if (n < 3) return false; // 至少需要三个点才能构成多边形 bool hasPositive = false, hasNegative = false; for (int i = 0; i < n; ++i) { Point A = points[i]; Point B = points[(i + 1) % n]; // 下一点 Point C = points[(i + 2) % n]; // 再下一点 double cp = crossProduct(A, B, C); // 叉积 if (cp > 0) hasPositive = true; if (cp < 0) hasNegative = true; if (hasPositive && hasNegative) return false; // 凹多边形 } return true; // 凸多边形 } int main() { vector<Point> polygon = {{0, 0}, {4, 0}, {4, 4}, {0, 4}}; // 示例:矩形(凸) // vector<Point> polygon = {{0, 0}, {4, 0}, {4, 4}, {1, 1}, {0, 4}}; // 示例:五角星(凹) if (isConvexPolygon(polygon)) { cout << "The polygon is Convex." << endl; } else { cout << "The polygon is Concave." << endl; } return 0; } ``` #### 解释 上述代码实现了以下功能: 1. **定义 `Point` 结构体**:用于存储二维平面上的点坐标。 2. **计算叉积函数**:给定三点 \(A\)、\(B\) 和 \(C\),返回由 \((B-A)\times(C-B)\) 表示的方向矢量的 z 轴分量。此值正负表示转向方向。 3. **遍历所有边对**:依次检查每一对连续边的转向一致性。如果有任意两个边对的转向相反,则判定为凹多边形。 4. **时间复杂度分析**:由于只需一次扫描即可完成检测操作,因此整体算法的时间复杂度为 \(O(n)\),其中 \(n\) 是多边形顶点数。 注意,在实际应用中可能还需要处理一些特殊情况,比如共线点或者非常接近零的小数值误差等问题[^4]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值