1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Deprecated AffineTransform::getScaleFactor() as it was producing incorrect values for transforms containing rotations. Added getDeterminant() method for getting the determinant of the transform

This commit is contained in:
ed 2020-03-30 18:34:19 +01:00
parent 5315160e51
commit 26c9468dc5
7 changed files with 62 additions and 11 deletions

View file

@ -1190,12 +1190,12 @@ private:
{
*rectToCheck = convertFromHostBounds (*rectToCheck);
auto scale = editor->getTransform().getScaleFactor();
auto transformScale = std::sqrt (std::abs (editor->getTransform().getDeterminant()));
auto minW = (double) (constrainer->getMinimumWidth() * scale);
auto maxW = (double) (constrainer->getMaximumWidth() * scale);
auto minH = (double) (constrainer->getMinimumHeight() * scale);
auto maxH = (double) (constrainer->getMaximumHeight() * scale);
auto minW = (double) (constrainer->getMinimumWidth() * transformScale);
auto maxW = (double) (constrainer->getMaximumWidth() * transformScale);
auto minH = (double) (constrainer->getMinimumHeight() * transformScale);
auto maxH = (double) (constrainer->getMaximumHeight() * transformScale);
auto width = (double) (rectToCheck->right - rectToCheck->left);
auto height = (double) (rectToCheck->bottom - rectToCheck->top);

View file

@ -236,9 +236,46 @@ bool AffineTransform::isOnlyTranslation() const noexcept
&& mat11 == 1.0f;
}
float AffineTransform::getDeterminant() const noexcept
{
return (mat00 * mat11) - (mat01 * mat10);
}
float AffineTransform::getScaleFactor() const noexcept
{
return (std::abs (mat00) + std::abs (mat11)) / 2.0f;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class AffineTransformTests : public UnitTest
{
public:
AffineTransformTests()
: UnitTest ("AffineTransform", UnitTestCategories::maths)
{}
void runTest() override
{
beginTest ("Determinant");
{
constexpr float scale1 = 1.5f, scale2 = 1.3f;
auto transform = AffineTransform::scale (scale1)
.followedBy (AffineTransform::rotation (degreesToRadians (72.0f)))
.followedBy (AffineTransform::translation (100.0f, 20.0f))
.followedBy (AffineTransform::scale (scale2));
expect (approximatelyEqual (std::sqrt (std::abs (transform.getDeterminant())), scale1 * scale2));
}
}
};
static AffineTransformTests timeTests;
#endif
} // namespace juce

View file

@ -264,11 +264,23 @@ public:
*/
float getTranslationY() const noexcept { return mat12; }
/** Returns the approximate scale factor by which lengths will be transformed.
/** Returns the determinant of the transform. */
float getDeterminant() const noexcept;
/** This method has been deprecated.
You can calculate the scale factor using:
@code
std::sqrt (std::abs (AffineTransform::getDeterminant()))
@endcode
This method produces incorrect values for transforms containing rotations.
Returns the approximate scale factor by which lengths will be transformed.
Obviously a length may be scaled by entirely different amounts depending on its
direction, so this is only appropriate as a rough guide.
*/
float getScaleFactor() const noexcept;
JUCE_DEPRECATED (float getScaleFactor() const noexcept);
/* A ready-to-use identity transform - now deprecated.
@deprecated If you need an identity transform, just use AffineTransform() or {}.

View file

@ -96,7 +96,7 @@ public:
float getPhysicalPixelScaleFactor() const noexcept
{
return isOnlyTranslated ? 1.0f : std::abs (complexTransform.getScaleFactor());
return isOnlyTranslated ? 1.0f : std::sqrt (std::abs (complexTransform.getDeterminant()));
}
void moveOriginInDeviceSpace (Point<int> delta) noexcept

View file

@ -580,7 +580,7 @@ void Direct2DLowLevelGraphicsContext::addTransform (const AffineTransform& trans
float Direct2DLowLevelGraphicsContext::getPhysicalPixelScaleFactor()
{
return currentState->transform.getScaleFactor();
return std::sqrt (std::abs (currentState->transform.getDeterminant()));
}
bool Direct2DLowLevelGraphicsContext::clipToRectangle (const Rectangle<int>& r)

View file

@ -1300,7 +1300,8 @@ float Component::getApproximateScaleFactorForComponent (Component* targetCompone
transform = transform.scaled (target->getDesktopScaleFactor());
}
return (transform.getScaleFactor() / Desktop::getInstance().getGlobalScaleFactor());
auto transformScale = std::sqrt (std::abs (transform.getDeterminant()));
return transformScale / Desktop::getInstance().getGlobalScaleFactor();
}
//==============================================================================

View file

@ -1024,7 +1024,8 @@ private:
float getStrokeWidth (const String& strokeWidth) const noexcept
{
return transform.getScaleFactor() * getCoordLength (strokeWidth, viewBoxW);
auto transformScale = std::sqrt (std::abs (transform.getDeterminant()));
return transformScale * getCoordLength (strokeWidth, viewBoxW);
}
PathStrokeType getStrokeFor (const XmlPath& xml) const