diff options
author | Alexander Larsson <alexl@redhat.com> | 2020-02-11 10:00:34 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2020-02-11 13:51:06 +0100 |
commit | 1f0438e7fe7a6580116d95a922948ee63c7547b4 (patch) | |
tree | 9b38f3291283225f02ca3b64cf764bc2daad4ba4 /gsk/gsktransform.c | |
parent | af98c46d04d86e192349d20711d36dbb1de9bc9d (diff) | |
download | gtk+-1f0438e7fe7a6580116d95a922948ee63c7547b4.tar.gz |
gsk: Fix angle normalization
I was getting assertions that normalize_angle() failed the
result < 260 check. Doing some research on this it turns out
to be a precision issue. If the incomming angle is very slightly
below zero, then adding 360 to it may end up with exactly 360.
I simplified the code a bit to avoid division and rounding, because in
practice most angles will be "just outside" the 0-360 degree anyway.
And i also added a workaround for the "result is 360" case by just
setting it to 0.
Diffstat (limited to 'gsk/gsktransform.c')
-rw-r--r-- | gsk/gsktransform.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/gsk/gsktransform.c b/gsk/gsktransform.c index b474ec4114..c8e0d321b7 100644 --- a/gsk/gsktransform.c +++ b/gsk/gsktransform.c @@ -821,20 +821,28 @@ static const GskTransformClass GSK_ROTATE_TRANSFORM_CLASS = static inline float normalize_angle (float angle) { - float f; if (angle >= 0 && angle < 360) return angle; - f = angle - (360 * ((int)(angle / 360.0))); + while (angle >= 360) + angle -= 360; + while (angle < 0) + angle += 360; - if (f < 0) - f = 360 + f; + /* Due to precision issues we may end up with a result that is just + * past the allowed range when rounded. For example, something like + * -epsilon + 360 when rounded to a float may end up with 360. + * So, we handle these cases by returning the exact value 0. + */ + + if (angle >= 360) + angle = 0; - g_assert (f < 360.0); - g_assert (f >= 0.0); + g_assert (angle < 360.0); + g_assert (angle >= 0.0); - return f; + return angle; } /** |