You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart实现Minecraft椭圆绘制:优化圆润度的数学问题求助

Minecraft椭圆绘制工具优化方案

问题分析

你当前的Dart代码生成的椭圆行激活块数为(8, 10, 10, 10, 10, 10, 10, 10, 10, 8),核心问题是只要点在椭圆内部就标记为激活,导致中间大部分行直接铺满整个宽度,边缘收缩过于突兀。需要调整数学逻辑,让激活块数从边缘到中心逐渐递增,实现(4, 6, 8, 10, 10, 10, 10, 8, 6, 4)的圆润渐变效果。

优化后的代码

替换原类中的blocks getter方法:

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

  final a = width / 2.0; // 半长轴
  final b = depth / 2.0; // 半短轴
  final centerX = a;
  final centerY = b;

  // 边缘收缩系数:0~1之间,值越小边缘收缩越明显,可根据需求调整
  const edgeShrinkFactor = 0.6;

  for (int y = 0; y < depth; y++) {
    // 计算当前行到椭圆中心的归一化纵向距离
    final normalizedY = (y - centerY) / b;
    final ySquared = normalizedY * normalizedY;

    // 计算椭圆方程中当前行对应的横向半径平方
    final xRadiusSquared = 1 - ySquared;
    if (xRadiusSquared <= 0) continue; // 超出椭圆范围,无激活块

    // 调整横向半径,让边缘行宽度随纵向距离增加而平滑收缩
    final adjustedXRadius = sqrt(xRadiusSquared) * (1 - (1 - edgeShrinkFactor) * ySquared);
    final halfWidth = adjustedXRadius * a;

    // 计算当前行激活块的起始/结束x坐标
    final startX = (centerX - halfWidth).round();
    final endX = (centerX + halfWidth).round();

    // 确保坐标在有效范围内
    final actualStartX = max(0, startX);
    final actualEndX = min(width - 1, endX);

    // 标记当前行的激活块
    for (int x = actualStartX; x <= actualEndX; x++) {
      blocks[y][x] = true;
    }
  }

  return blocks;
}

关键优化点

  1. 移除冗余对称赋值:原代码中重复设置四个对称点的逻辑会导致重复赋值,改为逐行计算激活范围,逻辑更清晰且高效。
  2. 平滑收缩逻辑:通过edgeShrinkFactor控制边缘收缩程度,结合椭圆方程调整每行的横向激活范围,让边缘行的宽度随纵向距离平滑递减。
  3. 边界安全处理:使用max()/min()确保x坐标在0到width-1之间,避免数组越界错误。

效果调整

  • 若想要更明显的边缘收缩,可降低edgeShrinkFactor(比如设为0.4);
  • 若想要接近原椭圆效果,可提高edgeShrinkFactor(比如设为0.9)。

内容的提问来源于stack exchange,提问作者FMorschel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:53:17