C++ (Qt)int CheckPolygonClockwise( const QPolygonF & poly );
C++ (Qt)int CheckPolygonClockwise( const QPolygonF & poly ){ double M_z = 0.0; int size = poly.size(); QPointF a = poly[size-1]; QPointF b = poly[0]-poly[size-1]; M_z += (a.x() * b.y() - a.y() * b.x()); for (int i = 0; i < size-1; ++i) { a = poly[i]; b = poly[i+1]-poly[i]; M_z += (a.x() * b.y() - a.y() * b.x()); } return (M_z > 0.0) ? 1 : -1;}
C++ (Qt)QPointF b = poly[size-1]-poly[0];
C++ (Qt)QPointF b = poly[0]-poly[size-1];
C++ (Qt)// возвращает знаковую удвоенную площадь треугольника (O(0, 0), p0, p1)inline qreal Square( const QPointF & p0, const QPointF & p1 ) { return p0.x * p1.y - p0.y * p1.x;} // возвращает знаковую удвоенную площадь полигона// нужна для выяснения направления обхода но может пригодиться и сама по себеqreal PolySquare( const QPolygonF & poly ){ qreal sum = 0.0f; int i, limit = poly.size(); for (i = 0; i < limit; ++i) sum += Square(poly[i], poly[(i + 1) % limit]); return sum;} // зная знак площади, возвращаем направление обходаenum { POLY_ORDER_UNDEF = -1, // площадь полигона слишком мала (вырожденный) POLY_ORDER_CW = 0, // по часовой POLY_ORDER_СCW = 1, // против часовой };const qreal POLY_FUDGE = 1.0e-5f; // предел точности int PolyClockwise( qreal polySquare ){ if (fabs(polySquare) < POLY_FUDGE) return POLY_ORDER_UNDEF; return (polySquare > 0.0) ? POLY_ORDER_СCW : POLY_ORDER_CW;}