问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

大圆套小圆问题(附解决源码)

创作时间:
作者:
@小白创作中心

大圆套小圆问题(附解决源码)

引用
CSDN
1.
https://blog.csdn.net/m0_73879806/article/details/143654538

最近,一位开发者遇到了一个有趣的数学计算问题:在一个直径为400mm的圆形容器中,可以装下多少个直径为55mm的小圆形容器?本文将从数学计算方法入手,详细解释计算过程,并通过编程实现一个可视化解决方案。

前言

这个问题看似简单,但要得到精确答案并不容易。我们可以通过数学方法计算最优装填方案。

思路

首先,我们需要确定基本参数:

  • 大圆半径 R = 400mm ÷ 2 = 200mm
  • 小圆半径 r = 55mm ÷ 2 = 27.5mm

计算步骤如下:

  1. 中心可以放置1个圆
  2. 计算第一圈可以放置的圆数:
    使用公式:n₁ = floor(2π ÷ (2 * arcsin(r/(R-r))))
    这是基于三角函数计算得出的精确值
  3. 计算后续圆环:
    每个圆环的半径是前一个圆环加上一个小圆直径
    对于每个圆环,计算其周长并除以小圆直径来确定可以放置的圆数
    最大圆环数 = floor((R-r)/(2r))

编程实现

下面是具体的实现代码:

import React from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';

const CirclePacking = () => {
  const R = 200; // 大圆半径 (400mm / 2)
  const r = 27.5; // 小圆半径 (55mm / 2)

  // 计算内切圆的数量
  const calculateMaxCircles = () => {
    // 第一圈最大内切圆数
    const n1 = Math.floor(2 * Math.PI / (2 * Math.asin(r / (R - r))));

    // 计算可以放置的总圆数(包括中心一个)
    let totalCircles = 1; // 中心一个
    let maxRings = Math.floor((R - r) / (2 * r)); // 最大环数

    for (let ring = 1; ring <= maxRings; ring++) {
      const radius = ring * 2 * r; // 当前环的半径
      const circumference = 2 * Math.PI * radius; // 当前环的周长
      const circlesInRing = Math.floor(circumference / (2 * r)); // 当前环可以放置的圆数
      totalCircles += circlesInRing;
    }

    return {
      firstRing: n1,
      totalCircles: totalCircles,
      maxRings: maxRings
    };
  };

  // 绘制圆形布局
  const drawCircles = () => {
    const circles = [];
    const { maxRings } = calculateMaxCircles();

    // 添加中心圆
    circles.push(
      <circle
        key="center"
        cx={200}
        cy={200}
        r={r}
        fill="#4CAF50"
        stroke="#2E7D32"
        strokeWidth="1"
      />
    );

    // 添加环形圆
    for (let ring = 1; ring <= maxRings; ring++) {
      const radius = ring * 2 * r;
      const circumference = 2 * Math.PI * radius;
      const circlesInRing = Math.floor(circumference / (2 * r));

      for (let i = 0; i < circlesInRing; i++) {
        const angle = (2 * Math.PI * i) / circlesInRing;
        const x = 200 + radius * Math.cos(angle);
        const y = 200 + radius * Math.sin(angle);

        circles.push(
          <circle
            key={`${ring}-${i}`}
            cx={x}
            cy={y}
            r={r}
            fill="#4CAF50"
            stroke="#2E7D32"
            strokeWidth="1"
          />
        );
      }
    }

    return circles;
  };

  const result = calculateMaxCircles();
  return (
    <Card className="w-full max-w-2xl">
      <CardHeader>
        <CardTitle>圆形容器装填分析</CardTitle>
      </CardHeader>
      <CardContent>
        <div className="space-y-4">
          <div className="bg-white p-4 rounded-lg">
            <svg viewBox="0 0 400 400" className="w-full h-full">
              {/* 外部容器圆 */}
              <circle
                cx={200}
                cy={200}
                r={R}
                fill="none"
                stroke="#1976D2"
                strokeWidth="2"
              />
              {/* 内部小圆 */}
              {drawCircles()}
            </svg>
          </div>

          <div className="space-y-2">
            <p className="font-medium">计算结果:</p>
            <ul className="list-disc list-inside space-y-1">
              <li>大圆直径: 400mm</li>
              <li>小圆直径: 55mm</li>
              <li>第一圈可以放置: {result.firstRing} 个圆</li>
              <li>最大同心圆环数: {result.maxRings} 环</li>
              <li>总计可以放置: {result.totalCircles} 个圆</li>
            </ul>
          </div>
        </div>
      </CardContent>
    </Card>
  );
};

export default CirclePacking;

结果

源码可视化显示了具体的装填方案,其中:

  • 蓝色外圆代表400mm的容器
  • 绿色内圆代表55mm的小容器

可以清楚地看到同心圆状的装填模式。

注意事项:

  • 实际放置时要考虑圆与圆之间的间隙
  • 理论计算值和实际可能会有细微差异
  • 可能需要考虑制造公差

根据计算,一个400mm直径的圆形容器大约可以装下37个55mm的圆形容器。这个数字是基于理想的密集装填模式计算得出的。在实际应用中,可能需要留出一定的操作空间,所以实际数量可能会稍少一些。

源码介绍

这段代码是一个使用React框架编写的组件,用于分析和展示在一个较大的圆形容器中可以装下多少个较小的圆形容器。这个组件使用了SVG来绘制圆形,并计算小圆在大圆中的排列。

以下是代码的主要部分及其功能:

  1. 导入依赖:
  • import React from 'react';:导入React库。
  • import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';:从项目中的@/components/ui/card路径导入UI组件。
  1. 定义CirclePacking组件:
  • const CirclePacking = () => { … };:定义一个名为CirclePacking的函数式组件。
  1. 计算内切圆的数量:
  • const calculateMaxCircles = () => { … };:定义一个函数来计算大圆中可以放置的最大小圆数量。
  • const n1 = Math.floor(2 * Math.PI / (2 * Math.asin(r / (R - r))));:计算第一圈可以放置的小圆数量。
  • let totalCircles = 1;:初始化总小圆数量,包括中心的一个。
  • let maxRings = Math.floor((R - r) / (2 * r));:计算最大同心圆环数。
  1. 绘制圆形布局:
  • const drawCircles = () => { … };:定义一个函数来绘制圆形布局。
  • `circles.push(…):向circles数组中添加SVG元素,表示小圆。
  1. 返回组件的JSX:
  • return ( … ):返回组件的JSX,包括一个组件,其中包含一个SVG绘制的圆形布局和一个显示计算结果的列表。
  1. 导出组件:
  • export default CirclePacking;:将CirclePacking组件导出,使其可以在其他文件中使用。

这个组件通过计算和SVG绘制,直观地展示了在大圆中可以放置多少个小圆,以及它们的排列方式。它还显示了计算结果,包括大圆和小圆的直径、第一圈可以放置的小圆数量、最大同心圆环数以及总计可以放置的小圆数量。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号