Anapple 发表于 2025-2-2 13:54:32

来个大家都爱的爆算题

做一个矩形,满足其内部能放下5个如图相切的圆,(相连处全都相切),题目出自Ander大佬

yimin0519 发表于 2025-2-5 15:57:11

Anapple 发表于 2025-2-3 17:17
有根式解哦

圆贼多,费神:

qjchen 发表于 2025-2-2 23:20:36

本帖最后由 qjchen 于 2025-2-3 09:40 编辑




挺有趣的题目,用python编了好一段代码才求出来,大概有14位的精度


随手改编下两道题,把此题右边的线改为45度线,直角梯形:),

结果又如何






这些圆圆的相切球,想起了当年做Joselin版主的许多切圆的题目,集合如下,快乐的年轻时光 :)
101-200
[公告]典型问题及其解法大集中! - 几何算法 - AutoCAD论坛 - 明经CAD社区 - 第2页 - Powered by Discuz! (mjtd.com)
1-100
[公告]典型问题及其解法大集中! - 几何算法 - AutoCAD论坛 - 明经CAD社区 - Powered by Discuz! (mjtd.com)


Anapple 发表于 2025-2-3 17:17:05

有根式解哦

yimin0519 发表于 2025-2-5 16:10:08

a=100;

b=86.850301679939548081238453054628...;
R1=31.090998694367849448184538993009...。

yimin0519 发表于 2025-2-9 20:32:09

本帖最后由 yimin0519 于 2025-2-9 20:42 编辑

qjchen 发表于 2025-2-2 23:20
挺有趣的题目,用python编了好一段代码才求出来,大概有14位的精度



矩形的情况只有一种(所谓不同唯镜像矣),如为凸四边形则可能有多种情况。

高一定、“45°”直角梯形一角放置一“恒星”圆(其它四圆拱卫),“唯一”性情况共有四种(且诸圆互不相等),见下图:

有时间看能否“爆算”一下,看能付诸尺规作图的又有凡几。


qjchen 发表于 2025-2-10 10:46:13

本帖最后由 qjchen 于 2025-2-11 07:40 编辑




代码修改一下,倒是不难算,迟些有空整理好了再把代码放上来。


顺便开个与此题相类似的题目
几何作图题111

左上角以X轴镜像之后的求解代码如下(不少是AI辅助写的),此时,以基准圆半径为1进行计算,没啥技术含量,也没啥通用性,姑且放到这里
import numpy as np
from scipy.optimize import fsolve
import math

def line_circle_intersection(p1, p2, center, radius):
    x1, y1 = p1
    x2, y2 = p2
    h, k = center
   
    # 如果直线是垂直于 x 轴的直线(x = 常数)
    if x1 == x2:
      x_line = x1
      discriminant = radius**2 - (x_line - h)**2
      if discriminant < 0:
            return []# 无交点
      y1_intersect = k + np.sqrt(discriminant)
      y2_intersect = k - np.sqrt(discriminant)
      return [(x_line, y1_intersect), (x_line, y2_intersect)]
    A = y2 - y1
    B = x1 - x2
    C = x2 * y1 - x1 * y2
    distance = abs(A * h + B * k + C) / np.sqrt(A**2 + B**2)
    if distance > radius:
      return []
    a = A**2 + B**2
    b = 2 * (A * C + A * B * k - B**2 * h)
    c = C**2 + 2 * B * C * k - B**2 * (radius**2 - h**2 - k**2)
    discriminant = b**2 - 4 * a * c
    if discriminant < 0:
      return []
   
    # 计算 x 坐标
    x_intersect1 = (-b + np.sqrt(discriminant)) / (2 * a)
    x_intersect2 = (-b - np.sqrt(discriminant)) / (2 * a)
   
    # 计算 y 坐标
    y_intersect1 = (-A * x_intersect1 - C) / B if B != 0 else (-A * x_intersect1 - C) / 1e-10
    y_intersect2 = (-A * x_intersect2 - C) / B if B != 0 else (-A * x_intersect2 - C) / 1e-10
   
    # 返回交点
    return [(x_intersect1, y_intersect1), (x_intersect2, y_intersect2)]

# 定义方程组
def equations(vars, circle1, circle2, line):
    x, y, r = vars
    x1, y1, r1 = circle1# 示例圆1的参数
    x2, y2, r2 = circle2# 示例圆2的参数
    x3, y3, x4, y4 = line# 示例直线的参数

    # 圆1的约束
    eq1 = (x - x1)**2 + (y - y1)**2 - (r + r1)**2

    # 圆2的约束
    eq2 = (x - x2)**2 + (y - y2)**2 - (r + r2)**2

    # 直线的约束
    A = y4 - y3
    B = x3 - x4
    C = x4 * y3 - x3 * y4
    eq3 = (A * x + B * y + C)**2 - r**2 * (A**2 + B**2)

    return

# 二分法寻找 assumeX 使得 y5 = r5
def find_assumeX():
    low, high = 0.4, 0.5
    tolerance = 1e-16
    while high - low > tolerance:
      assumeX = (low + high) / 2
      
      p1 = (assumeX, 0)
      p2 = (assumeX, 3)
      circle1center = (1, 1)
      circle1radius = 1 + assumeX

      intersections = line_circle_intersection(p1, p2, circle1center, circle1radius)
      
      if intersections:
            max_y_intersection = max(intersections, key=lambda point: point)
            x_value, y_value = max_y_intersection
      else:
            x_value, y_value = 0, 0
      
      # 初始猜测值
      initial_guess =
      circle1 =
      circle2 =
      line =

      # 求解方程组
      solution = fsolve(equations, initial_guess, args=(circle1, circle2, line))
      x3, y3, r3 = solution

      initial_guess =
      circle11 =
      circle13 =

      # 求解方程组
      solution = fsolve(equations, initial_guess, args=(circle11, circle13, line))
      x4, y4, r4 = solution

      initial_guess =
      circle11 =
      circle14 =
      line1 =

      # 求解方程组
      solution = fsolve(equations, initial_guess, args=(circle11, circle14, line1))
      x5, y5, r5 = solution
      print(f"当前猜测值: {assumeX}, 解得: x = {x5}, y = {y5}, r = {r5}")
      
      if abs(y5 - r5) < tolerance:
            return assumeX
      elif y5 > r5:
            low = assumeX
      else:
            high = assumeX
   
    return (low + high) / 2

# 找到合适的 assumeX
optimal_assumeX = find_assumeX()
print(f"找到的 assumeX: {optimal_assumeX}")






页: [1]
查看完整版本: 来个大家都爱的爆算题