Вращение вокруг пользовательской точки поворота - PullRequest
0 голосов
/ 30 июня 2018

Я действительно не знаю линейной алгебры, я пытаюсь изучить ее из-за этой проблемы сейчас. Я почти уверен, что это простой вопрос для тех, кто знает линейную алгебру.

Я постараюсь объяснить и показать несколько картинок, видео и кода, чтобы описать это лучше.

Во-первых, моя цель на первый взгляд довольно проста. Это создать этот вид анимации

Теперь мне удалось добраться почти до цели

Widget getWidget(Type type)
{
    Matrix4 _pmat(num pv) {
        return new Matrix4(
            1.0, 0.0, 0.0, 0.0, //
            0.0, 1.0, 0.0, 0.0, //
            0.0, 0.0, 1.0, pv * 0.001, //
            0.0, 0.0, 0.0, 1.0,
        );
    }

    double delta = _panDown ? _delta : _animationOffset.value;
    Matrix4 perspective = _pmat(0.35);

    if (type == Type.NEXT)
    {
        delta -= MAX_DELTA;
    }

    double xOffset = ((delta / 70) / 2.5) * (deviceWidth / 2);
    double zOffset = (delta / 70 / (math.pi - 0.55)).abs() * 180.0;
    double rotateY = (math.pi - (delta / 3) * math.pi / 180) - math.pi;

    if (type == Type.NEXT)
    {
        xOffset = ((delta / 70) / 2.5) * (deviceWidth);
        zOffset *= 2;
    }

    perspective.translate(xOffset, 0.0, zOffset);

    double angleOffset = delta * -0.5;

    return new Transform(
        alignment: FractionalOffset.center,
        transform: perspective.scaled(1.0, 1.0, 1.0)
            ..rotateX(0.0)
            ..rotateY(rotateY)
            ..rotateZ(0.0),
        child: new Container(color: Colors.red),
    );
}

Как вы можете видеть, я в настоящее время перемещаю каждую "страницу" с помощью "магических чисел", и я называю это магическими числами, потому что я довольно чертовски новичок в линейной алгебре, и то, что я сделал здесь, с небольшим пониманием того, есть + проб и ошибок. Ясно, что не правильный путь.

У меня есть дельта, которая в основном является смещением, взятым у пользователя GestureDetector , чтобы просто поиграть с ним.

Теперь, со всеми образцами этого кубического перехода, которые я видел, скажем, например, в CSS, они просто вращали / переводили каждую отдельную сторону. А потом переместил / повернул «камеру» или родителя, наверное?

Я тоже пытался сделать этот метод:

enter image description here

Как это:

Widget getWidget(Type type)
{
    AlignmentGeometry alignmentGeometry;
    Matrix4 matrix4;

    switch (type)
    {
        case Type.PREVIOUS:
            alignmentGeometry = FractionalOffset.center;
            matrix4 = Matrix4.identity()
                ..setEntry(3, 2, 0.001) // perspective
                ..rotateY(-90.0 * math64.degrees2Radians)
                ..translate(deviceWidth / 2, 0.0, deviceWidth / 2);
            break;

        case Type.CURRENT:
            alignmentGeometry = FractionalOffset.center;
            matrix4 = Matrix4.identity()
                ..setEntry(3, 2, 0.001);
            break;

        case Type.NEXT:
            alignmentGeometry = FractionalOffset.center;
            matrix4 = Matrix4.identity()
                ..setEntry(3, 2, 0.001) // perspective
                ..rotateY(90.0 * math64.degrees2Radians)
                ..translate(-deviceWidth / 2, 0.0, deviceWidth / 2);
            break;
    }

    return new Transform(
        alignment: alignmentGeometry,
        transform: matrix4,
        child: new Container(
            color: type == Type.NEXT ? Colors.green : type == Type.PREVIOUS ? Colors.red : Colors.black.withOpacity(0.5),
        ),
    );
}

А потом давайте просто повернем родительское право?

Widget build(BuildContext context)
{
    List<Widget> widgets = [];

    widgets.add(getWidget(Type.PREVIOUS));
    widgets.add(getWidget(Type.CURRENT));
    widgets.add(getWidget(Type.NEXT));

    return new Scaffold(
        key: _scaffoldKey,
        body: new Container(
            color: Colors.black,
            child: new GestureDetector(
                child: new Container(
                    color: Colors.white,
                    child: new Transform(
                        alignment: FractionalOffset.center,
                        transform: Matrix4.identity()
                            ..setEntry(3, 2, 0.0001)
                            ..rotateY(45.0 * math64.degrees2Radians),
                            child: new Stack(
                                children: widgets,
                            ),
                    )
                ),
            )
        )
    );
}
нет

No:

enter image description here

При 90 градусах все исчезнет.

Теперь я понимаю, что мне нужно что-то вроде «точки поворота вокруг оси» или изменить «точку отсчета» или «точку привязки», даже не зная, как это назвать.

Итак, чтобы представить это, скажем, например, у нас также есть нижняя сторона. поэтому я хочу, чтобы центр этой нижней стороны (скажем, например, в кубе) . Так это будет выглядеть так:

enter image description here

Теперь, если я поверну эту "исходную точку" по оси Y, я должен получить правильную анимацию, верно?

...