/*
Copyright 2006-2026 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see .
*/
#include "shapetransform.h"
#include
bool ShapeTransform::isIdentity() const
{
return qFuzzyIsNull(rotation) && qFuzzyIsNull(skewX) && qFuzzyIsNull(skewY)
&& qFuzzyCompare(scaleX, qreal(1)) && qFuzzyCompare(scaleY, qreal(1));
}
QTransform ShapeTransform::linearPart() const
{
QTransform t;
t.rotate(rotation);
t.shear(qTan(qDegreesToRadians(skewX)), qTan(qDegreesToRadians(skewY)));
t.scale(scaleX, scaleY);
return t;
}
QTransform ShapeTransform::toMatrix() const
{
QTransform t;
t.translate(pivot.x(), pivot.y());
t.rotate(rotation);
t.shear(qTan(qDegreesToRadians(skewX)), qTan(qDegreesToRadians(skewY)));
t.scale(scaleX, scaleY);
t.translate(-pivot.x(), -pivot.y());
return t;
}
bool ShapeTransform::operator==(const ShapeTransform &other) const
{
return qFuzzyCompare(rotation, other.rotation)
&& qFuzzyCompare(skewX, other.skewX)
&& qFuzzyCompare(skewY, other.skewY)
&& qFuzzyCompare(scaleX, other.scaleX)
&& qFuzzyCompare(scaleY, other.scaleY)
&& pivot == other.pivot;
}
ShapeTransform decomposeLinear(const QTransform &m)
{
const qreal scaleX = qSqrt(m.m11() * m.m11() + m.m12() * m.m12());
const qreal rotation = qRadiansToDegrees(qAtan2(m.m12(), m.m11()));
const qreal rad = qDegreesToRadians(rotation);
const qreal c = qCos(rad), s = qSin(rad);
// v * R(-rotation): undo the rotation, leaving the pure shear+scale
// contribution the local y-axis picked up from Shear(sh,0)*Scale(sx,sy).
const qreal vx = m.m21() * c + m.m22() * s;
const qreal scaleY = -m.m21() * s + m.m22() * c;
const qreal skewX = qFuzzyIsNull(scaleY) ? 0.0 : qRadiansToDegrees(qAtan(vx / scaleY));
ShapeTransform result;
result.rotation = rotation;
result.skewX = skewX;
result.skewY = 0;
result.scaleX = scaleX;
result.scaleY = scaleY;
return result;
}
QPointF compensatedPositionForNewPivot(
const QPointF &position,
const QPointF &oldPivot,
const QPointF &newPivot,
const QTransform &linearPart)
{
return position + (oldPivot - linearPart.map(oldPivot))
- (newPivot - linearPart.map(newPivot));
}