Flutter林登迈尔系统生成插件lindenmayer_systems的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter林登迈尔系统生成插件lindenmayer_systems的使用

什么是L-Systems (Lindenmayer Systems)?

Lindenmayer Systems (L-Systems) 是由 Aristid Lindenmayer 提出的一种数学模型,用于模拟植物的发展。它们本质上是并行生成语法。L-Systems 根据使用的生产规则类型有所不同。最简单的类型的 L-Systems 是确定性且上下文无关的,或称为 DOL-systems。DOL-system 可以正式定义如下:

1 Let V denote an alphabet, V∗ the set of all words over V, and V+ the set of all nonempty words over V. A string OL-system is an ordered triplet G = {V, ω, P} where V is the alphabet of the system, ω ∈ V + is a nonempty word called the axiom and P ⊂ V × V ∗ is a finite set of productions. A production (a, χ) ∈ P is written as a → χ. The letter a and the word χ are called the predecessor and the successor of this production, respectively. It assumed that for any letter a ∈ V, there is at least one-word χ ∈ V ∗ such that a → χ. If no production is explicitly specified for a given predecessor a ∈ V, the identity production a → a is assumed to belong to the set of productions P. An OL-system is deterministic (noted DOL-system) if and only if for each a ∈ V there is exactly one χ ∈ V ∗ such that a → χ.

一个 DOL-system 的示例如下:

  • 字母表 V 包含字母 {a, b}
  • 生产规则为:
    • a → ab
    • b → a
  • 如果我们以 b 作为公理,则前五次迭代如下:
    • 第0次迭代: “b”
    • 第1次迭代: “a”
    • 第2次迭代: “ab”
    • 第3次迭代: “aba”
    • 第4次迭代: “abaab”
    • 第5次迭代: “abaababa”

如果我们将每个生产字符串的长度进行比较,可以验证斐波那契数列的存在。

使用

DOL-Systems
import 'package:lindenmayer_systems/src/lindenmayer_systems/dol_system/dol_system.dart';
import 'package:lindenmayer_systems/src/production_rules/production_rule.dart';

void main() {
  /// [DolSystem] Examples

  final testDolSystem = DolSystem(
    alphabet: ['A', 'B'],
    axiom: 'AB',
    productionRuleSet: {
      ProductionRule(predecessoror: 'A', successor: 'AB'),
      ProductionRule(predecessor: 'B', successor: 'BA'),
    },
  );

  // Expected result is ABBA
  print(testDolSystem.generate(1));

  testDolSystem.generateAsStream(2)
    ..listen(
      // Should print (ABBA, 1) and ('ABBABAAB', )
      print,
    );
}

示例代码

import 'package:lindenmayer_systems/src/lindenmayer_systems/dol_system/dol_system.dart';
import 'package:lindenmayer_systems/src/production_rules/production_rule.dart';

void main() {
  /// [DolSystem] Examples

  final testDolSystem = DolSystem(
    alphabet: ['A', 'B'],
    axiom: 'AB',
    productionRuleSet: {
      ProductionRule(predecessor: 'A', successor: 'AB'),
      ProductionRule(predecessor: 'B', successor: 'BA'),
    },
  );

  // Expected result is ABBA
  print(testDolSystem.generate(1));

  testDolSystem.generateAsStream(2)
    ..listen(
      // Should print (ABBA, 1) and ('ABBABAAB', 2)
      print,
    );
}

更多关于Flutter林登迈尔系统生成插件lindenmayer_systems的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter林登迈尔系统生成插件lindenmayer_systems的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用lindenmayer_systems插件来生成林登迈尔系统(Lindenmayer Systems,简称L-系统)的示例代码。L-系统是一种用于描述植物形态的递归算法,通过简单的规则和初始字符串可以生成复杂的图案。

首先,你需要在你的pubspec.yaml文件中添加lindenmayer_systems依赖:

dependencies:
  flutter:
    sdk: flutter
  lindenmayer_systems: ^最新版本号  # 请替换为实际的最新版本号

然后运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter应用中使用lindenmayer_systems插件。以下是一个简单的示例,展示如何生成和绘制一个基本的L-系统图案:

import 'package:flutter/material.dart';
import 'package:lindenmayer_systems/lindenmayer_systems.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LindenmayerSystemDemo(),
    );
  }
}

class LindenmayerSystemDemo extends StatefulWidget {
  @override
  _LindenmayerSystemDemoState createState() => _LindenmayerSystemDemoState();
}

class _LindenmayerSystemDemoState extends State<LindenmayerSystemDemo> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Lindenmayer System Demo'),
      ),
      body: Center(
        child: CustomPaint(
          size: Size(double.infinity, double.infinity),
          painter: LindenmayerSystemPainter(),
        ),
      ),
    );
  }
}

class LindenmayerSystemPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 2.0
      ..style = PaintingStyle.stroke;

    // 定义L-系统的规则
    final LindenmayerSystem lSystem = LindenmayerSystem(
      axiom: 'FX',
      rules: {
        'X': 'X+YF+',
        'Y': '-FX-Y',
      },
      angle: 90.0,
      order: 4,  // 迭代次数
    );

    // 计算L-系统的最终字符串
    final String result = lSystem.generate();

    // 解析字符串并绘制图形
    final List<Offset> points = parseTurtleGraphics(result, size, 50.0);

    for (int i = 0; i < points.length - 1; i++) {
      canvas.drawLine(points[i], points[i + 1], paint);
    }
  }

  // 辅助函数:将L-系统的字符串解析为点列表
  List<Offset> parseTurtleGraphics(String result, Size size, double scale) {
    final List<Offset> points = <Offset>[];
    double x = size.width / 2;
    double y = size.height / 2;
    double angle = 0.0;

    for (final char code in result.codeUnits) {
      if (code == 70) {  // 'F' 表示向前移动
        final double radians = angle * (pi / 180.0);
        final double newX = x + (cos(radians) * scale);
        final double newY = y + (sin(radians) * scale);
        points.add(Offset(newX, newY));
        x = newX;
        y = newY;
      } else if (code == 43) {  // '+' 表示顺时针旋转
        angle += 90.0;
      } else if (code == 45) {  // '-' 表示逆时针旋转
        angle -= 90.0;
      } else if (code == 88 || code == 89) {  // 'X' 或 'Y' 通常表示递归规则,这里忽略
        // 不做处理
      }
    }

    return points;
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}

在这个示例中,我们创建了一个Flutter应用,其中包含一个自定义绘图组件LindenmayerSystemPainter。这个组件使用LindenmayerSystem类生成L-系统的字符串,并将其解析为一系列的点,然后使用Canvas.drawLine方法将这些点连接起来绘制图形。

注意,这个示例中的parseTurtleGraphics函数是一个简化的解析器,它只处理基本的指令(向前移动F,顺时针旋转+,逆时针旋转-)。对于更复杂的L-系统规则,你可能需要扩展这个函数以处理更多的指令和特性。

希望这个示例能帮助你理解如何在Flutter中使用lindenmayer_systems插件来生成和绘制L-系统图案。

回到顶部