Hengefinder:城市太阳对齐的几何学与算法
每年两次,成千上万的人聚集在纽约市观看“曼哈顿日晷”(Manhattanhenge),那是夕阳与城市街道东西向网格完美对齐的短暂时刻。虽然这一现象是当地的明星,但其背后的几何是普遍的。如果太阳能与曼哈顿的街道对齐,它也能与世界任何地方的街道对齐——前提是该街道的方位与日落时太阳的方位角相匹配。
构建一个用于预测这些时刻的工具,称为 Hengefinder,需要在简单假设与球面三角学和轨道力学的复杂现实之间架起桥梁。下面深入探讨计算城市太阳对齐时所涉及的技术挑战。
道路方位的挑战:地球不是平的
要找到一个“日晷”时刻,第一步是确定街道的方位——相对于真北的角度。常见的直觉是取街道上的两个点(纬度和经度),计算坐标差异,并使用 atan2 求得角度。然而,这假设了笛卡尔平面,而在球面上并不存在这样的平面。
经度收敛问题
纬线间距均匀,但经线在向极地区域收敛。例如,在纽约市一度经度大约相当于 52 英里,而在安克雷奇仅约 33 英里。如果在三角函数中将这些度数视为相等的单位,方位计算将会出现偏差。
为了解决此问题,需要将经度乘以纬度的余弦进行缩放。这将在计算角度之前,使纬度和经度具有可比的单位:
# Corrected approach for short street segments
delta_y = lat_2 - lat_1
mean_lat = math.radians((lat_1 + lat_2) / 2)
delta_x = (lon_2 - lon_1) * math.cos(mean_lat)
bearing_rad = math.atan2(delta_x, delta_y)
bearing_deg = math.degrees(bearing_rad)
通过二分搜索重新定义“日落”
标准天文库,例如 Python 的 Astral,将日落定义为太阳完全沉入地平线以下的时刻。对于日晷而言,这已经太晚;目标是找到太阳光盘刚好触及地平线的瞬间。
边界搜索 vs. 值搜索
由于太阳的高度在接近地平线时单调变化,这个问题非常适合二分搜索。然而,标准的二分搜索寻找的是特定的数值。在本例中,开发者需要一种“最后为真”的二分搜索——找到太阳高度仍高于特定目标阈值的最后一分钟。
与其搜索 altitude == target,算法评估的是一个布尔值:“太阳是否仍在目标高度之上?”
while left < right:
mid = (left + right + 1) // 2 # Upper-biased midpoint
if altitude > target:
left = mid # Valid, could be the last one
else:
right = mid - 1 # Invalid, look earlier
寻找对齐:两阶段搜索
一旦知道道路方位和太阳的方位角(相对于北方的角度),最后一步是找出它们相匹配的日期。这并不简单,因为一年中太阳的方位角并非单调——它沿着一条平滑曲线运动,在至点时会改变方向。
阶段 1:粗略采样
为了避免对全年每一天都计算方位角(这将耗费大量计算资源并导致过多的 API 调用),采用粗略搜索,每 30 天采样一次。如果满足以下条件,算法会标记一个窗口以供进一步调查:
- 满足中值定理:太阳的方位角在两个采样点之间跨越道路方位。
- 出现方向反转:方位角改变方向,意味着出现了峰值或谷值,可能恰好与道路方位相符。
阶段 2:细粒度搜索
一旦确定了潜在窗口,工具会切换到逐日搜索,以精确定位对齐的具体日期和时间。
更广泛的应用与局限性
虽然 Hengefinder 侧重于日落,但其逻辑可扩展到其他天体和对齐方式。该应用的移动版已将范围扩大到包括月亮以及“索伦日晷”(Sauron Henges),即太阳或月亮与特定建筑顶部完美对齐。
社区见解与反驳
该项目引发了关于太阳追踪实用性的讨论。一些用户指出,虽然二分搜索是一个优雅的编程练习,但可以直接使用来自 NOAA 等来源的太阳方程来计算太阳位置。另一些人则指出当前模型的局限性:
“它无法适用于弯曲的街道。”
此外,这类计算的实用性超越了审美。一位评论者提出了“逆向 Hengefinder”——一个预测城市阴影区域的应用,帮助家长为对热敏感的孩子规划最凉爽的路线。
结论
城市日晷在几何上稀有,却在全球范围内不断出现。从阿姆斯特丹的直运河到纽约的摩天大楼,这些时刻是人类城市规划与天体力学交汇的结果。通过将问题视为一系列“封闭盒子”——球面几何、边界搜索以及粗到细的采样——Hengefinder 将复杂的天文问题转化为可用于城市探索的实用工具。