在 Dart 中绘制省略号

Ellipsis plotting in Dart

提问人:FMorschel 提问时间:10/31/2023 最后编辑:FMorschel 更新时间:11/1/2023 访问量:24

问:

我想为我认识的 Minecraft 玩家创建一个省略号绘图仪。我有一个 Dart 类:

class Ellipse with EquatableMixin implements Comparable<Ellipse> {
  const Ellipse(this.width, this.depth) : assert((width > 0) && (depth > 0));

  final int width;
  final int depth;

  @override
  int compareTo(Ellipse other) {
    final widthResult = width.compareTo(other.width);
    if (widthResult != 0) return widthResult;
    return depth.compareTo(other.depth);
  }

  List<List<bool>> get blocks {
    final blocks = List.generate(depth, (_) => List.filled(width, false));

    final a = width / 2.0; // Semi-major axis
    final b = depth / 2.0; // Semi-minor axis
    final centerX = a;
    final centerY = b;

    for (int x = 0; x < width; x++) {
      for (int y = 0; y < depth; y++) {
        final normalizedX = (x - centerX) / a;
        final normalizedY = (y - centerY) / b;
        if ((normalizedX * normalizedX) + (normalizedY * normalizedY) <= 1) {
          blocks[y][x] = true;
          blocks[depth - y - 1][x] = true; // Ensure vertical symmetry
          blocks[y][width - x - 1] = true; // Ensure horizontal symmetry
          blocks[depth - y - 1][width - x - 1] =
              true; // Ensure both horizontal and vertical symmetry
        }
      }
    }

    return blocks;
  }

  @override
  List<Object?> get props => [width, depth];
}

我想到了在 GridView 中在屏幕上绘图。

我的问题是,这段代码正在绘制:(8, 10, 10, 10, 10, 10, 10, 10, 10, 8) 列/行(对称),但我想要一些更“圆润”的东西,比如 (4, 6, 8, 10, 10, 10, 10, 10, 8, 6, 4)。

谁能帮我算一下?

Dart 数学 矩阵 几何

评论


答:

1赞 fravolt 10/31/2023 #1

理念

我可能会做的是,将论坛用于椭圆上的点:

x^2/a^2 + y^2/b^2 = 1

https://en.wikipedia.org/wiki/Ellipse

Where 和width = 2aheight = 2b

然后,对于网格中的每个像元,您可以计算它偏离 1 的程度,并使用它来确定该位置是否应该有一个块。x^2/a^2 + y^2/b^2

例如,假设您有一个 5x5 的网格。公式变为

x^2/6.25 + y^2/6.25 = 1

一个例子

例如,我快速编写了以下脚本(作为灵感,可以玩弄!

import 'dart:math';

void main() {
  int width = 6;
  int height = 6;
  double treshold = 0.2;

  for (int x = (-width/2).round(); x <= (width/2).round(); x++) {
    String row = '';
    for (int y = (-height/2).round(); y <= (height/2).round(); y++) {
      double value = pow(x, 2)/pow(width/2, 2) + pow(y, 2)/pow(height/2, 2);
      row += '${(value - 1).abs() < treshold ? 'O' : ' '}';
    }
    print(row);
  }
}

对于给定的参数,它输出一个非常漂亮的圆圈(如果字符是方形的):

  OOO  
 O   O 
O     O
O     O
O     O
 O   O 
  OOO  

建议

您可以使用参数,值的 treshold 可能应该取决于宽度和高度参数。圆圈现在以 0,0 为中心,这就是为什么 for 循环变得有点混乱的原因,因此您还可以查看是否可以将公式移过来。

评论

0赞 FMorschel 11/1/2023
感谢您的主要方向!它真的很接近我想要的。它实际上并没有使用您设置的宽度和高度,而是使用 7,但我认为我可以解决它。我会把它开放几天,以便其他人也可以提交他们的建议,以便我将你的建议标记为已接受
1赞 fravolt 11/1/2023
啊,是的,我明白了。我想使用 round/ceil/floor 应该能够解决这个问题,或者在每个 1x1 单元格的中点而不是左上角进行测试(即 (0.5,0.5) 而不是 (0,0))