Skip to content

一段高铁孪生:把量纲摆正之前,列车一直在半空里跑 ​

初始化中…

这篇的教训比前面几篇都密。原因是我第一版写完就认定"能跑就是对的",直到逐条核对量纲才发现:画面里跑的不是火车,是一堆各自成立的盒子。它们每一块的尺寸都合理,但相互之间的标高和朝向全对不上。

场景里有什么 ​

  • 桥梁:长 620 m 整孔箱梁,32 m 一跨共 19 座桥墩,梁顶铺装到轨枕。
  • 轨道:无砟轨道形式,钢轨顶面定在 0.45 m,轨枕 953 根按 0.65 m 间距实例化。
  • 接触网:12 档门型架,单条承力索 7.9 m、单条接触线 5.95 m,档内 2 根竖直吊弦。
  • 列车:8 节编组,单节 24.5 m、节间缝隙 0.7 m,全长约 202 m;2、5 车各一架受电弓。
  • 两端的山:各 240 m 深山体,洞口带门檐和门柱,列车从近端钻进去、从远端冒出来。
  • 一轮回:约 21 秒——出洞、过全桥、入洞,然后从头再来。

交给 AI 的提示词(我固定分四组写) ​

总体与尺度

  1. 纯程序化生成,不引入任何外部模型、贴图或 HDR;全部几何加材质参数。
  2. 所有尺寸按真实量纲写死:轨距 1435 mm、车轮直径 840 mm、车厢宽 3.0 m、长 24.5 m、接触线自轨头起算悬挂净空 5.50 m。
  3. 全场景只允许一条竖向基准线:先定钢轨顶面 y = 0.45,车轮中心、转向架、裙板、车体、车顶拱、受电弓、接触线的高度全部从这条线往下或往上推,不许各块自己找一个好看的 y。
  4. 桥梁长度必须大于「整列车上桥到整列车离桥」的行程,两端各接一段深度足以咽下整列车的山体。

走行部与车体

  1. 滚动圆落在 x = ±0.7175(轨距一半)上,不是车宽的一半;轮对轴向沿横坡方向,绕自身轴转动的同时轮周线速度等于车速,转过的角度用 speed / 半径 × dt 推。
  2. 车顶拱用半圆柱:先想清楚鼓包长在圆柱的哪一侧,再决定欧拉角怎么写,最后压扁成 0.45 m 的拱高。
  3. 车厢构件按"从下往上叠"排:轮心 0.87 → 转向架 1.25 → 裙板 1.95 → 车体 3.3 → 车窗带 3.85 → 侧色带 2.62 → 车顶拱 4.45;裙板要比车体窄、比转向架宽,才能露出轮子。
  4. 头车加鼻锥、司机室前窗与两盏大灯,编组绕自身原点居中,方便相机算车头车尾。

接触网与桥隧

  1. 承力索、接触线各自只有一条,且都必须在轨道中心正上方同一 x 上;吊弦上下两端同一个 x 才叫竖直,否则画面里就是一堆斜拉的乱线。
  2. 腕臂从两侧支柱斜拉到轨道中心上方,用 LineSegments 一段段连线,不用贴图。
  3. 洞门是一套构件:山体前表面、洞口暗面、门檐、两根门柱,全部以同一个 face 值为基准偏移,山体在前、门脸露在山体外面。

镜头、阴影与读数

  1. 阴影相机只有 260 m 见方,光源和它的 target 必须每帧跟着列车平移,否则 620 m 的线路只有中段有影子。
  2. 相机分两态:列车可见时贴车跟随,不可见时退到洞口外盯着将要出来的门;判定用「车头已探出洞口且车尾还没进洞口」,两态之间 smoothstep 过渡。
  3. 拖拽随时接管,5 秒后指数缓动回巡游;卸载时几何、材质、控制器全部释放。
  4. 零控件,读数全写在左下角:车速、编组、阶段、轮径轨距、接触线高度、桥梁长度、桥墩数、三角面、帧耗时。

实现里几个值得记的点 ​

半圆柱的鼓包不是朝上的。 车顶拱我用 CylinderGeometry(1.5, 1.5, CAR_LEN, 14, 1, false, 0, Math.PI),只写了 rotation.x = Math.PI / 2。轴确实躺到列车长度方向去了,但鼓包长在车身两侧——第一版看起来像两节圆柱贴在车厢腰上。原因是半圆柱的角度从 0 到 π,顶点全落在自身 +X 一侧;绕 X 转 90° 不动 +X,鼓包自然还在横向上。Three 的 'XYZ' 欧拉序对应 R = Rx·Ry·Rz,我把复合矩阵推了一遍:要 rotation.y = +90° 才把局部 +X 送到世界上方。这类"看起来只是转了一下"的错,只靠肉眼看成品很难定位到是欧拉序的问题。

没有基准线,就没有「落在钢轨上」。 第一版轮心给 0.56、钢轨顶面算下来 0.45,等于轮子下半截埋进轨腰;裙板中心 0.86、高 0.9,把转向架整个包住,画面里看不见任何走行部。修正办法不是逐个调 y,而是先把轨头顶面钉成 0.45 这个数,然后所有构件的标高都由它推:轮心 = 0.45 + 0.42,裙板底要高于轮顶 1.29 且低于转向架顶,车体顶 4.45 就是车顶拱的落脚点。定死一条线之后,改哪个构件的高度都不用重新对齐全车。

