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

Flutter新手求助:如何数学正确实现12个环绕圆形的绘制

Flutter绘制12个均匀环绕圆形的子圆方案

12个环绕圆形的子圆示例

我是Flutter新手,需要绘制12个按正确角度环绕在一个圆形周围的圆,恳请提供数学层面准确的解决方案,可参考上图。

数学原理

要让12个圆均匀环绕中心,核心是极坐标转笛卡尔坐标:

  • 12个圆均分360°,相邻圆角度差为30°(对应弧度π/6)
  • 子圆圆心坐标公式:
    • x = 中心X + 环绕半径 * cos(当前角度)
    • y = 中心Y + 环绕半径 * sin(当前角度)
      其中环绕半径是中心到子圆圆心的距离,角度以弧度计算(Flutter默认用弧度)。

代码实现

先定义单个子圆组件:

Widget _childCircle() {
  return Container(
    width: 28,
    height: 28,
    decoration: BoxDecoration(
      color: Colors.green.withOpacity(0.25), // 外圈颜色
      shape: BoxShape.circle,
    ),
    child: Padding(
      padding: EdgeInsets.all(2), // 外圈宽度
      child: Container(
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: Colors.blue, // 内圈颜色
        ),
      ),
    ),
  );
}

再用Stack布局实现环绕效果:

Widget _circularLayout() {
  const childCount = 12;
  const centerX = 150; // 布局中心X坐标,可按需调整
  const centerY = 150; // 布局中心Y坐标,可按需调整
  const radius = 100; // 中心到子圆圆心的距离

  return Stack(
    children: [
      // 可选:添加中心圆
      Positioned(
        left: centerX - 40,
        top: centerY - 40,
        child: Container(
          width: 80,
          height: 80,
          decoration: BoxDecoration(
            color: Colors.grey.withOpacity(0.2),
            shape: BoxShape.circle,
          ),
        ),
      ),
      // 生成12个均匀分布的子圆
      for (int i = 0; i < childCount; i++)
        Positioned(
          // 计算子圆左上角坐标,减去子圆半径(28/2=14)让中心对齐计算点
          left: centerX + radius * cos(2 * pi * i / childCount) - 14,
          top: centerY + radius * sin(2 * pi * i / childCount) - 14,
          child: _childCircle(),
        ),
    ],
  );
}

说明

  • 2 * pi * i / childCount:计算每个子圆对应的弧度,确保12个圆均分一圈
  • 调整centerX/centerY可以改变整体布局位置,调整radius可以改变子圆与中心的距离
  • 子圆的大小可以通过修改_childCircle中的width/height调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:45:49