【问题标题】:rotate 3D on X in Flutter在 Flutter 中的 X 上旋转 3D
【发布时间】:2018-10-31 15:20:34
【问题描述】:

我一直在使用 Flutter 旋转,

new Matrix4.identity() ..rotateX(degrees * 3.1415927 / 180),

但是,问题是,我希望它类似于下图。 我可以使用 Flutter 在 x 轴上实现类似 3D 的旋转吗?

即使存在从 3D 到 2D 的映射或有替代方案 那会得到相同的结果。 提前致谢。

OpenCV 中的示例图像:How to calculate perspective transform for OpenCV from rotation angles?

【问题讨论】:

    标签: rotation flutter transformation


    【解决方案1】:

    您可以使用Transform 小部件将矩阵应用到它的孩子。

    这是一个将Transform 与动画框架相结合以在 X、Y 和 Z 方向上旋转的示例。

    import 'dart:math' as math;
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(
        new MaterialApp(
          home: new Home(),
        ),
      );
    }
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => new _HomeState();
    }
    
    class _HomeState extends State<Home> with SingleTickerProviderStateMixin {
      AnimationController animationController;
      Animation<double> rotateX;
      Animation<double> rotateY;
      Animation<double> rotateZ;
    
      @override
      initState() {
        super.initState();
        animationController = new AnimationController(
          duration: const Duration(seconds: 2),
          vsync: this,
        )..repeat();
        print('bar');
        rotateX = new Tween<double>(
          begin: .0,
          end: 1.0,
        ).animate(new CurvedAnimation(
          parent: animationController,
          curve: new Interval(.0, 1 / 3),
        ));
        rotateY = new Tween<double>(
          begin: .0,
          end: 1.0,
        ).animate(new CurvedAnimation(
          parent: animationController,
          curve: new Interval(1 / 3, 2 / 3),
        ));
        rotateZ = new Tween<double>(
          begin: .0,
          end: .5,
        ).animate(new CurvedAnimation(
          parent: animationController,
          curve: new Interval(2 / 3, 1.0),
        ));
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new Center(
            child: new AnimatedBuilder(
              animation: animationController,
              builder: (context, child) {
                final card = new SizedBox(
                  width: 42.0,
                  height: 42.0,
                  child: new Card(
                    color:
                        animationController.value >= 1 / 6 && animationController.value <= 3 / 6 ? Colors.blue : Colors.red,
                  ),
                );
    
                return new Transform(
                  transform: new Matrix4.rotationX(rotateX.value * math.pi)
                    ..multiply(new Matrix4.rotationY(rotateY.value * math.pi))
                    ..multiply(new Matrix4.rotationZ(rotateZ.value * math.pi)),
                  alignment: Alignment.center,
                  child: card,
                );
              },
            ),
          ),
        );
      }
    }
    

    【讨论】:

    • 我运行了代码。但它仍然是 2D 旋转,不像问题图。
    【解决方案2】:

    感谢this discussionthis repo,经过一天多的寻找答案,

    static 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,
        );
    }
    
    Matrix4 perspective = _pmat(1.0);
    
    
    // then use it
    
    new Center(
          child: new Transform(
            child: new FittedBox(
              fit: BoxFit.fill,
              child: LogoWidget(),
            ),
            alignment: FractionalOffset.center,
            transform: perspective.scaled(1.0, 1.0, 1.0)
              ..rotateX(math.pi - degrees * math.pi / 180)
              ..rotateY(0.0)
              ..rotateZ(0.0)
          ),
        );
    

    这是结果图片

    请阅读little theory关于这个主题。

    【讨论】:

    【解决方案3】:
    class MyTransform extends StatefulWidget {
      const MyTransform({Key? key}) : super(key: key);
    
      @override
      _MyTransformState createState() => _MyTransformState();
    }
    
    class _MyTransformState extends State<MyTransform> {
      double x = 0;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Transform(
              transform: Matrix4.identity()
                    ..setEntry(3, 2, 0.003) // col = 2, row = 3 & 0.003 = depth perception in the Z direction
                    ..rotateX(x), // (Both are equal because both are 4D identity matrix)
              // transform: Matrix4(
              //   1, 0, 0, 0,
              //   0, 1, 0, 0,
              //   0, 0, 1, 0.003,
              //   0, 0, 0, 1,
              // )..rotateX(x),
              alignment: FractionalOffset.center,
              child: GestureDetector(
                onPanUpdate: (details) {
                  setState(() {
                    x = x + details.delta.dy / 100;
                  });
                },
                child: Container(
                  color: Colors.red,
                  height: 200.0,
                  width: 200.0,
                ),
              ),
            ),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多