Qt 求两个多边形组合后的凸包,Qt里的排序方法
来源:互联网 发布:整进度计划软件 编辑:程序博客网 时间:2024/06/14 09:14
unique是很关键的一步,不可省略,一般的题目都给定了不会有重合点,但是实际项目应用里保不准。
可以证明,交点不会出现在凸包上。
这里的排序方法非常好用,不用单独写一个cmp函数了,相当于直接把这个函数写在sort下面
qreal DataConvert::getCrossProduct(const QPointF &iPointA,const QPointF &iPointB,const QPointF &iPointC){//获得a->b和a->c的叉积
//x1y2-x2y1
return ((iPointB.x()-iPointA.x())*(iPointC.y()-iPointA.y())-(iPointC.x()-iPointA.x())*(iPointB.y()-iPointA.y()));
}
QPolygonF DataConvert::getPolysConvexHull(const QPolygonF &iFirstPoly, const QPolygonF &iSecondPoly){//获取两个poly的凸包
if(iFirstPoly.size()==0)return iSecondPoly;
if(iSecondPoly.size()==0)return iFirstPoly;
int Size1=iFirstPoly.size();
int Size2=iSecondPoly.size();
//第一步把所有结点取出来
QVector<QPointF>AllPoints;
for(int i=0;i<Size1;i++){
AllPoints.push_back(iFirstPoly[i]);
}
for(int i=0;i<Size2;i++){
AllPoints.push_back(iSecondPoly[i]);
}
//其实交点可以不加,因为交点一定不属于凸包,凸包一定是两个多边形顶点的子集
// for(int i=0;i<Size1;i++){
// QLineF FirstLine=QLineF(iFirstPoly[i],iFirstPoly[(i+1)%Size1]);
// //AllPoints.push_back(FirstLine.p1());
// for(int j=0;j<Size2;j++){
// QLineF SecondLine=QLineF(iSecondPoly[j],iSecondPoly[(j+1)%Size2]);
// //AllPoints.push_back(SecondLine.p1());
// QPointF intersectionPoint;
// int interV=FirstLine.intersect(SecondLine,&intersectionPoint);
// if(interV==1)AllPoints.push_back(intersectionPoint);
// }
// }
//第二步,寻找基点,此步可以并到第一步里,但是为了代码清晰,便于阅读,多O(n)的复杂度也不太影响
int startPosition=0;
for(int i=0;i<AllPoints.size();i++){
if(AllPoints[startPosition].y()>AllPoints[i].y()||
(AllPoints[startPosition].y()==AllPoints[i].y()&&AllPoints[startPosition].x()>AllPoints[i].x())){
startPosition=i;
}
//AllPoints.swap()
}
if(startPosition>0){
qSwap(AllPoints[0],AllPoints[startPosition]);
}
//第三,给点按照与基点的叉积排序
qSort(AllPoints.begin()+1,AllPoints.end(),[=](const QPointF &aa,const QPointF &bb){
qreal crossAns=DataConvert::getCrossProduct(AllPoints[0],aa,bb);
qreal length1=QLineF(AllPoints[0],aa).length();
qreal length2=QLineF(AllPoints[0],bb).length();
return (crossAns>0||(crossAns==0&&length1>length2));
});
for(int i=0;i<AllPoints.size();i++){
qDebug()<<AllPoints[i].x()<<" fuck "<<AllPoints[i].y()<<"\n";
}
//第四unique
QVector<QPointF>uniquePoints;
for(int i=0;i<AllPoints.size();i++){
uniquePoints.push_back(AllPoints[i]);
int j=i;
while(i<AllPoints.size()){
if(DataConvert::fuzzyEqual(AllPoints[(i+1)%AllPoints.size()].x(),AllPoints[j].x())&&
DataConvert::fuzzyEqual(AllPoints[(i+1)%AllPoints.size()].y(),AllPoints[j].y())){
i++;
}
else break;
}
}
//第五开始算凸包
int s[1000];
s[0]=0;
s[1]=1;
int top=1;
for(int i=2;i<uniquePoints.size();i++){
while(top&&DataConvert::getCrossProduct(uniquePoints[s[top-1]],uniquePoints[s[top]],uniquePoints[i])<0)top--;
s[++top]=i;
}
top++;
qDebug()<<"top "<<top<<"\n";
//把凸包里的点组成新的poly输出
QPolygonF newpoly;
for(int i=0;i<top;i++){
newpoly.push_back(uniquePoints[s[i]]);
}
return newpoly;
}
1 0
- Qt 求两个多边形组合后的凸包,Qt里的排序方法
- 在Qt里调用WindowAPI的方法
- Qt里的moc
- Qt里的OpenGL
- Qt里的.ui
- 求多边形或轮廓的凸包(Hull)
- 求多边形或轮廓的凸包(Hull)
- Qt 组合键的实现
- 求数组排序后相邻两个数的最大差值
- Qt里的智能指针
- Qt里的原子操作
- QT里,windows下获取窗口句柄的方法
- qwt 在QT+mingw32里的编译方法
- 正方形组合而成的多边形的顶点排序算法
- QT安装包的下载
- QT的TCP传文件防止粘包方法
- QT常用的方法
- qt绘图的方法
- Sort with Swap(0,*)(25)
- c++知识体系
- jQuery中find和filter的区别
- myeclise10 svn: E210004: Number is larger than maximum 解决方案
- 总体性能——加载模块性能
- Qt 求两个多边形组合后的凸包,Qt里的排序方法
- Apache2.2.x 安装与配置详解
- sublime
- wireshark过滤抓包与过滤查看
- 知识体系图
- 堆、栈记录
- linux 下shell中的“-e,-d,-f”什么意思
- 解决多行标题,末行宽度不够时显示省略
- 日常随记