/*! \fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const Creates and returns a QPolygon representation of the given \a rectangle, mapped into the coordinate system defined by this matrix. The rectangle's coordinates are transformed using the following formulas: \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 3 Polygons and rectangles behave slightly differently when transformed (due to integer rounding), so \c{matrix.map(QPolygon(rectangle))} is not always the same as \c{matrix.mapToPolygon(rectangle)}. \sa mapRect(), {QMatrix#Basic Matrix Operations}{Basic Matrix Operations} */ QPolygon QMatrix::mapToPolygon(const QRect &rect) const { QPolygon a(4); qreal x[4], y[4]; if (_m12 == 0.0F && _m21 == 0.0F) { x[0] = _m11*rect.x() + _dx; y[0] = _m22*rect.y() + _dy; qreal w = _m11*rect.width(); qreal h = _m22*rect.height(); if (w < 0) { w = -w; x[0] -= w; } if (h < 0) { h = -h; y[0] -= h; } x[1] = x[0]+w; x[2] = x[1]; x[3] = x[0]; y[1] = y[0]; y[2] = y[0]+h; y[3] = y[2]; } else { qreal right = rect.x() + rect.width(); qreal bottom = rect.y() + rect.height(); MAPDOUBLE(rect.x(), rect.y(), x[0], y[0]); MAPDOUBLE(right, rect.y(), x[1], y[1]); MAPDOUBLE(right, bottom, x[2], y[2]); MAPDOUBLE(rect.x(), bottom, x[3], y[3]); } #if 0 int i; for(i = 0; i< 4; i++) qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], qRound(x[i]), qRound(y[i])); qDebug("width=%f, height=%f", qSqrt((x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0])), qSqrt((x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]))); #endif // all coordinates are correctly, tranform to a pointarray // (rounding to the next integer) a.setPoints(4, qRound(x[0]), qRound(y[0]), qRound(x[1]), qRound(y[1]), qRound(x[2]), qRound(y[2]), qRound(x[3]), qRound(y[3])); return a; }
QRect QMatrix::mapRect(const QRect &rect) const { QRect result; if (_m12 == 0.0F && _m21 == 0.0F) { int x = qRound(_m11*rect.x() + _dx); int y = qRound(_m22*rect.y() + _dy); int w = qRound(_m11*rect.width()); int h = qRound(_m22*rect.height()); if (w < 0) { w = -w; x -= w; } if (h < 0) { h = -h; y -= h; } result = QRect(x, y, w, h); } else { // see mapToPolygon for explanations of the algorithm. qreal x0, y0; qreal x, y; MAPDOUBLE(rect.left(), rect.top(), x0, y0); qreal xmin = x0; qreal ymin = y0; qreal xmax = x0; qreal ymax = y0; MAPDOUBLE(rect.right() + 1, rect.top(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); MAPDOUBLE(rect.right() + 1, rect.bottom() + 1, x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); MAPDOUBLE(rect.left(), rect.bottom() + 1, x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); result = QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin)); } return result; }
/*! \fn QRectF QMatrix::mapRect(const QRectF &rectangle) const Creates and returns a QRectF object that is a copy of the given \a rectangle, mapped into the coordinate system defined by this matrix. The rectangle's coordinates are transformed using the following formulas: \snippet doc/src/snippets/code/src_gui_painting_qmatrix.cpp 2 If rotation or shearing has been specified, this function returns the \e bounding rectangle. To retrieve the exact region the given \a rectangle maps to, use the mapToPolygon() function instead. \sa mapToPolygon(), {QMatrix#Basic Matrix Operations}{Basic Matrix Operations} */ QRectF QMatrix::mapRect(const QRectF &rect) const { QRectF result; if (_m12 == 0.0F && _m21 == 0.0F) { qreal x = _m11*rect.x() + _dx; qreal y = _m22*rect.y() + _dy; qreal w = _m11*rect.width(); qreal h = _m22*rect.height(); if (w < 0) { w = -w; x -= w; } if (h < 0) { h = -h; y -= h; } result = QRectF(x, y, w, h); } else { qreal x0, y0; qreal x, y; MAPDOUBLE(rect.x(), rect.y(), x0, y0); qreal xmin = x0; qreal ymin = y0; qreal xmax = x0; qreal ymax = y0; MAPDOUBLE(rect.x() + rect.width(), rect.y(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); MAPDOUBLE(rect.x() + rect.width(), rect.y() + rect.height(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); MAPDOUBLE(rect.x(), rect.y() + rect.height(), x, y); xmin = qMin(xmin, x); ymin = qMin(ymin, y); xmax = qMax(xmax, x); ymax = qMax(ymax, y); result = QRectF(xmin, ymin, xmax-xmin, ymax - ymin); } return result; }
void MATRIX_map_point(MATRIX *matrix, int *x, int *y) { double nx; double ny; MAPDOUBLE(matrix, *x, *y, nx, ny); *x = DROUND(nx); *y = DROUND(ny); }
/*! \fn QPolygonF QMatrix::map(const QPolygonF &polygon) const \overload Creates and returns a QPolygonF object that is a copy of the given \a polygon, mapped into the coordinate system defined by this matrix. */ QPolygonF QMatrix::map(const QPolygonF &a) const { int size = a.size(); int i; QPolygonF p(size); const QPointF *da = a.constData(); QPointF *dp = p.data(); for(i = 0; i < size; i++) { MAPDOUBLE(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp); } return p; }
void QMatrix::map(qreal x, qreal y, qreal *tx, qreal *ty) const { MAPDOUBLE(x, y, *tx, *ty); }
void MATRIX_map_rect(MATRIX *matrix, int *x, int *y, int *w, int *h) { int rx, ry, rw, rh; if (matrix->m12 == 0.0F && matrix->m21 == 0.0F) { rx = DROUND(matrix->m11 * *x + matrix->dx); ry = DROUND(matrix->m22 * *y + matrix->dy); rw = DROUND(matrix->m11 * *w); rh = DROUND(matrix->m22 * *h); if (rw < 0) { rw = -rw; rx -= rw - 1; } if (rh < 0) { rh = -rh; ry -= rh-1; } } else { int left = *x; int top = *y; int right = *x + *w; int bottom = *y + *h; double x0, y0; double x, y; MAPDOUBLE(matrix, left, top, x0, y0 ); double xmin = x0; double ymin = y0; double xmax = x0; double ymax = y0; MAPDOUBLE(matrix, right, top, x, y ); xmin = DMIN( xmin, x ); ymin = DMIN( ymin, y ); xmax = DMAX( xmax, x ); ymax = DMAX( ymax, y ); MAPDOUBLE(matrix, right, bottom, x, y ); xmin = DMIN( xmin, x ); ymin = DMIN( ymin, y ); xmax = DMAX( xmax, x ); ymax = DMAX( ymax, y ); MAPDOUBLE(matrix, left, bottom, x, y ); xmin = DMIN( xmin, x ); ymin = DMIN( ymin, y ); xmax = DMAX( xmax, x ); ymax = DMAX( ymax, y ); double ww = xmax - xmin; double hh = ymax - ymin; xmin -= ( xmin - x0 ) / ww; ymin -= ( ymin - y0 ) / hh; xmax -= ( xmax - x0 ) / ww; ymax -= ( ymax - y0 ) / hh; rx = DROUND(xmin); ry = DROUND(ymin); rw = DROUND(xmax) - DROUND(xmin) + 1; rh = DROUND(ymax) - DROUND(ymin) + 1; } *x = rx; *y = ry; *w = rw; *h = rh; }