diff options
Diffstat (limited to 'src/2geom/affine.cpp')
| -rw-r--r-- | src/2geom/affine.cpp | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/2geom/affine.cpp b/src/2geom/affine.cpp index 738d0fc48..e9ca5748e 100644 --- a/src/2geom/affine.cpp +++ b/src/2geom/affine.cpp @@ -222,6 +222,29 @@ bool Affine::isNonzeroRotation(Coord eps) const { are_near(_c[0]*_c[0] + _c[1]*_c[1], 1.0, eps); } +/** @brief Check whether this matrix represents a non-zero rotation about any point. + * @param eps Numerical tolerance + * @return True iff the matrix is of the form + * \f$\left[\begin{array}{ccc} + a & b & 0 \\ + -b & a & 0 \\ + c & d & 1 \end{array}\right]\f$, \f$a^2 + b^2 = 1\f$ and \f$a \neq 1\f$. */ +bool Affine::isNonzeroNonpureRotation(Coord eps) const { + return !are_near(_c[0], 1.0, eps) && + are_near(_c[0], _c[3], eps) && are_near(_c[1], -_c[2], eps) && + are_near(_c[0]*_c[0] + _c[1]*_c[1], 1.0, eps); +} + +/** @brief For a (possibly non-pure) non-zero-rotation matrix, calculate the rotation center. + * @pre The matrix must be a non-zero-rotation matrix to prevent division by zero, see isNonzeroNonpureRotation(). + * @return The rotation center x, the solution to the equation + * \f$A x = x\f$. */ +Point Affine::rotationCenter() const { + Coord x = (_c[2]*_c[5]+_c[4]-_c[4]*_c[3]) / (1-_c[3]-_c[0]+_c[0]*_c[3]-_c[2]*_c[1]); + Coord y = (_c[1]*x + _c[5]) / (1 - _c[3]); + return Point(x,y); +}; + /** @brief Check whether this matrix represents pure horizontal shearing. * @param eps Numerical tolerance * @return True iff the matrix is of the form @@ -342,8 +365,7 @@ bool Affine::preservesDistances(Coord eps) const /** @brief Check whether this transformation flips objects. * A transformation flips objects if it has a negative scaling component. */ bool Affine::flips() const { - // TODO shouldn't this be det() < 0? - return cross(xAxis(), yAxis()) > 0; + return det() < 0; } /** @brief Check whether this matrix is singular. @@ -356,7 +378,7 @@ bool Affine::isSingular(Coord eps) const { } /** @brief Compute the inverse matrix. - * Inverse is a matrix (denoted \f$A^{-1}) such that \f$AA^{-1} = A^{-1}A = I\f$. + * Inverse is a matrix (denoted \f$A^{-1}\f$) such that \f$AA^{-1} = A^{-1}A = I\f$. * Singular matrices have no inverse (for example a matrix that has two of its columns equal). * For such matrices, the identity matrix will be returned instead. * @param eps Numerical tolerance @@ -369,7 +391,7 @@ Affine Affine::inverse() const { fabs(_c[2]) + fabs(_c[3])); // a random matrix norm (either l1 or linfty if(mx > 0) { Geom::Coord const determ = det(); - if (!rel_error_bound(determ, mx*mx)) { + if (!rel_error_bound(std::sqrt(fabs(determ)), mx)) { Geom::Coord const ideterm = 1.0 / (determ); d._c[0] = _c[3] * ideterm; |