轨距的一半不是车宽的一半。 轮对我写成 wx = ±1.0,看着像压在轨上,其实是靠轮缘外侧 0.28 m 悬在钢轨外面。滚动圆应该在 ±0.7175(1435 mm 的一半),加上轮缘余量取 ±0.72。类似的还有接触线:真实净空是从轨头起算 5.5 m,不是从桥面也不是从地面,所以接触线 y = 0.45 + 5.50 = 5.95,正好贴住受电弓集电条。

桥长和行程必须一起改。 第一版桥 300 m、列车行程 535 m,出桥之后车还在往+z 跑,桥台外面没有路基,整列车就悬在 y≈3 的位置,底下是 24 m 深的空地。这不是"少画了一段路",是运动定义和静态定义没打通。改法是把桥加到 620 m、两端各塞 240 m 深的山体,再把行程写成 2 × (洞口位置 + 半列车长 + 余量),让起点和终点都在石头里面。

洞门不能画在山体内部。 山体的前表面我算成 z = -145,门脸写在 z = -151.2——差 6 m,门完全被石头盖住,页面上只看到一面山壁。正确顺序是先定山体前表面 face,再让门檐、门柱、洞口暗面各自相对 face 偏移零点几米,全部留在石头外面。

三条导线不共线,就成了乱线。 第一版承力索在 x = ±1.6、接触线在 x = ±1.1、吊弦两端 x 还不一样,画出来像一捆随手撒的斜线。真实简单链形悬挂里承力索和接触线各只有一条、都在轨道中心正上方,吊弦是竖直的。我把它们统一到 x = 0,腕臂负责从两侧支柱斜拉到中心,横截面关系立刻清楚。

阴影只盖住了桥中段。 方向光的阴影相机是它自己那个小正交盒,我给到 ±130,而线路 620 m。加了 sun.target 并把它 scene.add 进去(不加进去 target 不生效),每帧把光源和 target 一起沿 z 平移到列车位置,影子才跟着车走。

跟机会把镜头开进山里。 贴车跟随时机位 z 直接取 列车 z + 18,列车还在洞口内侧时这个值已经进了山体,画面一片黑。现在按「车头探出洞口、车尾还没进洞口」算一个可见度权重,可见度为 0 时相机退到洞口外固定距离盯门,同时把跟随 z 夹在 ±(face - 18) 之内。夹取是兜底,权重才是决定性的。

读数别拿列车原点当列车。 阶段判定原来用 train.position.z < -BRIDGE / 2 判"出洞口",但编组居中后原点在列车中点:车头早已出洞、中点还在桥外,标签停在"洞内"。现在用 noseZ / tailZ 两个量分别和洞口比,中间再留 46 m 的"洞口过渡"带。同理桥墩数原来报 piers + 1,循环改写后墩身起点内缩了 20 m,墩数就是 piers,多加的那一根已经不存在了。

每帧 new Vector3 是白扔的。 相机目标点每帧构造两个向量、clone().setZ() 再来一个,一轮 1200 多帧全是垃圾。改成 camFollow / camWide / want / wantLook 四个常驻对象,用 .set() 覆写。

按交付要求核对 ​

要求实际做到判定
零外部素材全几何 + 材质参数,无模型无贴图达成
真实量纲轨距 1435、轮径 840、净空 5.50 m 均由常量推导达成
单一竖向基准轨头顶面 0.45,全车标高向下/向上推达成
车顶拱朝上欧拉序推导后 rotation.x + rotation.y 双转达成
车轮压轨滚动圆 x = ±0.72,轮底恰在轨头达成
桥隧闭环桥 620 m、两端 240 m 山体,行程全程在实体上达成
洞门可见门脸、门檐、门柱都在山体前表面外侧达成
接触网共线承力索 7.9 / 接触线 5.95 均在轨道中心上方,吊弦竖直达成
阴影覆盖光源与 target 每帧跟车平移达成
相机不穿山体可见度权重 + z 夹取达成
文字读数无控件五项读数,页面无按钮达成
卸载清理几何、材质、控制器全部释放达成

已知不足 ​

  • 只有外形,没有系统。 无砟轨道做成了轨枕加钢轨的混合形式(真实高铁区间一般是整体道床);没有 CRTS 板、没有扣件、没有电缆槽和遮板。
  • 直线到底。 没有平面曲线和竖曲线,因此没有曲线超高、没有加宽,桥梁也是等高的——真实线路的纵坡会明显影响桥墩长度。
  • 隧道内部是空的。 列车一进洞就靠"看不见"糊过去,没有衬砌、没有中心水沟、没有洞内照明带,进洞瞬间其实能瞥见黑块。
  • 受电弓不认识接触线。 集电条高度是固定值,没有按接触线的拉出值和弛度做跟随,也没有离线火花。
  • 轮对不转向。 两个转向架在直线段没问题,但轮对是各自独立转的刚体,过曲线会立刻露馅。
  • 声屏障是整面通长板。 真实屏障是分单元插入 H 钢立柱的,这里两端立柱和中间的板是各自独立生成的,接缝处几何上有穿插。
  • 没有真实时间基准。 帧间时间被截在 0.05 秒以防卡顿后镜头瞬移,代价是后台标签页里这一轮 21 秒会走得非常慢,切回前台才恢复。

本站所有 3D 孪生场景、可视化系统均为个人技术实验 Demo,仅用于技术学习与效果展示,不属于对外运营平台,不提供任何商业服务。

本站为个人技术展示网站,仅用于个人研发作品、3D 数字孪生技术学习展示,无任何经营性服务、无社区互动、不对外提供商业服务。

本站为个人技术展示网站,仅用于个人研发作品、3D 数字孪生技术学习展示,无任何经营性服务、无社区互动、不对外提供商业服务。

蜀ICP备2026068005号-1|个人 3D 数字孪生技术研发展示站