📄 qtransform.cpp
字号:
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(); qreal fx, fy; 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]); } // 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;}/*! Creates a transformation matrix, \a trans, that maps a unit square to a four-sided polygon, \a quad. Returns true if the transformation is constructed or false if such a transformation does not exist. \sa quadToSquare(), quadToQuad()*/bool QTransform::squareToQuad(const QPolygonF &quad, QTransform &trans){ if (quad.count() != 4) return false; qreal dx0 = quad[0].x(); qreal dx1 = quad[1].x(); qreal dx2 = quad[2].x(); qreal dx3 = quad[3].x(); qreal dy0 = quad[0].y(); qreal dy1 = quad[1].y(); qreal dy2 = quad[2].y(); qreal dy3 = quad[3].y(); double ax = dx0 - dx1 + dx2 - dx3; double ay = dy0 - dy1 + dy2 - dy3; if (!ax && !ay) { //afine transform trans.setMatrix(dx1 - dx0, dy1 - dy0, 0, dx2 - dx1, dy2 - dy1, 0, dx0, dy0, 1); } else { double ax1 = dx1 - dx2; double ax2 = dx3 - dx2; double ay1 = dy1 - dy2; double ay2 = dy3 - dy2; /*determinants */ double gtop = ax * ay2 - ax2 * ay; double htop = ax1 * ay - ax * ay1; double bottom = ax1 * ay2 - ax2 * ay1; double a, b, c, d, e, f, g, h; /*i is always 1*/ if (!bottom) return false; g = gtop/bottom; h = htop/bottom; a = dx1 - dx0 + g * dx1; b = dx3 - dx0 + h * dx3; c = dx0; d = dy1 - dy0 + g * dy1; e = dy3 - dy0 + h * dy3; f = dy0; trans.setMatrix(a, d, g, b, e, h, c, f, 1.0); } return true;}/*! \fn bool QTransform::quadToSquare(const QPolygonF &quad, QTransform &trans) Creates a transformation matrix, \a trans, that maps a four-sided polygon, \a quad, to a unit square. Returns true if the transformation is constructed or false if such a transformation does not exist. \sa squareToQuad(), quadToQuad()*/bool QTransform::quadToSquare(const QPolygonF &quad, QTransform &trans){ if (!squareToQuad(quad, trans)) return false; bool invertible = false; trans = trans.inverted(&invertible); return invertible;}/*! Creates a transformation matrix, \a trans, that maps a four-sided polygon, \a one, to another four-sided polygon, \a two. Returns true if the transformation is possible; otherwise returns false. This is a convenience method combining quadToSquare() and squareToQuad() methods. It allows the input quad to be transformed into any other quad. \sa squareToQuad(), quadToSquare()*/bool QTransform::quadToQuad(const QPolygonF &one, const QPolygonF &two, QTransform &trans){ QTransform stq; if (!quadToSquare(one, trans)) return false; if (!squareToQuad(two, stq)) return false; trans *= stq; //qDebug()<<"Final = "<<trans; return true;}/*! Sets the matrix elements to the specified values, \a m11, \a m12, \a m13 \a m21, \a m22, \a m23 \a m31, \a m32 and \a m33. Note that this function replaces the previous values. QMatrix provides the translate(), rotate(), scale() and shear() convenience functions to manipulate the various matrix elements based on the currently defined coordinate system. \sa QTransform()*/void QTransform::setMatrix(qreal m11, qreal m12, qreal m13, qreal m21, qreal m22, qreal m23, qreal m31, qreal m32, qreal m33){ affine._m11 = m11; affine._m12 = m12; m_13 = m13; affine._m21 = m21; affine._m22 = m22; m_23 = m23; affine._dx = m31; affine._dy = m32; m_33 = m33; m_type = TxNone; m_dirty = TxProject;}QRect QTransform::mapRect(const QRect &rect) const{ QRect result; if (isAffine() && !isRotating()) { int x = qRound(affine._m11*rect.x() + affine._dx); int y = qRound(affine._m22*rect.y() + affine._dy); int w = qRound(affine._m11*rect.width()); int h = qRound(affine._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, fx, fy; 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); qreal w = xmax - xmin; qreal h = ymax - ymin; xmin -= (xmin - x0) / w; ymin -= (ymin - y0) / h; xmax -= (xmax - x0) / w; ymax -= (ymax - y0) / h; result = QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin)+1, qRound(ymax)-qRound(ymin)+1); } return result;}/*! \fn QRectF QTransform::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: \code x' = m11*x + m21*y + dx y' = m22*y + m12*x + dy if (is not affine) { w' = m13*x + m23*y + m33 x' /= w' y' /= w' } \endcode 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(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*/QRectF QTransform::mapRect(const QRectF &rect) const{ QRectF result; if (isAffine() && !isRotating()) { qreal x = affine._m11*rect.x() + affine._dx; qreal y = affine._m22*rect.y() + affine._dy; qreal w = affine._m11*rect.width(); qreal h = affine._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, fx, fy; 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;}/*! \fn QRect QTransform::mapRect(const QRect &rectangle) const \overload Creates and returns a QRect object that is a copy of the given \a rectangle, mapped into the coordinate system defined by this matrix. Note that the transformed coordinates are rounded to the nearest integer.*//*! Maps the given coordinates \a x and \a y into the coordinate system defined by this matrix. The resulting values are put in *\a tx and *\a ty, respectively. The coordinates are transformed using the following formulas: \code x' = m11*x + m21*y + dx y' = m22*y + m12*x + dy \endcode The point (x, y) is the original point, and (x', y') is the transformed point. \sa {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*/void QTransform::map(qreal x, qreal y, qreal *tx, qreal *ty) const{ qreal fx, fy; MAPDOUBLE(x, y, *tx, *ty);}/*! \overload Maps the given coordinates \a x and \a y into the coordinate system defined by this matrix. The resulting values are put in *\a tx and *\a ty, respectively. Note that the transformed coordinates are rounded to the nearest integer.*/void QTransform::map(int x, int y, int *tx, int *ty) const{ int fx, fy; MAPINT(x, y, *tx, *ty);}/*! Returns the QTransform cast to a QMatrix. */const QMatrix &QTransform::toAffine() const{ return affine;}/*! Returns the transformation type of this matrix. */QTransform::TransformationType QTransform::type() const{ if (m_dirty != TxNone && m_dirty >= m_type) { if (m_dirty > TxShear && (!qFuzzyCompare(m_13, 0) || !qFuzzyCompare(m_23, 0))) m_type = TxProject; else if (m_dirty > TxScale && (!qFuzzyCompare(affine._m12, 0) || !qFuzzyCompare(affine._m21, 0))) { const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22; if (qFuzzyCompare(dot, 0)) m_type = TxRotate; else m_type = TxShear; } else if (m_dirty > TxTranslate && (!qFuzzyCompare(affine._m11, 1) || !qFuzzyCompare(affine._m22, 1) || !qFuzzyCompare(m_33, 1))) m_type = TxScale; else if (m_dirty > TxNone && (!qFuzzyCompare(affine._dx, 0) || !qFuzzyCompare(affine._dy, 0))) m_type = TxTranslate; else m_type = TxNone; m_dirty = TxNone; } return static_cast<TransformationType>(m_type);}/*! Returns the transform as a QVariant.*/QTransform::operator QVariant() const{ return QVariant(QVariant::Transform, this);}/*! \fn bool QTransform::isInvertible() const Returns true if the matrix is invertible, otherwise returns false. \sa inverted()*//*! \fn qreal QTransform::det() const Returns the matrix's determinant.*//*! \fn qreal QTransform::m11() const Returns the horizontal scaling factor. \sa scale(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m12() const Returns the vertical shearing factor. \sa shear(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m21() const Returns the horizontal shearing factor. \sa shear(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m22() const Returns the vertical scaling factor. \sa scale(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::dx() const Returns the horizontal translation factor. \sa m31(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::dy() const Returns the vertical translation factor. \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m13() const Returns the horizontal projection factor. \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m23() const Returns the vertical projection factor. \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m31() const Returns the horizontal translation factor. \sa dx(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m32() const Returns the vertical translation factor. \sa dy(), translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::m33() const Returns the division factor. \sa translate(), {QTransform#Basic Matrix Operations}{Basic Matrix Operations}*//*! \fn qreal QTransform::determinant() const Returns the matrix's determinant.*//*! \fn bool QTransform::isIdentity() const Returns true if the matrix is the identity matrix, otherwise returns false. \sa reset()*//*! \fn bool QTransform::isAffine() const Returns true if the matrix represent an affine transformation, otherwise returns false.*//*! \fn bool QTransform::isScaling() const Returns true if the matrix represents a scaling transformation, otherwise returns false. \sa reset()*//*! \fn bool QTransform::isRotating() const Returns true if the matrix represents some kind of a scaling transformation, otherwise returns false. \sa reset()*//*! \fn bool QTransform::isTranslating() const Returns true if the matrix represents a translating transformation, otherwise returns false. \sa reset()*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -