太阳影子定位的几何建模与参数化(2015A 范文一)
一、问题重述
2015 年国赛 A 题"太阳影子定位"要求:已知一根竖直立杆的高度 ,以及某日从早到晚拍摄的视频中影子尖端在地面上的轨迹 (以杆底为原点、北为 轴、东为 轴),反推拍摄地点的纬度 、经度 与拍摄日期(日序 )。本题本质是一个天文几何正演—反演问题:先用太阳运动规律把"地理位置 + 时间"映射成"影子形态",再反过来由影子形态拟合出地理位置。
本文(范文一)聚焦正演几何建模,把影子长度、方向、随时间的变化规律用闭式公式显式表达,为后续反演(范文二)与稳健性分析(范文三)奠定物理基础。
二、天文几何基础
太阳相对地面的位置由三个角度刻画:
赤纬 :太阳直射点纬度,由日序 决定(Cooper 近似)
本文取真实场景:北京 、拍摄于夏至 ,此时 达到年度最大。时角 :太阳相对当地正午转过的角度,与本地太阳时 的关系为 。
太阳高度角 :由纬度、赤纬、时角共同决定
这三个量是连接"时间—空间—影子"的桥梁。给定一个相机时钟(本文采用 UTC+8 的北京时),本地太阳时满足 ,从而 可由时钟唯一算出——这正是经度能够反演的数学依据。
值得强调,经度 并非以显式出现在某一个时刻的影子坐标中,而是通过"本地太阳时的整体平移"间接编码:在相同的钟面时刻下,位置偏东( 大)的地点太阳更早偏西,其影子方向会整体相对偏西偏移。因此经度信息蕴含在"影子形态随时间推移的相位平移"里,而非某一瞬时快照。这也解释了为何本题给出全天连续视频而非单张照片——单时刻影子只能约束 的组合,唯有利用一段连续时刻的轨迹,才能把经度从时角项中分离出来。同理,若相机时钟本身未与标准时对齐(存在未知钟差),则该钟差将与经度完全耦合、不可分辨,必须在模型中作为额外未知量一并估计,或借助已知参照时刻(如日出日落)加以消除。
三、垂直杆影子的几何模型
设杆高为 ,太阳高度角为 ,则影子长度必然满足
当太阳越高( 大),影子越短;正午 最大,影子最短。这一闭式关系见图 7,呈典型的 形:高度角低于约 时影子迅速拉长。
影子不仅有长度,还有方向。在局部东北天(ENU)坐标系中,太阳方向单位向量为
影子尖端落在太阳的反方向上,故影子尖端坐标为
这就是本题的正演模型:输入 ,输出影子尖端 。图 6 给出了"垂直杆—太阳—影子尖端"的几何关系示意,红色线段即影子,其长度与方向完全由 决定。
四、影子随时间的形态
把正演模型代入真实参数,可得到一整天的影子轨迹。图 1 显示影子尖端在地面上的散点轨迹:从上午向东偏北延伸,到正午最短且近乎正北,午后转向西偏北——轨迹是一条关于南北轴展开、东西两支近似对称的弧(受采样窗相对真太阳正午 不完全对称影响,两支长度略有差异),这是北半球夏至日中纬度地区的典型形态。
图 2 给出太阳高度角 随相机时钟的变化:上午 9 点约 ,正午前后升至峰值 ,下午 15 点回落到约 。由于 在一天内先升后降,影子长度 必然先降后升,在正午达到最小。
图 3 实证了这一规律:实测影长从上午 9 点的约 单调下降到正午前后约 (最短),再回升到下午约 ,模型拟合曲线与实测点几乎重合,印证正演公式正确。本文场景共 13 个测量时刻(9:00–15:00 每 0.5 h),影长范围约 。
图 5 展示影子方位角(相对正北,东为正)的日变化:上午影子指向西北(方位角为负),正午指向正北(接近 ),下午指向东北(方位角为正),全天跨越约 。方位角与影长的联合变化,共同把"地理位置信息"编码进了影子轨迹。
七、结论
本文针对该问题建立了系统化的数学模型,通过理论分析与数值计算相结合的方法,得出了以下主要结论:
模型有效性验证:所提出的模型在给定数据集上表现出良好的拟合效果,各项性能指标均达到预期要求。
关键因素影响:通过灵敏度分析发现,参数X对结果影响最为显著,建议在后续研究中重点关注该参数的标定。
应用前景:本研究结果为类似问题提供了可借鉴的分析框架,具有较好的理论价值与实际应用潜力。
未来工作可沿以下方向展开:(1)拓展模型至更复杂的场景;(2)引入更多真实数据进行验证;(3)探索模型与其他方法的结合。
五、赤纬与日期的关系
影子形态由 与 共同决定,而 是日期的一一(除半年度歧义外)函数。图 4 画出 的全年曲线:在 (夏至)达到 ,在 (冬至)达到 。因此一旦从影子反演出 ,就能反推日序——这是"由影子定日期"的物理通道。需注意 关于年中心对称,同一赤纬值对应两个日序(如夏半年与冬半年),这一歧义将在范文三专门讨论。
六、几何灵敏度:哪些参数"显形"在影子里
理解参数对影子的灵敏度,是设计反演策略的前提。我们考察两类灵敏度:
(1)高度角的控制作用。由 可知,影长对 高度敏感,尤其当 较小时(清晨/黄昏)影长变化剧烈;而 又由 三者耦合决定,所以影长曲线同时携带了纬度、日期、时刻三类信息。
(2)纬度的区分能力。图 8 比较了 (广州一带)、(北京)、(高纬)三地在同日期下的影长曲线:低纬度地区正午影长明显更短、且全天影长变化更平缓;高纬度则相反。说明纬度差异会在影子形态上留下可分辨的印记,这正是纬度可被反演的根本原因。
进一步看,赤纬 的影响与纬度耦合:夏至日()中纬度地区的正午影长远小于冬至日。因此"纬度"与"日期"在影长公式中并非完全独立——反演时通常以 为联合待估参数,再用 映射得到日期,避免直接拟合高度非线性的日序。
这一耦合也给反演带来实际约束:当观测仅覆盖白天的部分时段(如本文 9:00–15:00),赤纬与纬度的部分效应会沿相近方向投影到影子形态上,导致二者估计存在弱相关;若进一步缩短观测窗口(如仅取正午前后两小时),这种耦合会显著增强,估计协方差变大。因此观测时段越完整,纬度与日期的可分离性越好——这是设计采样方案时的重要经验法则。与之相对,经度由时角相位独立承载,受时段完整度影响较小,但依赖时钟与标准时的对齐精度。
从工程实践看,上述耦合结构反过来指导了观测方案的设计:布设测量时应尽量覆盖正午前后对称、且跨度尽可能大的时段,使赤纬的振幅效应与经度的相位效应都能充分显现;影子坐标须以同一杆底原点、同一北东参考系记录,避免坐标系错配引入系统性偏差。本文在生成练习数据时已遵循这些原则,使后续反演获得良好可分性。可见,正演建模不仅服务于反演本身,其灵敏度分析还反过来优化了实验设计——这正是"模型—数据"相互印证的典型范例。
六之补、坐标约定与单点数值算例
为避免符号歧义,本文统一坐标约定:杆底为原点,正北为 轴、正东为 轴、天顶为 轴;太阳方位角 定义为从正北顺时针量到太阳水平投影的角度,故太阳水平单位向量为 。影子与太阳反向,因此影子尖端落在 方向,长度由 给出。
代入真实参数的一个具体算例:取 clock h,则 h,。代入球面公式得 ,即 ,影子长度 ,与图 3 上午 9 点的实测影长(约 ,含噪声)一致,验证了闭式正确。下午 15 点对应 ,影子转向西偏北、长度约 ,与上午 9 点(东偏北、约 )共同构成图 1 轨迹的左右两支(两者长度略有差异,源于采样窗相对真太阳正午 不完全对称)。
进一步,若把杆高 当作未知量一并估计,则 与 完全线性相关(),单日数据无法区分"高杆长影"与"矮杆短影"。因此实际反演中杆高 必须由题设给定或独立标定,这也是国赛原题提供杆高的原因。本文取 作为已知前提。
七、小结
本文建立了太阳影子定位问题的完整正演几何模型:
- 太阳高度角 由 经球面三角公式决定;
- 影子长度 、方向由太阳方位角反向给出,尖端坐标有闭式表达;
- 影子轨迹、影长、方位角的日变化规律均可由该模型精确复现(图 1–图 3、图 5);
- 赤纬 与日序 一一对应(除半年度歧义),构成"由影子定日期"的通道;
- 纬度与日期的差异都会在影子形态上留下可分辨印记,使反演在原理上可行。
需要强调,本文练习数据按天文几何模型确定性生成(固定随机种子,含 观测噪声),用于方法验证而非真实赛题测量值。从建模角度看,太阳影子定位的优雅之处在于:它将一个看似复杂的"视频反演地理"问题,约化为几条球面三角恒等式与一条 关系,物理直觉与数学工具在此高度统一。下一篇将把"由影子反推 "形式化为一个非线性最小二乘问题,并给出自写的 Levenberg–Marquardt 反演算法。
附录:正演模型与关键数值(可运行)
import sys, os, math
sys.path.insert(0, os.path.join("..", "..", "..", "tools"))
import gen_data as GD
H, phi, lam, n = 3.0, 39.9, 116.4, 172
delta = GD.declination(n)
print("杆高 H=%.1f m, 纬度 φ=%.1f°, 经度 λ=%.1f°, 日序 n=%d" % (H, phi, lam, n))
print("赤纬 δ=%.3f°" % delta)
obs = GD.gen_2015a()["obs"]
print("测量时刻数 =", len(obs), "(9:00–15:00 每0.5h)")
# 复现正午最短影
r = [math.hypot(x, y) for (_, x, y) in obs]
print("影长范围 r = [%.3f, %.3f] m" % (min(r), max(r)))
print("最短影对应时钟 = %.1f h(正午)" % obs[r.index(min(r))][0])
# 复现正演公式
c = 12.0
LST = c - 8.0 + lam / 15.0
w = math.radians(15.0 * (LST - 12.0))
sina = math.sin(math.radians(phi)) * math.sin(math.radians(delta)) + \
math.cos(math.radians(phi)) * math.cos(math.radians(delta)) * math.cos(w)
alpha = math.degrees(math.asin(sina))
x, y = GD.shadow_tip(c, phi, lam, delta, H)
print("clock=12 时: α=%.2f°, 影子尖端 (x,y)=(%.3f, %.3f) m, 影长=%.3f m"
% (alpha, x, y, math.hypot(x, y)))
参考文献
[1] Author A, Author B. Title of the paper[J]. Journal Name, Year, Volume(Issue): Pages.
[2] Author C. Title of the book[M]. City: Publisher, Year.
[3] Author D, Author E. Title of the article[J]. Conference Proceedings, Year: Pages.