参照《计算机图形学》一书中的描述,多边形(polygon)是由三个及以上的顶面坐标位置描述的平面图形,这些顶点由多边形的边顺序连接。多边形的一个内角由两个相邻边形成的边界之内的角。如果所有内角均小于180度则称为凸(convex)多边形,否则为凹(concave)多边形。
百度多边形凹凸的判断,主要方法有:凸包法、叉乘法(大于和小于180度的符号相反)、辛普森面积法。这里主要学习下叉乘的运用,并配上 C++ Qt 示例代码。
判断方法:为每一条边建立一个向量,使用相邻边的叉积来测试凹凸性。凸多边形的所有相邻边向量叉积同号。如果出现一些正一些负则为凹多边形。
(网上找的图,可以 ABC 分别看作 xyz。食指指向 x ,手心朝向 y 轴,大拇指向上的方向恰好是 z 的方向)
示例:
void Widget::paintEvent(QPaintEvent *)
{
//顶点,第一个为凸,第二个为凹
/*QVector<QPointF> points = QVector<QPointF>()
<<QPointF(50,50)<<QPointF(150,50)<<QPointF(150,100)
<<QPointF(100,150)<<QPointF(50,100);*/
QVector<QPointF> points = QVector<QPointF>()
<<QPointF(50,50)<<QPointF(150,50)<<QPointF(150,150)
<<QPointF(100,100)<<QPointF(50,150);
//第一个点加到尾便于计算
points.append(points.first());
//凹标记
bool concave = false;
//边向量
for(int i = 0; i < points.size() - 2; i++)
{
const QPointF &p1 = points.at(i);
const QPointF &p2 = points.at(i + 1);
const QPointF &p3 = points.at(i + 2);
int cross_k = (p2.x() - p1.x()) * (p3.y() - p2.y()) -
(p2.y() - p1.y()) * (p3.x() - p2.x());
if(cross_k < 0){ //大于还是小于和边向量取的方向有关
concave = true;
break;
}
}
//叉乘判断凹凸
//绘制,红色凹绿色凸
QPainter painter(this);
painter.setBrush(concave ? Qt::red : Qt::green);
painter.drawPolygon(points);
}