2

How do you rotate, using Matrix4x4 transform, a QML item around another axis than z, with the center of the item as origin of the transformation?

To rotate around the y axis with (0,0) as origin, I tried naively:

Image {
    source: "..."
    width: 100
    height: 100

    transform: Matrix4x4 {
        property real a: Math.PI / 4
        matrix: Qt.matrix4x4(
            Math.cos(a), 0, -Math.sin(a), 0,
            0,           1, 0,            0,
            Math.sin(a), 0, Math.cos(a),  0,
            0,           0, 0,            1)
    }
}

As a result, I get a cut width item whereas I am looking for a perspective effect.

Can anyone explain how the transformation matrix of QML items works?

Fabien
  • 549
  • 7
  • 22
  • I think that your question is a duplicate of [this question](http://stackoverflow.com/questions/25919378/qt-transform-matrix). Does the answer provide the information you are searching for? – BaCaRoZzo Feb 21 '15 at 16:23
  • Almost. I just don't understand how to get some perspective when rotating around x or y – Fabien Feb 22 '15 at 01:19

2 Answers2

1

Here's comment from Unity 8:

// Rotating 3 times at top/bottom because that increases the perspective.
// This is a hack, but as QML does not support real 3D coordinates
// getting a higher perspective can only be done by a hack. This is the most
// readable/understandable one I could come up with.

Link to source code: https://github.com/ubports/unity8/blob/xenial/qml/Launcher/LauncherDelegate.qml#L287

plasmatron
  • 143
  • 1
  • 8
0

The thing to be careful about is there appears to be clipping around z >= 0, where the object is technically in front of your monitor. To ensure the object stays on screen, you need to translate it so that it remains behind the monitor. In the following example, because I know the object is 300x300 and that it is centered, I know that I only need to push it into the screen by 150 pixels.

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

Page {
    property real xrotation: 0
    property real yrotation: 0
    property real zrotation: 0

    Image {
        width: 300
        height: 300
        anchors.centerIn: parent
        source: "image-32.svg"
        sourceSize: Qt.size(width, height)
        transform: Matrix4x4 {
            matrix: (() => {
                 let m = Qt.matrix4x4();
                 m.translate(Qt.vector3d(150, 150, -150));
                 m.rotate(zrotation, Qt.vector3d(0, 0, 1));
                 m.rotate(yrotation, Qt.vector3d(0, 1, 0));
                 m.rotate(xrotation, Qt.vector3d(1, 0, 0));
                 m.translate(Qt.vector3d(-150, -150, 0));
                 return m;
            })()
        }
    }

    Timer {
        running: xbutton.pressed
        repeat: true
        interval: 100
        onTriggered: xrotation += 5
    }

    Timer {
        running: ybutton.pressed
        repeat: true
        interval: 100
        onTriggered: yrotation += 5
    }

    Timer {
        running: zbutton.pressed
        repeat: true
        interval: 100
        onTriggered: zrotation += 5
    }

    footer: Frame {
        RowLayout {
            width: parent.width
            Button {
                id: xbutton
                text: "X"
            }
            Button {
                id: ybutton
                text: "Y"
            }
            Button {
                id: zbutton
                text: "Z"
            }
            Button {
                text: "Reset"
                onClicked: {
                     xrotation = yrotation = zrotation = 0;
                }
            }
        }
    }
}

// image-32.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path d="M2 5v22h28V5zm27 21H3v-5.474l4.401-3.5 1.198.567L14 13.106l5 4.531 3.506-3.123L29 20.39zm-5.997-12.422a.652.652 0 0 0-.926-.033L19 16.293l-4.554-4.131a.652.652 0 0 0-.857-.013L8.45 16.417l-.826-.391a.642.642 0 0 0-.72.117L3 19.248V6h26v13.082zM19 8a2 2 0 1 0 2 2 2.002 2.002 0 0 0-2-2zm0 3a1 1 0 1 1 1-1 1.001 1.001 0 0 1-1 1z"/><path fill="none" d="M0 0h32v32H0z"/></svg>

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75