Bug 409894

Summary: Rotation Shift+Space action drifts when rotating
Product: [Applications] krita Reporter: Dmitry Kazakov <dimula73>
Component: Shortcuts and Canvas Input SettingsAssignee: Krita Bugs <krita-bugs-null>
Status: RESOLVED FIXED    
Severity: minor CC: asrcpq, griffinvalley, info, talk2rene
Priority: NOR    
Version: git master (please specify the git hash!)   
Target Milestone: ---   
Platform: Other   
OS: All   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Dmitry Kazakov 2019-07-17 10:58:14 UTC
STEPS TO REPRODUCE
1. Rotate the canvas when Shift+Space action on a very low speed
2. See that the canvas drifts from side-to-side

The problem happens becasue of implementation of KisCanvasController::rotateCanvas, which uses widget coordinates as a still point instead of document coordinates. Widget coordinates are imprecise, therefore the drift happens.
Comment 1 wolthera 2019-09-21 16:21:25 UTC
Considering there's a cause identified, I am going to mark this as confirmed.
Comment 2 Dmitry Kazakov 2020-08-20 22:25:52 UTC
*** Bug 374828 has been marked as a duplicate of this bug. ***
Comment 3 Alvin Wong 2022-05-22 15:17:11 UTC
*** Bug 445564 has been marked as a duplicate of this bug. ***
Comment 4 Dmitry Kazakov 2023-03-30 13:56:00 UTC
Git commit b8c33501ac27d9822f7113026a8c3c6cb7d68e40 by Dmitry Kazakov, on behalf of Maciej Jesionowski.
Committed on 30/03/2023 at 13:55.
Pushed by dkazakov into branch 'master'.

Fix the canvas rotation drift

This patch changes how the canvas rotation is calculated.
Previously the rotation was applied continuously, updating the canvas
transformation with very small angle increments, which led to numerical
error accumulating throughout the operation.

The new method is modal. When canvas rotation action begins, the current
transformation is saved and used as the base, while the user adjusts the
angle. Once the action ends, the final transformation is applied in one
go.

**EDIT 3/27/2023:** With the last update I verified on an Android tablet with Rotate Mode touch events (rotate without zoom) and it's working correctly.

Test Plan
---------

Just create a new document and rotate canvas through various means. The fix is specifically for fine-grained rotation (SHIFT+SPACE drag). I tested on Windows and checked interactions of various rotation methods (discrete, and with the controls on the status bar).

This forum post shows the before and after behavior: [LINK](https://krita-artists.org/t/bug-rotate-canvas-drift/40832/7)

Formalities Checklist
--------------------- 

- [x] I confirmed this builds.
- [x] I confirmed Krita ran and the relevant functions work (on Windows).
- [ ] I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!) Canvas rotate test is marked as broken.
- [x] I made sure my commits build individually and have good descriptions as per [KDE guidelines](https://community.kde.org/Policies/Commit_Policy).
- [x] I made sure my code conforms to the standards set in the HACKING file.
- [x] I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per [KDE Licensing Policy](https://community.kde.org/Policies/Licensing_Policy).

_**Reminder: the reviewer is responsible for merging the patch, this is to ensure at the least two people can build the patch. In case a patch breaks the build, both the author and the reviewer should be contacted to fix the build.**_
_**If this is not possible, the commits shall be reverted, and a notification with the reasoning and any relevant logs shall be sent to the mailing list, kimageshop@kde.org.**_

M  +10   -0    libs/ui/canvas/kis_canvas_controller.cpp
M  +3    -0    libs/ui/canvas/kis_canvas_controller.h
M  +34   -1    libs/ui/canvas/kis_coordinates_converter.cpp
M  +5    -0    libs/ui/canvas/kis_coordinates_converter.h
M  +37   -32   libs/ui/input/kis_rotate_canvas_action.cpp
M  +1    -0    libs/ui/input/kis_rotate_canvas_action.h

https://invent.kde.org/graphics/krita/commit/b8c33501ac27d9822f7113026a8c3c6cb7d68e40