刷 xhs 刷到学弟的一个题,就写了一下。xhs 连接
给你一根长度为 𝑠 s 的绳子,以及两面夹角为 𝜃 θ 的墙。借助墙作为边界,最多能围出多大面积?如果两面墙不再无限长,而是长度分别为 𝑥 , 𝑦 x , y 的线段,答案又会怎样变化?
题目
两面墙在墙角 𝑂 O 相交,夹角满足 0 < 𝜃 < 𝜋 0 < θ < π ,角度用弧度 表示。绳长 𝑠 > 0 s > 0 固定,绳子柔软、不可伸长,可以弯曲,也可以自由选择形状。
将绳子的两个端点分别系在两面墙上的 𝐴 , 𝐵 A , B ,让绳子与墙段 𝑂 𝐴 , 𝑂 𝐵 O A , O B 组成一个简单闭合边界。系绳点可以沿墙移动,绳子不能穿墙或自交;墙段不消耗绳长。
分别考虑两种情况:
无限墙 :两面墙是从 𝑂 O 出发的无限长射线,围出的区域必须位于夹角内部。
有限墙 :两面墙是从 𝑂 O 出发、长度分别为 𝑥 , 𝑦 > 0 x , y > 0 的线段。系绳点不能超过墙端,但绳子可以绕过墙端,伸到夹角之外;墙的延长线不构成障碍。
求能够围出的最大面积,以及达到这个面积时的绳子形状和系绳点位置。
允许 𝐴 A 或 𝐵 B 取到 𝑂 O ,即其中一段被利用的墙长为零。未作为外边界的墙段可以留在区域内部。如果额外要求两面墙都必须利用正长度,那么后面某些退化情形只能给出上确界,而不能取到最大值。
墙提供两条边,绳子补上弯曲的一边
墙提供两条边,绳子补上弯曲的一边 从墙角 O 沿第一面墙走到 A,再沿绳子走到 B,最后沿第二面墙回到 O。阴影就是要最大化的面积;B 后面那一小段墙没有参与围边。 本图绳长 2.000,圆弧角 149.4 度。所围面积 1.353354。 A B O 绳长 2 · 面积 1.353354
从墙角 O 沿第一面墙走到 A,再沿绳子走到 B,最后沿第二面墙回到 O。阴影就是要最大化的面积;B 后面那一小段墙没有参与围边。
也可以先自己试一试。下面固定墙长 𝑥 = 1 , 𝑦 = 2 x = 1 , y = 2 ,夹角初始为 𝜃 = 𝜋 / 3 θ = π / 3 ,可用「墙夹角」滑块在 5 ∘ 5 ∘ 到 1 7 5 ∘ 175 ∘ 之间调整:拖动 A、B,或者调整对应滑块,改变 𝑂 𝐴 , 𝑂 𝐵 O A , O B ;再拖动绳长滑块,观察圆弧怎样从接近直线变成大圆弧。图中的墙不会随端点移动而伸长。
拖动图中的 A、B,或使用下方滑块,调整墙夹角和绳长,观察圆弧变化。调整滑块时视图自动缩放,直接拖动端点时比例保持固定。
可调整夹角、端点与绳长的圆弧 墙夹角可调,初始为六十度。第一面墙长一,第二面墙长二。A 沿水平墙移动,B 沿斜墙移动;棕色曲线表示绳子,虚线表示弦。 O A B 弦长 1.480 · 面积 1.353 · 圆弧角 149.4°
小圆弧:绳子尚未达到半圆。这是当前端点的圆弧,端点位置并未自动优化。
初始状态:夹角六十度,两面墙长分别为一、二,使用墙长一、1.7,绳长二。拖动端点只改变使用的墙长,调整夹角会旋转第二面墙,实际墙长保持不变;增大绳长会让圆弧逐渐鼓起。虚线不是绳子。若图形碰到剩余墙段,会单独标明不可行。
先按“扇形”,观察两端垂直墙面的形状;再按“大圆弧”,看绳子绕过墙端。保持端点不动,逐渐减小绳长,直到弧线拉直;继续减小,绳子就连接不了两个端点了。这个交互展示的是给定端点的圆弧 ,不会自动替你选择面积最大的端点。
为什么绳子应该是一段圆弧?
先固定 𝐴 , 𝐵 A , B 。它们与 𝑂 O 组成的三角形已经固定,我们能改变的只是绳子与弦 𝐴 𝐵 A B 之间的面积。这就是固定端点的 Dido 问题:在端点与曲线长度固定时,怎样使弓形面积最大?UCL 的变分法讲义 给出了这一圆弧问题及其长度约束。
先看绳子“弯得多急”。想象沿绳子走,脚下的切线方向就是前进方向。走过同样长的一小段,方向转得越多,曲率就越大。若这段弧长为 Δ ℓ Δ ℓ ,切线转过的角度为 Δ 𝜑 Δ φ ,那么局部曲率的大小约为 | Δ 𝜑 | / Δ ℓ | Δ φ | / Δ ℓ ,把弧段缩到一点就得到曲率。圆上有 Δ ℓ = 𝑅 Δ 𝜑 Δ ℓ = R Δ φ ,所以半径为 𝑅 R 的圆处处有 𝜅 = 1 / 𝑅 κ = 1 / R :小圆弯得急,大圆弯得缓,直线的曲率为零。MIT 的曲率讲义 也从切线方向随弧长的变化定义这一量。
缓弯:走一段,方向转得少
缓弯:走一段,方向转得少 圆弧半径为 2,弧长均为 1.8,切线方向转过 0.9 弧度。T 沿绳子指向前进方向,n 指向区域外侧,C 在内侧。 C R T T n 𝑅 = 2 , 𝜅 = 0 . 5 , Δ 𝜑 = 0 . 9 R = 2 , κ = 0.5 , Δ φ = 0.9
急弯:走一样远,方向转得多
急弯:走一样远,方向转得多 圆弧半径为 1,弧长均为 1.8,切线方向转过 1.8 弧度。T 沿绳子指向前进方向,n 指向区域外侧,C 在内侧。 C R T T n 𝑅 = 1 , 𝜅 = 1 , Δ 𝜑 = 1 . 8 R = 1 , κ = 1 , Δ φ = 1.8
两图比例相同,棕色弧的长度也相同。沿弧从右向左走,蓝色箭头 T 随之转向;右图的方向变化更大,所以曲率更大。n 垂直绳子、朝向外侧,圆心 C 位于反方向。这里用两段圆弧说明局部弯曲程度,并未假设整根绳子已经是圆。
现在试着把一小段绳子垂直向外推。它扫过一条窄带,增加面积,同时也需要更多绳长。下面会看到:推出同样的距离 𝑢 u ,一阶面积增量约为 𝑢 u 乘以这段弧长,长度增量还要再乘以局部曲率 𝜅 κ 。弯得越急的地方,同样的面积收益需要花费越多绳长。
把这个直觉写成变分,就可以明确得到“曲率恒定”的方程。先考虑绳长大于端点距离的非退化情形,并暂时固定两端。我们先在光滑曲线中寻找候选形状,再用后面的全局上界验证它;仅仅求出一个驻点,还不能宣布它是最大值。
沿围出区域的边界逆时针走,绳子这一段从 𝐴 A 走到 𝐵 B 。用原曲线的弧长 ℓ ℓ 作参数,记绳子为 𝛾 ( ℓ ) γ ( ℓ ) ,单位切向量为 𝑇 T ,外法向量为 𝑛 n 。曲率 𝜅 κ 的符号约定为:向外鼓起的圆弧取正值。于是
𝛾 ′ = 𝑇 , 𝑇 ′ = − 𝜅 𝑛 , 𝑛 ′ = 𝜅 𝑇 . γ ′ = T , T ′ = − κ n , n ′ = κ T .
现在只推挤绳子的内部:把位置 ℓ ℓ 沿外法线移动 𝜀 𝑓 ( ℓ ) ε f ( ℓ ) ,其中 𝑓 f 在端点附近为零。正的 𝑓 f 表示向外推,负的 𝑓 f 表示向内收。扰动后的曲线是
𝛾 𝜀 ( ℓ ) = 𝛾 ( ℓ ) + 𝜀 𝑓 ( ℓ ) 𝑛 ( ℓ ) . γ ε ( ℓ ) = γ ( ℓ ) + ε f ( ℓ ) n ( ℓ ) .
只挪动内部,两个端点不动
只挪动内部,两个端点不动 同一条曲线的左侧沿外法线向外推,绿色窄带表示增加的面积;右侧沿外法线的反方向向内收,棕色窄带表示失去的面积。扰动在两端附近为零。虚线表示扰动后的曲线。 A B 向外推 向内收 区域内部 𝛾 𝜀 = 𝛾 + 𝜀 𝑓 𝑛 γ ε = γ + ε f n
实线是原绳子,虚线是移动后的绳子,箭头沿原曲线的法线。向外推时 f 为正,向内收时 f 为负;移动距离为了看清而放大。两块窄带分别增加、减少面积,这幅图只示意允许的动作,尚未要求两处长度变化抵消。
这里 ℓ ℓ 只是原曲线的弧长参数;扰动之后,不再要求 𝛾 𝜀 γ ε 仍以单位速度走过。下面用 A A 表示面积、𝐿 L 表示绳子的实际长度,𝛿 δ 表示对 𝜀 ε 求导后取 𝜀 = 0 ε = 0 。
面积怎样变? 一小段长度为 d ℓ d ℓ 的绳子向外移动 𝜀 𝑓 ε f ,一阶增加的是一条宽为 𝜀 𝑓 ε f 的窄带。因此
𝛿 A = ∫ 𝑠 0 𝑓 ( ℓ ) d ℓ . δ A = ∫ 0 s f ( ℓ ) d ℓ .
长度怎样变? 先看一小段圆弧:向外平移 𝑢 u 后,半径从 𝑅 R 变成 𝑅 + 𝑢 R + u ,两端半径之间的角度 Δ 𝜑 Δ φ 不变。原弧长是 Δ ℓ = 𝑅 Δ 𝜑 Δ ℓ = R Δ φ ,新弧长是 ( 𝑅 + 𝑢 ) Δ 𝜑 ( R + u ) Δ φ ,所以多用的绳长为
Δ 𝐿 = 𝑢 Δ 𝜑 = 𝑢 𝑅 Δ ℓ = 𝜅 𝑢 Δ ℓ . Δ L = u Δ φ = u R Δ ℓ = κ u Δ ℓ .
缓弯向外推:较少的长度成本
缓弯向外推:较少的长度成本 原圆弧半径 2、弧长 1.8,沿外法线推出 0.2。保持两条半径的方向不变,新弧长增加 0.18;绿色表示扫过的窄带。 C R u Δ 𝐿 = 0 . 1 8 , Δ A ≈ 0 . 3 6 Δ L = 0.18 , Δ A ≈ 0.36
急弯向外推:两倍的长度成本
急弯向外推:两倍的长度成本 原圆弧半径 1、弧长 1.8,沿外法线推出 0.2。保持两条半径的方向不变,新弧长增加 0.36;绿色表示扫过的窄带。 C R u Δ 𝐿 = 0 . 3 6 , Δ A ≈ 0 . 3 6 Δ L = 0.36 , Δ A ≈ 0.36
沿用上面的两段弧:原弧长都为 1.8,向外移动距离都为 0.2。虚线新弧与原弧夹着绿色窄带;它们的面积增量在一阶相同,右图的长度增量却是左图的两倍。这里截取的是内部小段,截面的端点可以移动;完整扰动会在两旁平滑地降为零。面积只比较一阶项,有限宽度下还有二阶差异。
一般光滑曲线在很小范围内也有这样的局部弯曲程度;下面直接求导,验证即使推挤的幅度沿绳子变化,一阶长度变化仍由同一个系数决定。对扰动曲线求导,利用 𝑛 ′ = 𝜅 𝑇 n ′ = κ T ,得到
𝛾 ′ 𝜀 = ( 1 + 𝜀 𝜅 𝑓 ) 𝑇 + 𝜀 𝑓 ′ 𝑛 . γ ε ′ = ( 1 + ε κ f ) T + ε f ′ n .
因为 𝑇 , 𝑛 T , n 正交且都是单位向量,扰动后的长度就是
𝐿 [ 𝛾 𝜀 ] = ∫ 𝑠 0 √ ( 1 + 𝜀 𝜅 𝑓 ) 2 + 𝜀 2 ( 𝑓 ′ ) 2 d ℓ . L [ γ ε ] = ∫ 0 s ( 1 + ε κ f ) 2 + ε 2 ( f ′ ) 2 d ℓ .
对 𝜀 ε 求导后取零,便得到
𝛿 𝐿 = ∫ 𝑠 0 𝜅 ( ℓ ) 𝑓 ( ℓ ) d ℓ . δ L = ∫ 0 s κ ( ℓ ) f ( ℓ ) d ℓ .
这正好解释了前面的直觉:同样向外移动一小段距离,面积收益的一阶系数是 1 1 ,长度成本的一阶系数却是局部曲率 𝜅 κ 。
这也给出一个具体的改进方向。假设两小段都向外鼓起,急弯处的曲率是缓弯处的两倍:在急弯处向内收,省下一点绳长;再把它用在缓弯处向外推。一阶近似下,得到的面积是失去面积的两倍,总面积便增加了。只要还能这样调配,原来的形状就不是最优;下面用变分把“各处应当同样弯”写成方程,并处理一般的局部扰动。
但任意的 𝑓 f 未必保持绳长,所以不能直接要求 𝛿 A = 0 δ A = 0 。对约束 𝐿 = 𝑠 L = s 引入拉格朗日乘子,考虑
J [ 𝛾 ] = A [ 𝛾 ] − 𝜆 ( 𝐿 [ 𝛾 ] − 𝑠 ) . J [ γ ] = A [ γ ] − λ ( L [ γ ] − s ) .
这里只约束总长度这一个数 ,所以 𝜆 λ 是一个常数,不是沿绳子变化的函数。最优曲线必须使
0 = 𝛿 J = ∫ 𝑠 0 ( 1 − 𝜆 𝜅 ( ℓ ) ) 𝑓 ( ℓ ) d ℓ 0 = δ J = ∫ 0 s ( 1 − λ κ ( ℓ ) ) f ( ℓ ) d ℓ
对任意这样的局部推挤 𝑓 f 都成立。若某处 1 − 𝜆 𝜅 1 − λ κ 不为零,就能在那一小段选择同号的 𝑓 f ,让积分不为零。因此
𝜅 ( ℓ ) = 1 𝜆 = 常数 . κ ( ℓ ) = 1 λ = 常数 .
为什么恒定曲率就意味着圆? 不必再靠图形直觉:令
𝐶 ( ℓ ) = 𝛾 ( ℓ ) − 𝜆 𝑛 ( ℓ ) . C ( ℓ ) = γ ( ℓ ) − λ n ( ℓ ) .
那么
𝐶 ′ ( ℓ ) = 𝑇 − 𝜆 𝜅 𝑇 = 0 . C ′ ( ℓ ) = T − λ κ T = 0.
所以 𝐶 C 是一个固定点,并且
| 𝛾 ( ℓ ) − 𝐶 | = | 𝜆 | | γ ( ℓ ) − C | = | λ |
处处成立。绳子上的每一点到同一个点的距离相同,绳形自然就是一段圆弧。对于向外鼓起的最优分支,𝜅 > 0 κ > 0 ,于是 𝜆 = 𝑅 λ = R 。
面积变分的窄带解释,怎样写成积分证明? 取墙角 𝑂 O 为坐标原点。两条直墙段对有向面积积分的贡献为零,因此由 Green 公式,
A [ 𝛾 ] = 1 2 ∫ 𝑠 0 𝛾 × 𝛾 ′ d ℓ , A [ γ ] = 1 2 ∫ 0 s γ × γ ′ d ℓ ,
其中二维叉积定义为 ( 𝑢 1 , 𝑢 2 ) × ( 𝑣 1 , 𝑣 2 ) = 𝑢 1 𝑣 2 − 𝑢 2 𝑣 1 ( u 1 , u 2 ) × ( v 1 , v 2 ) = u 1 v 2 − u 2 v 1 。令一般的扰动向量为 𝑉 V ,对上式求变分并分部积分:
𝛿 A = 1 2 ∫ 𝑠 0 ( 𝑉 × 𝑇 + 𝛾 × 𝑉 ′ ) d ℓ = ∫ 𝑠 0 𝑉 × 𝑇 d ℓ + 1 2 [ 𝛾 × 𝑉 ] 𝐵 𝐴 . δ A = 1 2 ∫ 0 s ( V × T + γ × V ′ ) d ℓ = ∫ 0 s V × T d ℓ + 1 2 [ γ × V ] A B .
固定端点时,边界项为零。又因为逆时针边界的外法线是 𝑇 T 顺时针旋转九十度的结果,𝑉 × 𝑇 = 𝑉 ⋅ 𝑛 V × T = V ⋅ n 。代入 𝑉 = 𝑓 𝑛 V = f n ,就得到 𝛿 A = ∫ 𝑓 d ℓ δ A = ∫ f d ℓ 。
即使端点沿墙滑动,边界项仍然为零:在每个端点处,位置向量 𝛾 γ 与允许的位移 𝑉 V 都沿着同一面墙,叉积为零。这一点会在下面推导端点条件时用到。
变分到这里给出了必要条件 。全局最优性还要另证:把候选圆弧补成一个整圆,再把同一段补弧接到任何其他等长曲线上。拼接后的总长度始终等于这个圆的周长;如果其他曲线贡献的有向面积更大,拼接后的有向面积就会超过圆,违反等周不等式。因此,选定端点后,这段向外鼓起的圆弧确实达到全局最大值。这里使用的有向面积版本也允许拼接曲线发生自交。
圆弧不一定是小于半圆的劣弧。端点很近而绳子很长时,最优形状会接近一整个圆,只留下很短的一条弦。
绳子略长于弦
绳子略长于弦 固定同一对端点,弦长均为一,三图比例相同。这里只改变绳长:圆弧从不足半圆变成超过半圆。虚线是弦,不是绳子;第三图的较大面积来自更多绳长,不能拿它当作等绳长比较。 本图绳长 1.100,圆弧角 85.8 度。各图端点和弦长完全相同。 A B 绳长 1.100 · 圆弧角 85.8°
恰好围成半圆
恰好围成半圆 固定同一对端点,弦长均为一,三图比例相同。这里只改变绳长:圆弧从不足半圆变成超过半圆。虚线是弦,不是绳子;第三图的较大面积来自更多绳长,不能拿它当作等绳长比较。 本图绳长 1.571,圆弧角 180.0 度。各图端点和弦长完全相同。 A B 绳长 1.571 · 圆弧角 180.0°
继续加长,变成大圆弧
继续加长,变成大圆弧 固定同一对端点,弦长均为一,三图比例相同。这里只改变绳长:圆弧从不足半圆变成超过半圆。虚线是弦,不是绳子;第三图的较大面积来自更多绳长,不能拿它当作等绳长比较。 本图绳长 3.000,圆弧角 261.1 度。各图端点和弦长完全相同。 A B 绳长 3.000 · 圆弧角 261.1°
固定同一对端点,弦长均为一,三图比例相同。这里只改变绳长:圆弧从不足半圆变成超过半圆。虚线是弦,不是绳子;第三图的较大面积来自更多绳长,不能拿它当作等绳长比较。
无限墙:圆心为什么恰好是墙角?
固定端点的结论还不够,因为端点也能沿墙滑动。设最优圆弧的半径为 𝑅 R 。如果绳子在系绳点处与墙不垂直,沿墙移动端点,就会一阶改变绳长;端点扫过的面积却只有二阶大小。把省下来的绳长放到圆弧上向外扩张,就能增加面积。因此,自由滑动的端点处,绳子必须与墙垂直。
圆的切线与半径垂直,所以对应的半径必须沿着墙。两面墙上的端点都自由,圆心就必须同时在两条墙线上,只能是交点 𝑂 O 。
变分中的边界项,直接给出“端点垂直墙面” 现在允许端点移动,令 𝑉 V 为曲线的扰动向量,𝑓 = 𝑉 ⋅ 𝑛 f = V ⋅ n 为它的外法向分量。对长度求变分并分部积分,不能再丢掉端点项:
𝛿 𝐿 = ∫ 𝑠 0 𝑇 ⋅ 𝑉 ′ d ℓ = [ 𝑇 ⋅ 𝑉 ] 𝐵 𝐴 + ∫ 𝑠 0 𝜅 𝑓 d ℓ . δ L = ∫ 0 s T ⋅ V ′ d ℓ = [ T ⋅ V ] A B + ∫ 0 s κ f d ℓ .
前面已经证明,端点沿墙移动时,面积变分仍为 𝛿 A = ∫ 𝑓 d ℓ δ A = ∫ f d ℓ 。因此
𝛿 J = ∫ 𝑠 0 ( 1 − 𝜆 𝜅 ) 𝑓 d ℓ − 𝜆 𝑇 ( 𝐵 ) ⋅ 𝑉 ( 𝐵 ) + 𝜆 𝑇 ( 𝐴 ) ⋅ 𝑉 ( 𝐴 ) . δ J = ∫ 0 s ( 1 − λ κ ) f d ℓ − λ T ( B ) ⋅ V ( B ) + λ T ( A ) ⋅ V ( A ) .
绳子内部已经满足 1 − 𝜆 𝜅 = 0 1 − λ κ = 0 ,剩下的恰好是两个边界项。记两条墙从 𝑂 O 向外的单位方向为 𝑒 1 , 𝑒 2 e 1 , e 2 ,端点允许的位移为
𝑉 ( 𝐴 ) = 𝛿 𝑎 𝑒 1 , 𝑉 ( 𝐵 ) = 𝛿 𝑏 𝑒 2 . V ( A ) = δ a e 1 , V ( B ) = δ b e 2 .
若端点处于墙段内部,𝛿 𝑎 , 𝛿 𝑏 δ a , δ b 可以独立地取正值或负值。为了使 𝛿 J = 0 δ J = 0 对所有这些移动成立,必须有
𝑇 ( 𝐴 ) ⋅ 𝑒 1 = 0 , 𝑇 ( 𝐵 ) ⋅ 𝑒 2 = 0 . T ( A ) ⋅ e 1 = 0 , T ( B ) ⋅ e 2 = 0.
也就是说,绳子的切线垂直墙面 。于是圆心位于两条墙线上,只能是 𝑂 O 。
有限墙也遵循同一个推导,只是端点碰到墙端后,位移只能向墙内取值。此时变分条件变成单边不等式,不再要求相应的点积为零,所以固定在墙端的绳子不必垂直墙面。这正是后面圆心能够离开 𝑂 O 的原因。
两个直角,把圆心钉在墙角
两个直角,把圆心钉在墙角 蓝色短线表示绳子在端点的切线,小方框标出直角。端点可自由滑动时,切线必须垂直墙面,于是半径沿墙,两个半径的交点就是 O。图中的墙继续延伸,端点并未被墙端限制。 本图绳长 1.047,圆弧角 60.0 度。所围面积 0.523599。 A B O 绳长 1.047 · 面积 0.523599
蓝色短线表示绳子在端点的切线,小方框标出直角。端点可自由滑动时,切线必须垂直墙面,于是半径沿墙,两个半径的交点就是 O。图中的墙继续延伸,端点并未被墙端限制。
看图中的两个直角:它们约束的是端点处的切线方向,不是说整根绳子要拉直。绳子的中间部分仍然向外鼓起,而圆心已经不能再自由移动。
于是最优区域是半径为 𝑅 R 、圆心角为 𝜃 θ 的扇形。绳子只负责弧边,因此
𝑠 = 𝑅 𝜃 , 𝐴 = 1 2 𝑅 2 𝜃 . s = R θ , A = 1 2 R 2 θ .
消去半径,得到
𝑅 = 𝑠 𝜃 , 𝐴 m a x = 𝑠 2 2 𝜃 . R = s θ , A max = s 2 2 θ .
例如两面墙互相垂直,𝜃 = 𝜋 / 2 θ = π / 2 ,应围成四分之一圆,面积为 𝑠 2 / 𝜋 s 2 / π 。只借助一面无限长的直墙时,最优形状是半圆,面积为 𝑠 2 / ( 2 𝜋 ) s 2 / ( 2 π ) ;直角墙角把这个面积翻了一倍。
怎样排除其他全局最大值? 记 𝑂 𝐴 = 𝑎 , 𝑂 𝐵 = 𝑏 O A = a , O B = b 。绳子必须能连接两端,所以
𝑎 2 + 𝑏 2 − 2 𝑎 𝑏 c o s 𝜃 ≤ 𝑠 2 . a 2 + b 2 − 2 a b cos θ ≤ s 2 .
对固定的 0 < 𝜃 < 𝜋 0 < θ < π ,这使可行的 𝑎 , 𝑏 a , b 有界。因此,可以先在允许所有平面圆弧的更大集合中求最大值,再检查获胜者是否位于夹角内。
两个端点都不在 𝑂 O 、且弦长严格小于绳长时,端点都是自由的,上面的垂直条件迫使圆心为 𝑂 O 。若一个端点到达 𝑂 O ,退化为单墙问题,其最大面积不超过 𝑠 2 / ( 2 𝜋 ) s 2 / ( 2 π ) ,严格小于扇形的 𝑠 2 / ( 2 𝜃 ) s 2 / ( 2 θ ) 。两个端点都在 𝑂 O 的圆也更小。
弦长恰好等于绳长时,绳子拉成直线,也不可能是最大值:把两端稍微向 𝑂 O 缩进,使弦短一点,再把余下的长度用于向外鼓起,新增的弓形面积会超过三角形面积的一阶损失。
因此,更大集合中的最大值就是这个扇形,而它也确实位于两面墙之间。这同时给出了上界与可行构造,不需要假设 𝜃 θ 能整除 2 𝜋 2 π ,也不需要把任意夹角反射拼成整圆。
有限墙:先固定端点,算出面积
现在令两面墙的长度分别为 𝑥 , 𝑦 x , y ,并记
0 ≤ 𝑎 = 𝑂 𝐴 ≤ 𝑥 , 0 ≤ 𝑏 = 𝑂 𝐵 ≤ 𝑦 . 0 ≤ a = O A ≤ x , 0 ≤ b = O B ≤ y .
有限墙增加的是端点位置的约束 ,不是“半径必须小于短墙”的约束。只要圆心离开 𝑂 O ,半径就不再等于被利用的墙长。
为了一次处理小圆弧、半圆和大圆弧,我们用绳子对应的圆心角 𝛼 α 描述它。注意,𝛼 α 与墙的夹角 𝜃 θ 是两个不同的量。
由余弦定理,两个端点的距离为
𝑑 = 𝐴 𝐵 = √ 𝑎 2 + 𝑏 2 − 2 𝑎 𝑏 c o s 𝜃 . d = A B = a 2 + b 2 − 2 a b cos θ .
设圆弧半径为 𝑅 R 。弧长和弦长分别满足
𝑠 = 𝑅 𝛼 , 𝑑 = 2 𝑅 s i n 𝛼 2 . s = R α , d = 2 R sin α 2 .
消去 𝑅 R ,就得到决定圆弧的方程:
𝑑 𝑠 = 2 s i n ( 𝛼 / 2 ) 𝛼 , 0 < 𝛼 < 2 𝜋 . d s = 2 sin ( α / 2 ) α , 0 < α < 2 π .
右侧从 1 1 严格递减到 0 0 。因此,只要 0 < 𝑑 < 𝑠 0 < d < s ,就存在唯一的 𝛼 α ,直接二分即可。这里必须搜索整个 ( 0 , 2 𝜋 ) ( 0 , 2 π ) ;只搜索 ( 0 , 𝜋 ] ( 0 , π ] 会漏掉长绳子的答案。
为什么这个方程只有一个解? 令 𝑢 = 𝛼 / 2 u = α / 2 ,右侧就是 s i n 𝑢 / 𝑢 sin u / u 。其导数的符号取决于 𝑢 c o s 𝑢 − s i n 𝑢 u cos u − sin u 。又因为
d d 𝑢 ( s i n 𝑢 − 𝑢 c o s 𝑢 ) = 𝑢 s i n 𝑢 > 0 , 0 < 𝑢 < 𝜋 , d d u ( sin u − u cos u ) = u sin u > 0 , 0 < u < π ,
且括号中的量在 𝑢 = 0 u = 0 处趋于零,所以导数严格为负。
小圆弧:三角形加小弓形
小圆弧:三角形加小弓形 沿虚线 AB 切开,绿色部分是墙角三角形,棕色部分是圆弓形。超过半圆时,弓形依然完整位于弦背离 O 的一侧;改变的是圆弧角和圆心位置,面积拆分方法没有改变。两图比较拆分方式,绳长与端点并不相同。 本图绳长 1.300,圆弧角 140.0 度。所围面积 0.687841。 A B O 绳长 1.3 · 面积 0.687841
大圆弧:仍然是两部分相加
大圆弧:仍然是两部分相加 沿虚线 AB 切开,绿色部分是墙角三角形,棕色部分是圆弓形。超过半圆时,弓形依然完整位于弦背离 O 的一侧;改变的是圆弧角和圆心位置,面积拆分方法没有改变。两图比较拆分方式,绳长与端点并不相同。 本图绳长 4.000,圆弧角 234.9 度。所围面积 3.206944。 A B O 绳长 4 · 面积 3.206944
墙角三角形 弦外圆弓形 绳子
沿虚线 AB 切开,绿色部分是墙角三角形,棕色部分是圆弓形。超过半圆时,弓形依然完整位于弦背离 O 的一侧;改变的是圆弧角和圆心位置,面积拆分方法没有改变。两图比较拆分方式,绳长与端点并不相同。
接下来,沿图中的虚线切开,把所围区域拆成绿色的三角形 𝑂 𝐴 𝐵 O A B 与棕色的圆弓形。先算不依赖绳子弯曲方式的三角形:
𝐴 △ 𝑂 𝐴 𝐵 = 1 2 𝑎 𝑏 s i n 𝜃 . A △ O A B = 1 2 a b sin θ .
圆弓形的面积是扇形面积减去相应的有向 三角形面积,即
𝐴 s e g m e n t = 1 2 𝑅 2 ( 𝛼 − s i n 𝛼 ) . A segment = 1 2 R 2 ( α − sin α ) .
当 𝛼 > 𝜋 α > π 时,s i n 𝛼 < 0 sin α < 0 ,这个式子自动给出大弓形的面积,不需要另外拼一个公式。
暂时不把未使用墙段当作障碍,固定 𝑎 , 𝑏 a , b 时的最优面积是
𝐹 𝑠 ( 𝑎 , 𝑏 ) = 1 2 𝑎 𝑏 s i n 𝜃 + 𝑠 2 2 𝛼 2 ( 𝛼 − s i n 𝛼 ) , F s ( a , b ) = 1 2 a b sin θ + s 2 2 α 2 ( α − sin α ) ,
其中 𝛼 α 由上面的弦长方程确定。圆弧选在弦 𝐴 𝐵 A B 背离 𝑂 O 的一侧,使两部分面积相加。对任意固定端点,这首先是一个上界:画出的圆弧还可能穿过未使用的真实墙段。不过,让端点一起参与全局优化以后,最大值确实存在不穿墙的构造,下面会说明原因。
三个边界情况也很自然:𝑑 > 𝑠 d > s 时绳子够不到;𝑑 = 𝑠 d = s 时弓形面积为零;𝑑 = 0 d = 0 时取极限 𝑠 2 / ( 4 𝜋 ) s 2 / ( 4 π ) ,也就是整圆面积。
再让端点移动:有限墙的答案
有限墙的统一答案可以写成
𝐴 m a x ( 𝑠 , 𝑥 , 𝑦 , 𝜃 ) = m a x 0 ≤ 𝑎 ≤ 𝑥 , 0 ≤ 𝑏 ≤ 𝑦 𝑎 2 + 𝑏 2 − 2 𝑎 𝑏 c o s 𝜃 ≤ 𝑠 2 𝐹 𝑠 ( 𝑎 , 𝑏 ) . A max ( s , x , y , θ ) = max 0 ≤ a ≤ x , 0 ≤ b ≤ y a 2 + b 2 − 2 a b cos θ ≤ s 2 F s ( a , b ) .
这个表达式已经把“在所有曲线里找最优形状”化成了两个实数的优化。不过,还可以进一步降到一维。
如果两个端点都严格位于各自墙段内部,垂直条件仍然成立,圆心必须为 𝑂 O ,所以唯一的内部候选仍然是
𝑎 = 𝑏 = 𝑠 𝜃 . a = b = s θ .
它只有在
𝑠 ≤ 𝜃 m i n ( 𝑥 , 𝑦 ) s ≤ θ min ( x , y )
时才可行。一旦这个条件成立,有限墙能够实现无限墙的最优扇形,上界也就取到了,直接返回 𝑠 2 / ( 2 𝜃 ) s 2 / ( 2 θ ) 。
如果扇形放不下,最大值必在端点矩形的边界上。于是只需比较四个一维问题:
m a x 0 ≤ 𝑏 ≤ 𝑦 𝐹 𝑠 ( 𝑥 , 𝑏 ) , m a x 0 ≤ 𝑎 ≤ 𝑥 𝐹 𝑠 ( 𝑎 , 𝑦 ) , m a x 0 ≤ 𝑏 ≤ 𝑦 𝐹 𝑠 ( 0 , 𝑏 ) , m a x 0 ≤ 𝑎 ≤ 𝑥 𝐹 𝑠 ( 𝑎 , 0 ) , max 0 ≤ b ≤ y F s ( x , b ) , max 0 ≤ a ≤ x F s ( a , y ) , max 0 ≤ b ≤ y F s ( 0 , b ) , max 0 ≤ a ≤ x F s ( a , 0 ) ,
每项都只保留 𝑑 ≤ 𝑠 d ≤ s 的可行部分。最后两项是允许一个系绳点到达墙角的单墙情形,不能随意删除。
这里的“一维优化”仍然要求找全局 最大值。不同的圆弧分支可能竞争,不能未经证明就对整个区间做一次三分搜索。可以找齐区间端点与驻点,再比较面积;用于作图的密集采样加局部细化,只能视为数值近似。
用导数求一维候选,以及如何检查圆弧的位置 取坐标 𝑂 = ( 0 , 0 ) O = ( 0 , 0 ) 、𝐴 = ( 𝑎 , 0 ) A = ( a , 0 ) 、𝐵 = ( 𝑏 c o s 𝜃 , 𝑏 s i n 𝜃 ) B = ( b cos θ , b sin θ ) 。令
ℎ = 𝑅 c o s 𝛼 2 . h = R cos α 2 .
这里 ℎ h 是圆心到弦中点的有向距离,大圆弧时它可以为负。圆心 𝐶 = ( 𝑐 1 , 𝑐 2 ) C = ( c 1 , c 2 ) 为
𝑐 1 = 𝑎 + 𝑏 c o s 𝜃 2 − ℎ 𝑏 s i n 𝜃 𝑑 , 𝑐 2 = 𝑏 s i n 𝜃 2 + ℎ 𝑏 c o s 𝜃 − 𝑎 𝑑 . c 1 = a + b cos θ 2 − h b sin θ d , c 2 = b sin θ 2 + h b cos θ − a d .
把固定绳长的弓形面积记为 𝐺 𝑠 ( 𝑑 ) G s ( d ) 。对弦长方程和面积公式求导,可以得到
𝐺 ′ 𝑠 ( 𝑑 ) = − ℎ . G s ′ ( d ) = − h .
因此
𝜕 𝐹 𝑠 𝜕 𝑎 = 𝑏 s i n 𝜃 2 − ℎ 𝑎 − 𝑏 c o s 𝜃 𝑑 = 𝑐 2 , 𝜕 𝐹 𝑠 𝜕 𝑏 = 𝑎 s i n 𝜃 2 − ℎ 𝑏 − 𝑎 c o s 𝜃 𝑑 = 𝑐 1 s i n 𝜃 − 𝑐 2 c o s 𝜃 . ∂ F s ∂ a = b sin θ 2 − h a − b cos θ d = c 2 , ∂ F s ∂ b = a sin θ 2 − h b − a cos θ d = c 1 sin θ − c 2 cos θ .
这给出了不依赖图形直觉的端点条件:𝑎 a 自由时,圆心落在第一条墙线上;𝑏 b 自由时,圆心落在第二条墙线上;两者都自由时,圆心为 𝑂 O 。
圆弧可以通过
𝐶 + 𝑅 ( c o s ( 𝑡 0 + 𝑡 ) , s i n ( 𝑡 0 + 𝑡 ) ) , 0 ≤ 𝑡 ≤ 𝛼 , C + R ( cos ( t 0 + t ) , sin ( t 0 + t ) ) , 0 ≤ t ≤ α ,
画出,其中 𝑡 0 t 0 是向量 𝐴 − 𝐶 A − C 的极角。实际构造时,要检查整段圆弧而不只是端点:允许越过延长线,不等于允许穿过真实墙段。与第一条墙线的另一交点的坐标是 2 𝑐 1 − 𝑎 2 c 1 − a ;与第二条墙线的另一交点到 𝑂 O 的有向距离是 2 ( 𝑐 1 c o s 𝜃 + 𝑐 2 s i n 𝜃 ) − 𝑏 2 ( c 1 cos θ + c 2 sin θ ) − b 。同时检查交点是否落在实际墙段与所选圆弧上即可。
为什么统一公式的全局最大值一定能实现?分情况看:扇形没有问题;两个端点都在墙端时,没有需要绕开的剩余墙段;一个端点在 𝑂 O 时,可以把单墙圆弓形放到另一面墙的外侧。
只剩下一端在墙端、另一端自由的情形。不妨设 𝑎 = 𝑥 a = x 、0 < 𝑏 < 𝑦 0 < b < y 。驻点条件使圆心在第二条墙线上。若圆弧穿过这面墙的剩余部分,那么 𝐵 B 必须是圆与该射线的近交点,远交点到 𝑂 O 的距离为 𝑞 = 𝑏 + 2 𝑅 ≤ 𝑦 q = b + 2 R ≤ y 。因为圆心也在射线上,从 𝑂 O 看圆上各点的距离最小为 𝑏 b 、最大为 𝑞 q 。另一端 𝐴 A 不在这条直线上,所以
𝑏 < 𝑥 < 𝑞 ≤ 𝑦 . b < x < q ≤ y .
现在把整个构造关于墙角平分线反射,交换两端使用的墙长,得到 ( 𝑎 ′ , 𝑏 ′ ) = ( 𝑏 , 𝑥 ) ( a ′ , b ′ ) = ( b , x ) 。面积完全相同,却有 0 < 𝑎 ′ < 𝑥 0 < a ′ < x 、0 < 𝑏 ′ < 𝑦 0 < b ′ < y :两个端点都变成了内部点。若原构造是全局最大值,反射后的构造也必须是内部驻点,圆心就应当为 𝑂 O ;但它的圆心显然不是 𝑂 O ,矛盾。
因此,穿过剩余墙段的圆弧不可能赢得全局比较。这个论证使上面的无障碍面积上界在端点优化后成为可达到的答案;它并不意味着每一组固定端点的圆弧都可直接使用。
不扫描整个区间:最多三个圆弧驻点就够了 考虑 𝑎 = 𝑥 a = x 、𝑏 b 自由的边界。圆心在第二条墙线上,𝐵 B 既可能是圆与这条射线的远交点,也可能是近交点。分别用 𝜀 = 1 , − 1 ε = 1 , − 1 表示这两种情况。沿墙线与垂直墙线的两个方向分解半径,可以得到
𝑥 s i n 𝜃 = 𝜀 𝑅 s i n 𝛼 , 𝑏 = 𝑥 c o s 𝜃 + 𝜀 𝑅 ( 1 − c o s 𝛼 ) . x sin θ = ε R sin α , b = x cos θ + ε R ( 1 − cos α ) .
消去 𝑅 = 𝑠 / 𝛼 R = s / α ,得到
| s i n 𝛼 | 𝛼 = 𝑥 s i n 𝜃 𝑠 , 𝑏 = 𝑥 c o s 𝜃 + 𝑥 s i n 𝜃 t a n 𝛼 2 . | sin α | α = x sin θ s , b = x cos θ + x sin θ tan α 2 .
在 ( 0 , 𝜋 ) ( 0 , π ) 内,s i n 𝛼 / 𝛼 sin α / α 严格递减,至多有一个解。在 ( 𝜋 , 2 𝜋 ) ( π , 2 π ) 内,− s i n 𝛼 / 𝛼 − sin α / α 先增后减,分界点是
𝛽 c o s 𝛽 − s i n 𝛽 = 0 , 𝛽 ∈ ( 𝜋 , 3 𝜋 / 2 ) , 𝛽 ≈ 4 . 4 9 3 4 0 9 4 5 8 . β cos β − sin β = 0 , β ∈ ( π , 3 π / 2 ) , β ≈ 4.493409458 .
因此,将这三个单调区间分别二分,就找齐了所有驻点。把每个解代回 𝑏 b ,仅保留 0 < 𝑏 < 𝑦 0 < b < y 的候选。另一条边界交换 𝑥 , 𝑦 x , y 即可。
矩形角点还要单独检查。两端均在墙端的 ( 𝑥 , 𝑦 ) ( x , y ) 直接代入;落在坐标轴上的候选可以进一步简化:由于 𝐺 ′ 𝑠 ( 𝑑 ) = − 𝑅 c o s ( 𝛼 / 2 ) G s ′ ( d ) = − R cos ( α / 2 ) ,弓形面积在 𝛼 = 𝜋 α = π 时最大,对应 𝑑 = 2 𝑠 / 𝜋 d = 2 s / π 。所以两条坐标轴上的最优端点分别是
( 0 , m i n ( 𝑦 , 2 𝑠 𝜋 ) ) , ( m i n ( 𝑥 , 2 𝑠 𝜋 ) , 0 ) . ( 0 , min ( y , 2 s π ) ) , ( min ( x , 2 s π ) , 0 ) .
当扇形不可行时,两个单墙候选、一个双墙端点候选,以及每条固定墙端边界上至多三个驻点,合计最多九个候选,就覆盖了全局最大值。弦长等于绳长的直线边界不会产生最大值,理由与无限墙时相同。
短墙用满之后,圆心怎样移动?
为了看清最初的变化,不妨设 𝑥 ≤ 𝑦 x ≤ y 。当 𝑠 s 刚超过 𝜃 𝑥 θ x ,原来的扇形会先碰到短墙的墙端。此时令 𝑎 = 𝑥 a = x ,另一个端点暂时仍可沿长墙滑动。
因为 𝐵 B 自由,圆心 𝐶 C 必须在长墙所在的直线上。把 𝐶 C 在这条有向直线上的坐标记为 𝑡 t ,并取从扇形连续延伸出来的圆弧分支。短墙端点 𝐴 A 到长墙线的垂直距离为 𝑥 s i n 𝜃 x sin θ ;同一个距离也等于 𝑅 s i n 𝛼 R sin α ,所以
𝑅 s i n 𝛼 = 𝑥 s i n 𝜃 . R sin α = x sin θ .
结合 𝑠 = 𝑅 𝛼 s = R α ,得到
𝑠 𝑥 = 𝛼 s i n 𝜃 s i n 𝛼 , 𝜃 ≤ 𝛼 < 𝜋 . s x = α sin θ sin α , θ ≤ α < π .
沿长墙方向投影,还可以得到
𝑡 = 𝑥 c o s 𝜃 − 𝑅 c o s 𝛼 , t = x cos θ − R cos α ,
而 𝐵 B 在圆心前方一个半径处,因此
𝑏 = 𝑡 + 𝑅 = 𝑥 c o s 𝜃 + 𝑥 s i n 𝜃 t a n 𝛼 2 . b = t + R = x cos θ + x sin θ tan α 2 .
在起点 𝛼 = 𝜃 α = θ ,有 𝑅 = 𝑥 , 𝑡 = 0 , 𝑏 = 𝑥 R = x , t = 0 , b = x ,正好接上扇形。绳子继续变长,𝛼 α 与 𝑏 b 随之增大,圆心离开 𝑂 O 。
当这个分支碰到长墙端点时,𝑏 = 𝑦 b = y ,对应
𝛼 ∗ = 2 a r c t a n 𝑦 − 𝑥 c o s 𝜃 𝑥 s i n 𝜃 , 𝑠 ∗ = 𝑥 s i n 𝜃 𝛼 ∗ s i n 𝛼 ∗ . α ∗ = 2 arctan y − x cos θ x sin θ , s ∗ = x sin θ α ∗ sin α ∗ .
这描述了“短墙先受限、随后长墙也受限”的连续分支。它不是任意绳长下都成立的三段式答案 :继续增加绳长以后,还要与其他边界候选比较,尤其是只利用一面墙的候选。
两端自由
两端自由的绳子与墙示意图 墙角为六十度,墙长分别为一和二,绳长为1。阴影面积为0.477465。粗曲线是绳子,直线是实际墙段,虚线是端点之间的弦。圆心与墙角 O 重合。 O A B 绳长 1 · 面积 0.477465
短墙端点固定
短墙端点固定的绳子与墙示意图 墙角为六十度,墙长分别为一和二,绳长为2。阴影面积为1.386966。粗曲线是绳子,直线是实际墙段,虚线是端点之间的弦。圆心 C 在长墙线上。 O A B C 绳长 2 · 面积 1.386966
两端固定,大圆弧
两端固定,大圆弧的绳子与墙示意图 墙角为六十度,墙长分别为一和二,绳长为4。阴影面积为3.206944。粗曲线是绳子,直线是实际墙段,虚线是端点之间的弦。圆弧超过半圆,绕过短墙端点。 O A B C 绳长 4 · 面积 3.206944
同一对有限墙,三种绳长:圆心和端点随约束改变,大圆弧可以伸到墙的延长线之外。
图中取 𝜃 = 𝜋 / 3 , 𝑥 = 1 , 𝑦 = 2 θ = π / 3 , x = 1 , y = 2 ,三幅图使用相同的长度比例。实线是实际墙段,粗曲线是绳子,虚线是弦 𝐴 𝐵 A B ,阴影是围出的区域。圆心从墙角 𝑂 O 移到长墙线上,最后在两个端点都固定时离开两条墙线;第三幅图的绳子已经绕过短墙端点,伸到夹角之外。
一个数值例子,以及长绳子的反直觉之处
继续取 𝜃 = 𝜋 / 3 , 𝑥 = 1 , 𝑦 = 2 θ = π / 3 , x = 1 , y = 2 。用统一公式比较端点边界,可以得到下面的数值结果,均四舍五入到六位小数:
绳长 𝑠 s 使用第一面墙 𝑎 a 使用第二面墙 𝑏 b 圆弧角 𝛼 α 最大面积 1 1 0 . 9 5 4 9 3 0 0.954930 0 . 9 5 4 9 3 0 0.954930 1 . 0 4 7 1 9 8 1.047198 0 . 4 7 7 4 6 5 0.477465 2 2 1 1 1 . 9 2 5 3 7 7 1.925377 2 . 0 4 9 6 4 9 2.049649 1 . 3 8 6 9 6 6 1.386966 4 4 1 1 2 2 4 . 0 9 9 2 9 8 4.099298 3 . 2 0 6 9 4 4 3.206944 1 0 10 1 1 2 2 5 . 3 2 4 6 5 2 5.324652 1 1 . 6 9 9 5 0 9 11.699509 3 0 30 0 0 2 2 5 . 8 8 8 0 8 2 5.888082 8 1 . 4 2 1 5 1 1 81.421511
前两行分别是扇形与短墙受限的圆弧。第三行已经有 𝛼 > 𝜋 α > π ,是大圆弧。最后一行却把第一面墙的使用长度变成了零:绳子从 𝑂 O 出发,绕出一个大弓形,再接到第二面墙的墙端。
两面墙都用满
两面墙都用满 这次两图的绳长、墙长、夹角和绘图比例完全相同:绳长为十,两面墙各长一,夹角三十度。右图的弦更长,围出的面积也更大。第一面墙留在区域内部,绳子从它的墙端外面绕过,没有穿墙。 本图绳长 10.000,圆弧角 342.2 度。所围面积 9.049452。 A B O 绳长 10 · 面积 9.049452
把一个端点移到墙角
把一个端点移到墙角 这次两图的绳长、墙长、夹角和绘图比例完全相同:绳长为十,两面墙各长一,夹角三十度。右图的弦更长,围出的面积也更大。第一面墙留在区域内部,绳子从它的墙端外面绕过,没有穿墙。 本图绳长 10.000,圆弧角 326.9 度。所围面积 9.604790。 B O / A 绳长 10 · 面积 9.604790
这次两图的绳长、墙长、夹角和绘图比例完全相同:绳长为十,两面墙各长一,夹角三十度。右图的弦更长,围出的面积也更大。第一面墙留在区域内部,绳子从它的墙端外面绕过,没有穿墙。
为了让差别在图上更明显,上图另取两面等长的墙与三十度夹角。左图两段墙都在外边界上;右图只把其中一段墙作为外边界,另一段墙留在围出的区域内部。比较下面标出的面积,就能看到:省略一段外边界上的墙,确实可能围得更大。
为什么不用满两面墙反而更好?因为大圆弧接近整圆时,墙提供的弦长也很重要。两面墙都用满,弦长为
𝑑 𝑥 𝑦 = √ 𝑥 2 + 𝑦 2 − 2 𝑥 𝑦 c o s 𝜃 . d x y = x 2 + y 2 − 2 x y cos θ .
这个例子中 𝑑 𝑥 𝑦 = √ 3 < 2 = 𝑦 d x y = 3 < 2 = y 。不用第一面墙,虽然失去了三角形面积,却得到了更长的弦;绳子很长时,后者带来的收益会占上风。
更具体地,固定 𝑑 d ,令 𝑠 → ∞ s → ∞ 。此时 𝛼 → 2 𝜋 α → 2 π ,小缺口对应的弧长趋近于弦长 𝑑 d ,所以整个圆的周长约为 𝑠 + 𝑑 s + d 。由此得到
𝐺 𝑠 ( 𝑑 ) = 𝑠 2 4 𝜋 + 𝑠 𝑑 2 𝜋 + 𝑂 ( 1 ) . G s ( d ) = s 2 4 π + s d 2 π + O ( 1 ) .
三角形面积是有界的,而弦长增加带来的收益有一个与 𝑠 s 成正比的项。因此,长绳子的首要选择趋向于最大化弦长。矩形 [ 0 , 𝑥 ] × [ 0 , 𝑦 ] [ 0 , x ] × [ 0 , y ] 上,弦长的最大值为
𝑑 m a x = m a x { 𝑥 , 𝑦 , √ 𝑥 2 + 𝑦 2 − 2 𝑥 𝑦 c o s 𝜃 } . d max = max { x , y , x 2 + y 2 − 2 x y cos θ } .
这解释了为什么锐角墙可能最终只利用一面墙,也说明“既然墙免费,就一定应该全部用满”并不成立。这里说的是长绳极限下的趋势;有限 𝑠 s 的切换点仍应比较完整面积,而不能只比较弦长。
可直接运行的求解代码
下面的 Python 代码先计算固定端点的 𝐹 𝑠 ( 𝑎 , 𝑏 ) F s ( a , b ) ,再按上述三个单调区间找齐驻点,比较所有候选。它返回最大面积、两段被利用的墙长,以及绳子的圆弧角;数值精度受双精度浮点数限制。
from math import cos , hypot , pi , sin , tan
def area_for_endpoints ( s , theta , a , b ):
"""Return (area, arc_angle); infeasible endpoints return (-inf, None)."""
if s <= 0 or not 0 < theta < pi or a < 0 or b < 0 :
raise ValueError ( "Require s > 0, 0 < theta < pi, and a, b >= 0" )
d = hypot ( a - b * cos ( theta ), b * sin ( theta ))
triangle = a * b * sin ( theta ) / 2
if d > s :
return float ( "-inf" ), None
if d == 0 :
return s * s / ( 4 * pi ), 2 * pi
if d == s :
return triangle , 0.0
lo , hi = 0.0 , 2 * pi
for _ in range ( 80 ):
alpha = ( lo + hi ) / 2
chord_ratio = 2 * sin ( alpha / 2 ) / alpha
if chord_ratio > d / s :
lo = alpha
else :
hi = alpha
alpha = ( lo + hi ) / 2
# Avoid cancellation in alpha - sin(alpha) for short arcs.
if alpha < 1e-3 :
factor = alpha / 6 - alpha ** 3 / 120 + alpha ** 5 / 5040
else :
factor = ( alpha - sin ( alpha )) / ( alpha * alpha )
segment = s * s * factor / 2
return triangle + segment , alpha
def bisect_root ( f , lo , hi ):
"""The interval must bracket a root of the continuous function f."""
left = f ( lo )
if left == 0 :
return lo
if f ( hi ) == 0 :
return hi
for _ in range ( 80 ):
mid = ( lo + hi ) / 2
value = f ( mid )
if ( value > 0 ) == ( left > 0 ):
lo , left = mid , value
else :
hi = mid
return ( lo + hi ) / 2
def max_area ( s , x , y , theta ):
"""Return (area, used_first_wall, used_second_wall, arc_angle)."""
if min ( s , x , y ) <= 0 or not 0 < theta < pi :
raise ValueError ( "Require s, x, y > 0 and 0 < theta < pi" )
if s / theta <= min ( x , y ):
return s * s / ( 2 * theta ), s / theta , s / theta , theta
candidates = []
def add ( a , b ):
area , alpha = area_for_endpoints ( s , theta , a , b )
if alpha is not None :
candidates . append (( area , a , b , alpha ))
add ( 0 , min ( y , 2 * s / pi ))
add ( min ( x , 2 * s / pi ), 0 )
add ( x , y )
beta = bisect_root ( lambda t : t * cos ( t ) - sin ( t ), pi , 1.5 * pi )
peak = - sin ( beta ) / beta
for fixed , free , swap in [( x , y , False ), ( y , x , True )]:
k = fixed * sin ( theta ) / s
angles = []
if k < 1 :
def minor ( t ):
return ( sin ( t ) / t if t else 1.0 ) - k
angles . append ( bisect_root ( minor , 0.0 , pi ))
if k <= peak :
def major ( t ):
return - sin ( t ) / t - k
angles . append ( bisect_root ( major , pi , beta ))
angles . append ( bisect_root ( major , beta , 2 * pi ))
for alpha in angles :
moving = fixed * cos ( theta ) + fixed * sin ( theta ) * tan ( alpha / 2 )
if 0 < moving < free :
add ( moving , fixed ) if swap else add ( fixed , moving )
return max ( candidates , key = lambda result : result [ 0 ])
# (3.2069441257..., 1, 2, 4.0992982217...)
print ( max_area ( 4 , 1 , 2 , pi / 3 ))
检查实现时,至少核对这几个极限:𝑑 = 𝑠 d = s 时弓形面积为零;𝑑 = 2 𝑠 / 𝜋 d = 2 s / π 时圆弧是半圆;𝑑 → 0 d → 0 时面积趋于 𝑠 2 / ( 4 𝜋 ) s 2 / ( 4 π ) ;𝑎 = 𝑏 = 𝑠 / 𝜃 a = b = s / θ 时总面积回到 𝑠 2 / ( 2 𝜃 ) s 2 / ( 2 θ ) 。
无限墙的简洁答案来自两个端点都能自由滑动,迫使圆心固定在墙角。有限墙改变了这个端点条件:墙端可以固定住绳子,让圆心移动,也让大圆弧成为可能。保留“先求圆弧,再优化端点”这两个步骤,就能在同一个公式里处理这些变化。