公路造价工程师考试真题—双塔双索面混凝土斜拉桥(WorkBuddy建模)
- 2026-11-07 06:58:17
公路造价工程师考试真题—双塔双索面混凝土斜拉桥(WorkBuddy建模)为跨越无水的山区大峡谷而修建一座双塔双索面混凝土斜拉桥,桥梁全长456m,桥梁布置为 (121+214+121m),桥梁宽度 24.5m,索塔高 140 m。主梁采用单箱双室三向预应力混凝土结构。0 号块长 20m,中跨和边跨合拢段长度均为 2m,边跨现浇段长13m。0 号块和边跨现浇段均采用钢管桩支架,支架下部高度 40m,采用 Φ60cm 钢管(钢管延米质量 88.73kg,考虑连接的横撑、斜撑等,按15%考虑),上部为贝雷梁搭设的平台,高度 2m,全桥主梁每节段长6m,采用挂篮逐段对称悬浇,平均10 天一个节段,单个挂篮重量 172t。全桥混凝土采用泵送施工工艺,平均运距3km,拌合站场地及安拆费用不计。 全桥配有塔吊和电梯,其使用费计入到主梁混凝土费用中。 
整体效果: 
侧面效果: 
0号块下部钢管支撑细部: 
施工电梯及塔吊: 
劲性骨架: 
源代码: 使用方法:新建文本文档,复制粘贴保存,再将后缀名txt改为html,建议用 Microsoft Edge、Chrome等浏览器打开网页。 直接下载:https://pan.baidu.com/s/1CDV9qAmjoyQZgMZovnF-_w?pwd=y4wk 提取码: y4wk






⚠️ 唯一前提:接收者的电脑能联网
打开时页面会从 CDN 拉取一次 Three.js 3D 引擎(约 600KB,正常网络 1~2 秒) 代码里已做了三重保险:jsdelivr → unpkg → cdnjs 三个源自动切换。 如果在断网/内网环境(比如工地现场无外网),页面会显示"3D 引擎加载失败,请检查网络后刷新页面"。
<!DOCTYPE html><htmllang="zh-CN"><head><metacharset="UTF-8"/><metaname="viewport"content="width=device-width, initial-scale=1.0"/><title>0号块钢管桩支架三维布置 · 双塔双索面混凝土斜拉桥</title><style>* { margin:0; padding:0; box-sizing:border-box; }html,body { width:100%; height:100%; overflow:hidden; font-family:"Microsoft YaHei","PingFang SC",sans-serif; background:#eef1f5; }#container { width:100%; height:100%; }canvas { display:block; }#header { position:fixed; top:14px; left:16px; z-index:10; pointer-events:none; }#header h1 { font-size:18px; color:#2b3a4a; font-weight:700; text-shadow:0 1px 2px rgba(255,255,255,.85); }#header p { font-size:12px; color:#5a6b7d; margin-top:4px; text-shadow:0 1px 2px rgba(255,255,255,.85); }#panel { position:fixed; top:14px; right:16px; z-index:10; width:236px; background:rgba(255,255,255,.94); border:1px solid #d5dce4; border-radius:10px; padding:14px 14px 12px; box-shadow:0 4px 16px rgba(30,50,80,.12); max-height:calc(100% - 40px); overflow:auto; }#panel h3 { font-size:13px; color:#33475e; margin-bottom:9px; border-bottom:1px solid #e3e8ee; padding-bottom:6px; }.legend { display:flex; align-items:center; margin-bottom:5px; font-size:12px; color:#44576a; }.legend .swatch { width:16px; height:16px; border-radius:3px; margin-right:8px; flex:none; border:1px solid rgba(0,0,0,.12); }.ctrl { display:flex; align-items:center; margin:6px 0; font-size:12px; color:#44576a; cursor:pointer; user-select:none; }.ctrl input { margin-right:7px; accent-color:#2f6fb2; cursor:pointer; }.views { display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }.views button { flex:1 1 44%; padding:6px 0; font-size:12px; border:1px solid #c3ccd6; background:#fff; color:#33475e; border-radius:6px; cursor:pointer; transition:all .15s; }.views button:hover { background:#e8f0f9; border-color:#2f6fb2; }.note { margin-top:10px; font-size:11px; color:#7a8a9c; line-height:1.7; background:#f4f7fa; border-radius:6px; padding:8px 10px; }#tip { position:fixed; bottom:14px; left:50%; transform:translateX(-50%); z-index:10; background:rgba(255,255,255,.88); border:1px solid #d5dce4; border-radius:20px; padding:6px 18px; font-size:12px; color:#5a6b7d; white-space:nowrap; pointer-events:none; box-shadow:0 2px 8px rgba(30,50,80,.08); }#load-error { display:none; position:fixed; inset:0; z-index:99; background:#f7f9fb; color:#c0392b; font-size:14px; padding:80px 40px; text-align:center; line-height:2; }#load-error code { background:#f0f2f5; padding:2px 8px; border-radius:4px; font-size:12px; }#xsect { display:none; position:fixed; left:16px; bottom:56px; z-index:10; width:330px; background:rgba(255,255,255,.97); border:1px solid #d5dce4; border-radius:10px; padding:10px 12px 8px; box-shadow:0 4px 16px rgba(30,50,80,.16); }#xsect .xs-head { font-size:13px; color:#2b3a4a; font-weight:700; margin-bottom:4px; display:flex; justify-content:space-between; align-items:center; }#xsect .xs-close { cursor:pointer; color:#8a93a3; font-size:15px; line-height:1; padding:2px 5px; border-radius:4px; }#xsect .xs-close:hover { background:#eef1f5; color:#c0392b; }#xsect svg { width:100%; height:auto; display:block; }#xsect .xs-foot { font-size:11px; color:#6b7c8e; line-height:1.65; margin-top:4px; border-top:1px dashed #d5dce4; padding-top:6px; }</style></head><body><divid="container"></div><divid="header"><h1>全桥 456m 三维布置 · 双塔双索面混凝土斜拉桥</h1><p>布置 (121+214+121)m · 索塔 140m×2 · 0号块 20m×2 · 悬浇段 16段×6m×4组(64段)· 边跨现浇段 13m×2 · 合拢段 2m×3 · 钢管桩支架 + 贝雷梁平台 + 挂篮 · 措施设备:塔吊×2 + 施工电梯×2 + 混凝土泵管 + 液压爬模 + 塔顶缆索吊机 + 混凝土拌合站/泵站(平均运距3km)</p></div><divid="panel"><h3>结构图例</h3><divclass="legend"><spanclass="swatch"style="background:#4a5f7a"></span>索塔 / 下横梁 / 上横梁(永久结构)</div><divclass="legend"><spanclass="swatch"style="background:#7d8a99"></span>过渡墩(边跨现浇段端部支点)</div><divclass="legend"><spanclass="swatch"style="background:#e8913a"></span>0号块 / 边跨现浇段主梁(单箱双室,半透明)</div><divclass="legend"><spanclass="swatch"style="background:#e0453a"></span>钢管桩支架 Φ60cm×40m(视觉放大)</div><divclass="legend"><spanclass="swatch"style="background:#8ba3b8"></span>平联(横撑,每10m一道)+剪刀撑(斜撑,四周X形)</div><divclass="legend"><spanclass="swatch"style="background:#c96a2e"></span>索塔劲性骨架(塔肢内角钢桁架:立柱+平联+剪刀撑)</div><divclass="legend"><spanclass="swatch"style="background:#5d7186"></span>节点板+M20螺栓(6m节段分缝处)</div><divclass="legend"><spanclass="swatch"style="background:#f0941e"></span>上塔柱锚固区(95~140m)骨架加密段</div><divclass="legend"><spanclass="swatch"style="background:#f2c14e"></span>贝雷梁平台(2m 高)</div><divclass="legend"><spanclass="swatch"style="background:#3fa06b"></span>挂篮(示意)</div><divclass="legend"><spanclass="swatch"style="background:#f0c040"></span>塔吊(附壁式,每塔1台 H≈150m)</div><divclass="legend"><spanclass="swatch"style="background:#4db8a0"></span>施工电梯(附壁于塔柱外侧)</div><divclass="legend"><spanclass="swatch"style="background:#d43a2f"></span>混凝土泵管(塔柱附壁竖管 + 梁面水平管)</div><divclass="legend"><spanclass="swatch"style="background:#c8a04e"></span>液压爬模(索塔施工模板 + 爬升平台)</div><divclass="legend"><spanclass="swatch"style="background:#ff7f2a"></span>塔顶缆索吊机(主索 + 起重小车 + 背索锚碇)</div><divclass="legend"><spanclass="swatch"style="background:#5f8fa8"></span>混凝土拌合站 / 泵站(山谷两岸场站,运距≈3km)</div><divclass="legend"><spanclass="swatch"style="background:#9aa4b0"></span>斜拉索(双索面)</div><divclass="legend"><spanclass="swatch"style="background:#6fa8dc"></span>悬浇段 16段×6m×4组(单箱双室三向预应力,待施工半透明)</div><divclass="legend"><spanclass="swatch"style="background:#e74c3c"></span>纵向预应力筋(悬浇段顶/底板内,顺桥向 Z)</div><divclass="legend"><spanclass="swatch"style="background:#3498db"></span>横向预应力筋(悬浇段顶板内,横桥向 X)</div><divclass="legend"><spanclass="swatch"style="background:#27ae60"></span>竖向预应力筋(悬浇段三道腹板内,竖向 Y)</div><divclass="legend"><spanclass="swatch"style="background:#8f6fc7"></span>合拢段 2m×3处(边跨×2 / 中跨×1,最后浇筑)</div><divclass="legend"><spanclass="swatch"style="background:#e0453a;opacity:.35"></span>塔肢 / 下横梁 / 过渡墩投影 —— 禁布桩区</div><h3style="margin-top:12px">显示控制</h3><labelclass="ctrl"><inputtype="checkbox"id="chk-rotate"checked/>自动旋转</label><labelclass="ctrl"><inputtype="checkbox"id="chk-cables"checked/>斜拉索</label><labelclass="ctrl"><inputtype="checkbox"id="chk-cant"checked/>挂篮</label><labelclass="ctrl"><inputtype="checkbox"id="chk-labels"checked/>尺寸与文字标注</label><labelclass="ctrl"><inputtype="checkbox"id="chk-nogo"checked/>禁布桩区高亮</label><labelclass="ctrl"><inputtype="checkbox"id="chk-seg"checked/>悬浇段 / 合拢段</label><labelclass="ctrl"><inputtype="checkbox"id="chk-seg-long"checked/>纵向预应力筋(红)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-seg-trans"checked/>横向预应力筋(蓝)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-seg-vert"checked/>竖向预应力筋(绿)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-tower"/>塔柱半透明(透视后方支架)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-brace"checked/>平联 / 剪刀撑(支撑体系)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-frame"checked/>索塔劲性骨架(塔肢内桁架,自动透视塔柱)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-joint"checked/>节段分缝(节点板+螺栓)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-crane"checked/>塔吊(附壁式 ×2)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-lift"checked/>施工电梯(附壁 ×2)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-pump"checked/>混凝土泵管</label><labelclass="ctrl"><inputtype="checkbox"id="chk-form"checked/>液压爬模(索塔施工)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-cablecrane"checked/>塔顶缆索吊机(跨峡谷吊装)</label><labelclass="ctrl"><inputtype="checkbox"id="chk-plant"checked/>混凝土拌合站 / 泵站(运距3km)</label><divclass="views"><buttondata-v="整体">整体</button><buttondata-v="正面">正面</button><buttondata-v="侧面">侧面</button><buttondata-v="俯视">俯视</button><buttondata-v="近景">0号块近景</button><buttondata-v="边跨近景">边跨近景</button><buttondata-v="边跨合拢">边跨合拢</button><buttondata-v="中跨合拢">中跨合拢</button><buttondata-v="塔2近景">塔2近景</button><buttondata-v="塔吊近景">塔吊近景</button><buttondata-v="缆索吊近景">缆索吊近景</button><buttondata-v="拌合站近景">拌合站近景</button><buttondata-v="横断面">横断面剖切</button></div><divclass="note"><b>全桥施工布置(塔柱外置型):</b>① 两塔对称布置,塔肢中心距21m、宽3.5m,塔肢外侧与桥边齐平;每塔 0号块 20m(1200m³为全桥两塔总量 → 单塔600m³≈1560t,4排×5根Φ600钢管桩,收进塔肢内侧±5.5m,中部下横梁直承、两侧悬出段由桩承,避开塔肢/下横梁投影);② 两处边跨现浇段各13m(835m³为两处总量 → 单侧417.5m³≈1086t,3排×5根桩,一端搭过渡墩分担约1/4);③ 支撑体系:40m 高支架设 5 层平联(横撑,y=1扫地杆/11/21/31/36,约每10m一道,Φ160×5)+ 四周最外立面 X 形剪刀撑(斜撑,Φ140×5),保证整体稳定与自由长度 λ<60;④ 索塔劲性骨架(赤陶色,塔肢内):140m 高塔施工"骨架先行"——每肢 8 根立柱(四角 L125×10+边中 L100×10)+平联(L75×8)+层间X形剪刀撑,供钢筋绑扎与斜拉索锚管(±5mm)定位依附;**6m节段分缝**处设节点板(360×500×10,灰蓝)+M20×8高强螺栓(银白),节段间螺栓接长随爬模逐节上升;**上塔柱锚固区(95~140m)骨架加密**(亮橙):平联由10m/道加密为5m/道、剪刀撑同步加密,保证索锚管密集区的定位刚度(双塔骨架用钢量约185t);⑤ 悬浇段 4组×16段×6m:**单箱双室三向预应力混凝土**——顶板24.5m/底板21.4m、三道腹板(边±10.5m=索面=塔肢中心+中0m)分双室;**三向预应力**=纵向(红,顶板9+底板7+附加2束/段,抗顺桥向弯矩)+横向(蓝,顶板内@1m,抗横向弯矩)+竖向(绿,腹板内@0.6m,抗剪防斜裂缝),逐段悬浇逐段张拉;挂篮对称悬浇(10天/段,半透明=待施工);⑥ 合拢段 3处各2m(两处边跨 + 一处中跨),劲性骨架锁定 + 水箱配重 + 凌晨低温浇筑,先边跨后中跨;⑦ <b>施工措施设备(V12新增)</b>:<b>附壁式塔吊</b>×2(每塔1台,H≈150m,位于桥面右侧外侧 X=+15,塔身格构标准节 + 附墙杆每20m锚固于塔柱 + 起重臂 L=30m 朝主跨 + 平衡臂配重,负责劲性骨架/钢筋/模板/索鞍吊装);<b>施工电梯</b>×2(附壁于塔柱外侧,双导轨架 + 吊笼上下,供人员/小料运输至塔顶,140m 一次到顶);<b>混凝土泵管</b>(塔柱附壁竖管 Φ125 每10m法兰 + 梁面水平管至挂篮浇筑区,分别供应索塔与主梁 C55 混凝土);<b>液压爬模</b>(紧贴塔肢外圈 4 面板 + 顶部操作平台,随节段爬升,与劲性骨架"骨架先行"配套,浇筑→爬升→再浇筑循环至塔顶);⑧ <b>塔顶缆索吊机(V13新增)</b>:本桥跨越<b>无水山区大峡谷</b>,不设栈桥/水上钻孔平台;索塔与两岸桥台间以<b>塔顶缆索吊机</b>作为主吊运手段——两塔顶间张拉<b>主索(承重索)</b>(跨中垂度 f≈L/12≈18m),上设<b>起重小车(跑车)</b>沿索横移,吊钩下放至桥面/基坑吊装劲性骨架、钢筋笼、模板、索导管等;塔顶设<b>索鞍桁架</b>,主索两端经背索锚固于两岸<b>地锚</b>;⑨ <b>混凝土拌合站与泵站(V13新增)</b>:项目全桥混凝土采用<b>泵送施工工艺</b>,平均运距 <b>3km</b>——峡谷两岸各设<b>拌合站</b>(HZS120 双机搅拌楼 + 粉料筒仓×4 + 骨料仓 + 配料皮带机)与<b>泵站</b>(HBT90 拖泵×2),混凝土自拌合楼经地面<b>泵送管线</b>沿便道输送 3km 至桥位,接塔柱附壁竖管与梁面水平管泵送至索塔与挂篮浇筑点。</div></div><divid="xsect"><divclass="xs-head">塔中心横断面 · 边腹板 = 索面 = 塔肢 对位关系<spanclass="xs-close"id="xs-close"title="关闭剖切">✕</span></div><svgviewBox="0 0 300 160"xmlns="http://www.w3.org/2000/svg"><!-- 顶板 24.5m --><rectx="27.5"y="68"width="245"height="4"fill="#e8913a"/><!-- 底板(箱底 21m,边腹板±10.5m) --><rectx="45"y="104"width="210"height="4"fill="#e8913a"/><!-- 三道腹板:-10.5m / 0m / +10.5m --><rectx="43.5"y="68"width="3"height="40"fill="#b06a1f"/><rectx="148.5"y="68"width="3"height="40"fill="#b06a1f"/><rectx="253.5"y="68"width="3"height="40"fill="#b06a1f"/><!-- 塔肢(中心±10.5m 宽3.5m,外侧到桥边±12.25m,塔梁固结嵌入主梁) --><rectx="27.5"y="8"width="35"height="100"fill="#4a5f7a"opacity="0.88"/><rectx="237.5"y="8"width="35"height="100"fill="#4a5f7a"opacity="0.88"/><!-- 索面竖虚线(从塔顶到梁面锚点,与边腹板/塔肢同轴) --><linex1="45"y1="8"x2="45"y2="68"stroke="#9aa4b0"stroke-width="1.5"stroke-dasharray="4,3"/><linex1="255"y1="8"x2="255"y2="68"stroke="#9aa4b0"stroke-width="1.5"stroke-dasharray="4,3"/><circlecx="45"cy="68"r="3"fill="#5c3d96"/><circlecx="255"cy="68"r="3"fill="#5c3d96"/><!-- 钢管桩:收进塔肢内侧 ±5.5m --><circlecx="95"cy="122"r="4"fill="#e0453a"/><circlecx="205"cy="122"r="4"fill="#e0453a"/><!-- 桥宽尺寸线 24.5m --><linex1="27.5"y1="54"x2="272.5"y2="54"stroke="#44576a"stroke-width="1"/><linex1="27.5"y1="50"x2="27.5"y2="58"stroke="#44576a"stroke-width="1"/><linex1="272.5"y1="50"x2="272.5"y2="58"stroke="#44576a"stroke-width="1"/><textx="150"y="48"text-anchor="middle"font-size="11"fill="#33475e">24.5m 桥宽</text><!-- 索面间距 21m --><linex1="45"y1="116"x2="255"y2="116"stroke="#44576a"stroke-width="1"/><linex1="45"y1="112"x2="45"y2="120"stroke="#44576a"stroke-width="1"/><linex1="255"y1="112"x2="255"y2="120"stroke="#44576a"stroke-width="1"/><textx="150"y="130"text-anchor="middle"font-size="11"fill="#33475e">21m 索面间距 = 塔肢中心距 = 边腹板间距</text><!-- 翼缘悬挑 1.75m(在塔肢上方,端部与桥边/塔肢外侧齐平) --><textx="36"y="92"text-anchor="middle"font-size="9.5"fill="#7a5a10">悬挑1.75m</text><textx="264"y="92"text-anchor="middle"font-size="9.5"fill="#7a5a10">悬挑1.75m</text><!-- 塔肢标注 --><textx="45"y="32"text-anchor="middle"font-size="9.5"fill="#dfe7f0">塔肢</text><textx="45"y="44"text-anchor="middle"font-size="9.5"fill="#dfe7f0">3.5m</text><textx="255"y="32"text-anchor="middle"font-size="9.5"fill="#dfe7f0">塔肢</text><!-- 索面标注 --><textx="55"y="24"font-size="9.5"fill="#6b7c8e">索面</text><textx="245"y="24"text-anchor="end"font-size="9.5"fill="#6b7c8e">索面</text><!-- 塔梁固结说明 --><textx="150"y="84"text-anchor="middle"font-size="10"fill="#44576a">塔梁固结 · 塔肢嵌入主梁 · 翼缘在塔肢上方</text><!-- 钢管桩说明 --><textx="150"y="146"text-anchor="middle"font-size="10"fill="#c0392b">钢管桩:横桥向5根/排(间距2.75m),收进两塔肢内侧(±5.5m),避开塔肢投影</text></svg><divclass="xs-foot">双索面斜拉桥铁律:斜拉索从塔肢出发,必须锚在能传力的主梁骨架上 → 索面锚固点、边腹板、塔肢中心三者同轴(±10.5m)。塔柱外置型:塔肢中心距21m、宽3.5m,塔肢外侧与桥边齐平(±12.25m),翼缘悬挑仅1.75m且全部在塔肢上方,与照片所示一致。</div></div><divid="tip">🖱 左键拖拽旋转 · 滚轮缩放 · 右键平移</div><divid="load-error">3D 引擎加载失败,请检查网络后刷新页面(需访问 jsdelivr / unpkg CDN)。</div><script>(function(){var CDN = [['https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js','https://unpkg.com/three@0.128.0/build/three.min.js','https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js'],['https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js','https://unpkg.com/three@0.128.0/examples/js/controls/OrbitControls.js']];function loadScript(url){return new Promise(function(res, rej){var s = document.createElement('script');s.src = url; s.onload = res; s.onerror = function(){ s.remove(); rej(new Error(url)); };document.head.appendChild(s);});}async function loadSeq(list){var err;for (var i = 0; i < list.length; i++){try { await loadScript(list[i]); return; } catch(e){ err = e; }}throw err;}async function boot(){try {await loadSeq(CDN[0]);await loadSeq(CDN[1]);init();} catch(e){document.getElementById('load-error').style.display = 'block';}}var scene, camera, renderer, controls;var groups = {};function init(){scene = new THREE.Scene();scene.background = new THREE.Color(0xeef1f5);scene.fog = new THREE.Fog(0xeef1f5, 700, 1700);camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 3000);camera.position.set(280, 190, 450);renderer = new THREE.WebGLRenderer({ antialias:true });renderer.localClippingEnabled = true;renderer.setPixelRatio(Math.min(devicePixelRatio, 2));renderer.setSize(innerWidth, innerHeight);document.getElementById('container').appendChild(renderer.domElement);controls = new THREE.OrbitControls(camera, renderer.domElement);controls.target.set(0, 55, 107);controls.enableDamping = true;controls.dampingFactor = 0.08;controls.autoRotate = true;controls.autoRotateSpeed = 0.9;controls.minDistance = 18;controls.maxDistance = 900;controls.maxPolarAngle = Math.PI * 0.93;addLights();buildGround();buildNoGoZone();buildTower(0); // 塔1(主跨左端,Z=0)buildTower(214); // 塔2(主跨右端,Z=214)buildPier(-121); // 塔1边跨过渡墩buildPier(335); // 塔2边跨过渡墩buildGirder(0); // 塔1 0号块buildGirder(214); // 塔2 0号块buildSideGirder(-114.5, -121, -108); // 塔1边跨现浇段buildSideGirder(328.5, 322, 335); // 塔2边跨现浇段buildSegments();buildClosures();buildPiles();buildBracing();buildBentley();buildCantilever();buildCrane(0, 1); // 塔1 塔吊(起重臂朝主跨 Z+)buildCrane(214, -1); // 塔2 塔吊(起重臂朝主跨 Z-)buildLift(0); // 塔1 施工电梯buildLift(214); // 塔2 施工电梯buildPump(0, 1); // 塔1 混凝土泵管buildPump(214, -1); // 塔2 混凝土泵管buildForm(-10.5, 0); // 塔1 左肢液压爬模(施工至 y=56~62)buildForm(10.5, 214); // 塔2 右肢液压爬模buildCableCrane(); // 塔顶缆索吊机(两塔顶间主索 + 起重小车)buildPlant(); // 混凝土拌合站 + 泵站(左岸场站,运距≈3km)buildCables();buildLabels();bindUI();animate();window.addEventListener('resize', function(){camera.aspect = innerWidth / innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth, innerHeight);});}function addLights(){scene.add(new THREE.HemisphereLight(0xffffff, 0xbfc9d4, 0.85));var d1 = new THREE.DirectionalLight(0xffffff, 0.9);d1.position.set(120, 220, 90);scene.add(d1);var d2 = new THREE.DirectionalLight(0xffffff, 0.35);d2.position.set(-90, 70, -130);scene.add(d2);}function buildGround(){var g = new THREE.GridHelper(900, 90, 0x8fa0b3, 0xc7d0da);g.position.y = 0;scene.add(g);var plane = new THREE.Mesh(new THREE.PlaneGeometry(1400, 1400),new THREE.MeshBasicMaterial({ color:0xe2e7ec, transparent:true, opacity:0.5 }));plane.rotation.x = -Math.PI / 2;plane.position.y = -0.05;scene.add(plane);// 峡谷山体(示意)[[-170,-70,95,60],[165,-80,85,50],[-150,130,75,42],[180,140,100,55]].forEach(function(h){var c = new THREE.Mesh(new THREE.ConeGeometry(h[2], h[3], 8),new THREE.MeshLambertMaterial({ color:0xa8c9a0, transparent:true, opacity:0.6 }));c.position.set(h[0], h[3] / 2 - 0.3, h[1]);scene.add(c);});}function buildNoGoZone(){groups.nogo = new THREE.Group();var mat = new THREE.MeshBasicMaterial({ color:0xe0453a, transparent:true, opacity:0.32, depthWrite:false });function zone(x, w, z, d){var m = new THREE.Mesh(new THREE.PlaneGeometry(w, d), mat);m.rotation.x = -Math.PI / 2;m.position.set(x, 0.16, z);groups.nogo.add(m);// 红色虚线框var pts = [new THREE.Vector3(x - w/2, 0.2, z - d/2),new THREE.Vector3(x + w/2, 0.2, z - d/2),new THREE.Vector3(x + w/2, 0.2, z + d/2),new THREE.Vector3(x - w/2, 0.2, z + d/2)];pts.push(pts[0].clone());var ln = new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts),new THREE.LineBasicMaterial({ color:0xe0453a }));groups.nogo.add(ln);}// 塔1 塔肢投影(中心距21m,宽3.5m,覆盖±8.75~±12.25m,桥边±12.25m)zone(-10.5, 3.5, 0, 3.5);zone( 10.5, 3.5, 0, 3.5);// 塔2 塔肢投影zone(-10.5, 3.5, 214, 3.5);zone( 10.5, 3.5, 214, 3.5);var mat2 = new THREE.MeshBasicMaterial({ color:0xf2a53d, transparent:true, opacity:0.28, depthWrite:false });// 塔1 下横梁投影(宽21m)var m2 = new THREE.Mesh(new THREE.PlaneGeometry(21, 3.5), mat2);m2.rotation.x = -Math.PI / 2;m2.position.set(0, 0.12, 0);groups.nogo.add(m2);// 塔2 下横梁投影var m2b = m2.clone();m2b.position.z = 214;groups.nogo.add(m2b);// 塔1 过渡墩投影(Z=-122.7~-119.3)var mat3 = new THREE.MeshBasicMaterial({ color:0xe0453a, transparent:true, opacity:0.3, depthWrite:false });var m3 = new THREE.Mesh(new THREE.PlaneGeometry(6, 3.4), mat3);m3.rotation.x = -Math.PI / 2;m3.position.set(0, 0.16, -121);groups.nogo.add(m3);var pts3 = [new THREE.Vector3(-3, 0.2, -122.7),new THREE.Vector3( 3, 0.2, -122.7),new THREE.Vector3( 3, 0.2, -119.3),new THREE.Vector3(-3, 0.2, -119.3),new THREE.Vector3(-3, 0.2, -122.7)];groups.nogo.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts3),new THREE.LineBasicMaterial({ color:0xe0453a })));// 塔2 过渡墩投影(Z=+333.3~+336.7)var m4 = m3.clone();m4.position.z = 335;groups.nogo.add(m4);var pts4 = [new THREE.Vector3(-3, 0.2, 333.3),new THREE.Vector3( 3, 0.2, 333.3),new THREE.Vector3( 3, 0.2, 336.7),new THREE.Vector3(-3, 0.2, 336.7),new THREE.Vector3(-3, 0.2, 333.3)];groups.nogo.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(pts4),new THREE.LineBasicMaterial({ color:0xe0453a })));scene.add(groups.nogo);}function buildTower(z){groups.tower = new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0x4a5f7a, side:THREE.DoubleSide });// 塔肢:宽3.5m(覆盖±8.75~±12.25m),中心距21m(±10.5m),桥边±12.25mvar pier = new THREE.Mesh(new THREE.BoxGeometry(3.5, 140, 3.5), mat);pier.position.set(-10.5, 70, z);var pier2 = pier.clone();pier2.position.x = 10.5;groups.tower.add(pier, pier2);// 下横梁(宽21m,顶面与梁底齐平,Y=35~40)var xb = new THREE.Mesh(new THREE.BoxGeometry(21, 5, 3.5), mat);xb.position.set(0, 37.5, z);groups.tower.add(xb);// 上横梁var ub = new THREE.Mesh(new THREE.BoxGeometry(17, 4, 3.2), mat);ub.position.set(0, 94, z);groups.tower.add(ub);// 塔顶索锚固区var an = new THREE.Mesh(new THREE.BoxGeometry(3.1, 6, 3.2), mat);an.position.set(-10.5, 137, z);var an2 = an.clone();an2.position.x = 10.5;groups.tower.add(an, an2);// 承台var cf = new THREE.Mesh(new THREE.BoxGeometry(11, 4, 8), new THREE.MeshPhongMaterial({ color:0x6b7684 }));cf.position.set(-10.5, 2, z);var cf2 = cf.clone();cf2.position.x = 10.5;groups.tower.add(cf, cf2);scene.add(groups.tower);buildSteelFrame(z); // 塔柱内劲性骨架(骨架先行,供钢筋/索锚管依附)}function buildSteelFrame(z){// 索塔劲性骨架:塔肢空心箱形(壁厚0.7m示意),内设角钢空间桁架// 立柱 8根/肢:四角 L125×10 + 边中 L100×10(距截面中心±1.35m,位于壁厚内)// V10细化:① 6m节段分缝处节点板+M20螺栓(独立组 frameJoints,可单独开关)// ② 上塔柱锚固区(95~140m)骨架加密:平联10m/道→5m/道、剪刀撑随之加密,亮橙高亮groups.frame = groups.frame || new THREE.Group(); // 两塔共用同一组,开关一次控制全部groups.frameJoints = groups.frameJoints || new THREE.Group();var matV = new THREE.MeshPhongMaterial({ color:0xc96a2e, emissive:0x40200a }); // 立柱 赤陶橙var matH = new THREE.MeshPhongMaterial({ color:0xb85a20, emissive:0x301705 }); // 平联var matD = new THREE.MeshPhongMaterial({ color:0xa04a18, emissive:0x2a1404 }); // 剪刀撑var matH2 = new THREE.MeshPhongMaterial({ color:0xf0941e, emissive:0x7a3a08 }); // 锚固区平联(加密·亮橙)var matD2 = new THREE.MeshPhongMaterial({ color:0xe07b1f, emissive:0x6a3006 }); // 锚固区剪刀撑var matPlate = new THREE.MeshPhongMaterial({ color:0x5d7186, emissive:0x232c38 }); // 节点板 灰蓝var matBolt = new THREE.MeshPhongMaterial({ color:0xe6ecf2, emissive:0x808a94 }); // 螺栓 银白function bar(x1,y1,z1, x2,y2,z2, r, mat){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), mat);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.frame.add(m);}// 6m 节段分缝处的节点板(360×500×10示意) + M20×8 高强螺栓(示意4颗)function joint(x, y, z){var pl = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.5, 0.36), matPlate);pl.position.set(x, y, z);groups.frameJoints.add(pl);var bg = new THREE.CylinderGeometry(0.035, 0.035, 0.18, 6);[[-0.11, -0.16], [0.11, -0.16], [-0.11, 0.16], [0.11, 0.16]].forEach(function(b){var bt = new THREE.Mesh(bg, matBolt);bt.position.set(x, y + b[1], z + b[0]);bt.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(1,0,0));groups.frameJoints.add(bt);});}// 8 根立柱位置(相对塔肢中心 ±1.35m):四角 + 四边中var cols = [[-1.35,-1.35],[1.35,-1.35],[-1.35,1.35],[1.35,1.35],[0,-1.35],[0,1.35],[-1.35,0],[1.35,0]];// 6m 节段划分(承台顶 y=4 → 塔顶140:4/10/16/…/136/140,共23段),分缝节点 y=10,16,…,136,140var segH = [], nodeY = [];for(var y=4; y<140; y+=6) segH.push(y);segH.push(140);for(var y=10; y<=136; y+=6) nodeY.push(y);nodeY.push(140);[-10.5, 10.5].forEach(function(ox){cols.forEach(function(c){for(var k=0;k<segH.length-1;k++){bar(ox+c[0], segH[k], z+c[1], ox+c[0], segH[k+1], z+c[1], 0.13, matV);}nodeY.forEach(function(ny){joint(ox+c[0], ny, z+c[1]);});});});// 平联:普通段每10m一道(y=5~95,10层);锚固区每5m一道(y=100~140,9层·亮橙)function layer(y, mat){[-10.5, 10.5].forEach(function(ox){bar(ox-1.35,y,z-1.35, ox, y,z-1.35, 0.08, mat);bar(ox, y,z-1.35, ox+1.35,y,z-1.35, 0.08, mat);bar(ox+1.35,y,z-1.35, ox+1.35,y,z, 0.08, mat);bar(ox+1.35,y,z, ox+1.35,y,z+1.35, 0.08, mat);bar(ox+1.35,y,z+1.35, ox, y,z+1.35, 0.08, mat);bar(ox, y,z+1.35, ox-1.35,y,z+1.35, 0.08, mat);bar(ox-1.35,y,z+1.35, ox-1.35,y,z, 0.08, mat);bar(ox-1.35,y,z, ox-1.35,y,z-1.35, 0.08, mat);});}for(var y=5; y<=95; y+=10) layer(y, matH);for(var y=100; y<=140; y+=5) layer(y, matH2);// 剪刀撑:层间 X 形;普通段10m层高,锚固区(95m以上)5m层高·亮橙var lv = [];for(var y=5; y<=95; y+=10) lv.push(y);for(var y=100; y<=140; y+=5) lv.push(y);for(var k=0;k<lv.length-1;k++){var y1=lv[k], y2=lv[k+1];var mD = (y1 >= 95) ? matD2 : matD;[-10.5, 10.5].forEach(function(ox){// X 向壁(横桥向立面):Z 向 X 形bar(ox-1.35,y1,z-1.35, ox-1.35,y2,z+1.35, 0.06, mD);bar(ox-1.35,y2,z-1.35, ox-1.35,y1,z+1.35, 0.06, mD);bar(ox+1.35,y1,z-1.35, ox+1.35,y2,z+1.35, 0.06, mD);bar(ox+1.35,y2,z-1.35, ox+1.35,y1,z+1.35, 0.06, mD);// Z 向壁(顺桥向立面):X 向 X 形bar(ox-1.35,y1,z-1.35, ox+1.35,y2,z-1.35, 0.06, mD);bar(ox-1.35,y2,z-1.35, ox+1.35,y1,z-1.35, 0.06, mD);bar(ox-1.35,y1,z+1.35, ox+1.35,y2,z+1.35, 0.06, mD);bar(ox-1.35,y2,z+1.35, ox+1.35,y1,z+1.35, 0.06, mD);});}scene.add(groups.frame);scene.add(groups.frameJoints);}function buildPier(z){// 过渡墩:边跨现浇段端部支点,墩帽顶面与梁底齐平var mat = new THREE.MeshPhongMaterial({ color:0x7d8a99 });var shaft = new THREE.Mesh(new THREE.BoxGeometry(5, 38, 3), mat);shaft.position.set(0, 19, z);groups.tower.add(shaft);var cap = new THREE.Mesh(new THREE.BoxGeometry(8, 2, 3.5), mat);cap.position.set(0, 39, z);groups.tower.add(cap);}function buildGirder(z){groups.girder = new THREE.Group();var panelMat = new THREE.MeshPhongMaterial({ color:0xe8913a, transparent:true, opacity:0.5, depthWrite:false, side:THREE.DoubleSide });var top = new THREE.Mesh(new THREE.BoxGeometry(24.5, 0.5, 20), panelMat);top.position.set(0, 42.75, z);var bot = top.clone();bot.position.y = 40.25;groups.girder.add(top, bot);// 三道腹板(单箱双室:中腹板0m,边腹板±10.5m = 索面锚固 = 塔肢中心)var webMat = new THREE.MeshPhongMaterial({ color:0xb06a1f, transparent:true, opacity:0.85, side:THREE.DoubleSide });[-10.5, 0, 10.5].forEach(function(x){var w = new THREE.Mesh(new THREE.BoxGeometry(0.4, 3.0, 20), webMat);w.position.set(x, 41.5, z);groups.girder.add(w);});// 端部封板(半透明)var endMat = new THREE.MeshPhongMaterial({ color:0xe8913a, transparent:true, opacity:0.3, side:THREE.DoubleSide, depthWrite:false });var e1 = new THREE.Mesh(new THREE.PlaneGeometry(24.5, 3), endMat);e1.position.set(0, 41.5, z - 10);var e2 = e1.clone();e2.position.z = z + 10;groups.girder.add(e1, e2);// 轮廓线框var edges = new THREE.EdgesGeometry(new THREE.BoxGeometry(24.5, 3, 20));var line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color:0x9a6418 }));line.position.y = 41.5;line.position.z = z;groups.girder.add(line);scene.add(groups.girder);}function buildSideGirder(zc, zLo, zHi){// 边跨现浇段:13m × 24.5m,梁底 Y=40groups.side = new THREE.Group();var panelMat = new THREE.MeshPhongMaterial({ color:0xe8913a, transparent:true, opacity:0.5, depthWrite:false, side:THREE.DoubleSide });var top = new THREE.Mesh(new THREE.BoxGeometry(24.5, 0.5, 13), panelMat);top.position.set(0, 42.75, zc);var bot = top.clone();bot.position.y = 40.25;groups.side.add(top, bot);var webMat = new THREE.MeshPhongMaterial({ color:0xb06a1f, transparent:true, opacity:0.85, side:THREE.DoubleSide });[-10.5, 0, 10.5].forEach(function(x){var w = new THREE.Mesh(new THREE.BoxGeometry(0.4, 3.0, 13), webMat);w.position.set(x, 41.5, zc);groups.side.add(w);});var endMat = new THREE.MeshPhongMaterial({ color:0xe8913a, transparent:true, opacity:0.3, side:THREE.DoubleSide, depthWrite:false });var e1 = new THREE.Mesh(new THREE.PlaneGeometry(24.5, 3), endMat);e1.position.set(0, 41.5, zLo);var e2 = e1.clone();e2.position.z = zHi;groups.side.add(e1, e2);var edges = new THREE.EdgesGeometry(new THREE.BoxGeometry(24.5, 3, 13));var line = new THREE.LineSegments(edges, new THREE.LineBasicMaterial({ color:0x9a6418 }));line.position.y = 41.5;line.position.z = zc;groups.side.add(line);scene.add(groups.side);}function buildSegments(){// 悬浇段 64 段×6m:结构形式 = 单箱双室三向预应力混凝土(与项目背景一致)// 梁底 Y=40、梁顶 Y=43(梁高 3.0m);蓝色半透明 = 待施工状态// 截面:顶板 24.5m×0.28、底板 21.4m×0.30、边腹板±10.5m+中腹板 0m(厚0.40)→ 双室// 三向预应力:纵向(红,顶/底板内)+横向(蓝,顶板内)+竖向(绿,腹板内)groups.seg = new THREE.Group();groups.segLong = new THREE.Group();groups.segTrans = new THREE.Group();groups.segVert = new THREE.Group();var D = {segLen: 6,topY: 43, botY: 40, // 梁顶 / 梁底topBotY: 43 - 0.28, // 顶板底 42.72botTopY: 40 + 0.30, // 底板顶 40.30edge: 12.25, botEdge: 10.7, // 顶板半宽 / 底板半宽webC: 10.5, webT: 0.4 // 边腹板中心 / 腹板厚};var cMat = new THREE.MeshPhongMaterial({ color:0x6fa8dc, transparent:true, opacity:0.30, depthWrite:false, side:THREE.DoubleSide });var wMat = new THREE.MeshPhongMaterial({ color:0x4a8fc4, transparent:true, opacity:0.45, depthWrite:false, side:THREE.DoubleSide });var eMat = new THREE.LineBasicMaterial({ color:0x3f6ea5, transparent:true, opacity:0.8 });var lMat = new THREE.MeshPhongMaterial({ color:0xe74c3c, shininess:60 }); // 纵向预应力 红var tMat = new THREE.MeshPhongMaterial({ color:0x3498db, shininess:60 }); // 横向预应力 蓝var vMat = new THREE.MeshPhongMaterial({ color:0x27ae60, shininess:60 }); // 竖向预应力 绿function section(z0){// 单箱双室截面(XY 平面轮廓,沿 Z 挤出 6m)var s = new THREE.Shape();s.moveTo(-D.edge, D.topY);s.lineTo( D.edge, D.topY);s.lineTo( D.edge, D.topBotY);s.lineTo( D.botEdge, D.topBotY);s.lineTo( D.botEdge, D.botY);s.lineTo(-D.botEdge, D.botY);s.lineTo(-D.botEdge, D.topBotY);s.lineTo(-D.edge, D.topBotY);s.closePath();var innerL = D.botEdge - D.webT; // 10.3(底板内缘)var midL = D.webC - D.webT/2; // 0.2(中腹板半厚)var h1 = new THREE.Path(); // 左室h1.moveTo(-innerL, D.botTopY);h1.lineTo(-midL, D.botTopY);h1.lineTo(-midL, D.topBotY);h1.lineTo(-innerL, D.topBotY);h1.closePath();s.holes.push(h1);var h2 = new THREE.Path(); // 右室h2.moveTo(midL, D.botTopY);h2.lineTo(innerL, D.botTopY);h2.lineTo(innerL, D.topBotY);h2.lineTo(midL, D.topBotY);h2.closePath();s.holes.push(h2);var g = new THREE.ExtrudeGeometry(s, { depth:D.segLen, bevelEnabled:false, steps:1 });g.translate(0, 0, z0 - D.segLen/2);groups.seg.add(new THREE.Mesh(g, cMat));// 三道腹板深色覆盖(视觉区分)[-D.webC, 0, D.webC].forEach(function(x){var w = new THREE.Mesh(new THREE.BoxGeometry(D.webT, D.topBotY - D.botTopY, D.segLen), wMat);w.position.set(x, (D.topBotY + D.botTopY)/2, z0);groups.seg.add(w);});// 两端截面轮廓线(外轮廓 + 双室内框)[z0 - D.segLen/2, z0 + D.segLen/2].forEach(function(z){var out = [[-D.edge,D.topY],[D.edge,D.topY],[D.edge,D.topBotY],[D.botEdge,D.topBotY],[D.botEdge,D.botY],[-D.botEdge,D.botY],[-D.botEdge,D.topBotY],[-D.edge,D.topBotY],[-D.edge,D.topY]].map(function(p){ return new THREE.Vector3(p[0], p[1], z); });groups.seg.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(out), eMat));var in1 = [[-innerL,D.botTopY],[-midL,D.botTopY],[-midL,D.topBotY],[-innerL,D.topBotY],[-innerL,D.botTopY]].map(function(p){ return new THREE.Vector3(p[0], p[1], z); });groups.seg.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(in1), eMat));var in2 = [[midL,D.botTopY],[innerL,D.botTopY],[innerL,D.topBotY],[midL,D.topBotY],[midL,D.botTopY]].map(function(p){ return new THREE.Vector3(p[0], p[1], z); });groups.seg.add(new THREE.Line(new THREE.BufferGeometry().setFromPoints(in2), eMat));});}function tendons(z0){// 纵向预应力(红,沿 Z):顶板 9 根 + 底板 7 根 + 顶板近边腹板 2 根 = 18 根/段var len = D.segLen + 0.6, r = 0.05;[-10.5,-8,-5.5,-3,0,3,5.5,8,10.5].forEach(function(x){var c = new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,8), lMat);c.rotation.x = Math.PI/2;c.position.set(x, D.topY - 0.14, z0);groups.segLong.add(c);});[-8,-5.5,-3,0,3,5.5,8].forEach(function(x){var c = new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,8), lMat);c.rotation.x = Math.PI/2;c.position.set(x, 40.15, z0);groups.segLong.add(c);});[-10.5,10.5].forEach(function(x){var c = new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,8), lMat);c.rotation.x = Math.PI/2;c.position.set(x, D.topY - 0.20, z0);groups.segLong.add(c);});// 横向预应力(蓝,沿 X):顶板内 6 根,间距 1.0mvar tlen = D.edge*2 - 2.0; // -11.25 ~ +11.25[-2.5,-1.5,-0.5,0.5,1.5,2.5].forEach(function(z){var c = new THREE.Mesh(new THREE.CylinderGeometry(0.035,0.035,tlen,8), tMat);c.rotation.z = Math.PI/2;c.position.set(0, D.topY - 0.14, z0 + z);groups.segTrans.add(c);});// 竖向预应力(绿,沿 Y):三道腹板内,间距 0.6mvar vlen = D.topBotY - D.botTopY - 0.1;[-D.webC, 0, D.webC].forEach(function(x){for (var z = -2.7; z <= 2.7; z += 0.6){var c = new THREE.Mesh(new THREE.CylinderGeometry(0.03,0.03,vlen,6), vMat);c.position.set(x, (D.topBotY + D.botTopY)/2, z0 + z);groups.segVert.add(c);}});}var i, z;// 塔1 边跨 16 段:Z=-10 → -106(中心 -13-6i)for (i = 0; i < 16; i++){ z = -13 - 6*i; section(z); tendons(z); }// 塔1 主跨侧 16 段:Z=+10 → +106(中心 13+6i)for (i = 0; i < 16; i++){ z = 13 + 6*i; section(z); tendons(z); }// 塔2 主跨侧 16 段:Z=+108 → +204(中心 111+6i)for (i = 0; i < 16; i++){ z = 111 + 6*i; section(z); tendons(z); }// 塔2 边跨 16 段:Z=+224 → +320(中心 227+6i)for (i = 0; i < 16; i++){ z = 227 + 6*i; section(z); tendons(z); }scene.add(groups.seg);scene.add(groups.segLong);scene.add(groups.segTrans);scene.add(groups.segVert);}function buildClosures(){// 合拢段 3 处各 2m:塔1边跨 Z=-108~-106、中跨 Z=+106~+108、塔2边跨 Z=+320~+322,紫色高亮groups.closure = new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0x8f6fc7, transparent:true, opacity:0.82, depthWrite:false, side:THREE.DoubleSide });var edge = new THREE.LineBasicMaterial({ color:0x5c3d96 });[-107, 107, 321].forEach(function(zc){var b = new THREE.Mesh(new THREE.BoxGeometry(24.5, 3, 2), mat);b.position.set(0, 41.5, zc);groups.closure.add(b);var e = new THREE.LineSegments(new THREE.EdgesGeometry(b.geometry), edge);e.position.copy(b.position);groups.closure.add(e);});scene.add(groups.closure);}function buildPiles(){groups.piles = new THREE.Group();var geo = new THREE.CylinderGeometry(0.55, 0.55, 38, 14);var mat = new THREE.MeshPhongMaterial({ color:0xe0453a });// 塔1 0号块:4排×5根(单塔600m³≈1560t,验算满足),收进两塔肢内侧(±5.5m)var zs = [-8.5, -4.5, 4.5, 8.5];var xs = [-5.5, -2.75, 0, 2.75, 5.5];zs.forEach(function(z){xs.forEach(function(x){var p = new THREE.Mesh(geo, mat);p.position.set(x, 19, z);groups.piles.add(p);});});// 塔1 边跨现浇段:3排×5根,排距4.5m(Z=-109.5/-114/-118.5),// 无塔肢限制,横向放宽到±8.5m;最靠墩一排距墩投影边约1mvar zs2 = [-109.5, -114, -118.5];var xs2 = [-8.5, -4.25, 0, 4.25, 8.5];zs2.forEach(function(z){xs2.forEach(function(x){var p = new THREE.Mesh(geo, mat);p.position.set(x, 19, z);groups.piles.add(p);});});// 塔2 0号块:镜像塔1(Z=+205.5/+209.5/+218.5/+222.5,中心+214,4排×5根)var zs3 = [205.5, 209.5, 218.5, 222.5];zs3.forEach(function(z){xs.forEach(function(x){var p = new THREE.Mesh(geo, mat);p.position.set(x, 19, z);groups.piles.add(p);});});// 塔2 边跨现浇段:镜像塔1(Z=+323.5/+328/+332.5,过渡墩在+335)var zs4 = [323.5, 328, 332.5];zs4.forEach(function(z){xs2.forEach(function(x){var p = new THREE.Mesh(geo, mat);p.position.set(x, 19, z);groups.piles.add(p);});});scene.add(groups.piles);}function buildBracing(){// 钢管桩支架稳定支撑体系:平联(横撑)+ 剪刀撑(斜撑)// 40m 高支架按“每10m左右一道平联”设置 5 层:y = 1(扫地杆)/11/21/31/36(顶部系杆)// 剪刀撑沿支架四周最外立面设 X 形(横桥向 Z 向立面 + 顺桥向 X 向立面)groups.bracing = new THREE.Group();var matH = new THREE.MeshPhongMaterial({ color:0x8ba3b8 }); // 平联 蓝灰var matD = new THREE.MeshPhongMaterial({ color:0x667f9c }); // 剪刀撑 深蓝灰function brace(x1,y1,z1, x2,y2,z2, r, mat){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), mat);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.bracing.add(m);}function addBracing(zs, xs){var levels = [1, 11, 21, 31, 36];var xMin = Math.min.apply(null,xs), xMax = Math.max.apply(null,xs);var zMin = Math.min.apply(null,zs), zMax = Math.max.apply(null,zs);// 平联:每层 X 向连排 + Z 向分段连列levels.forEach(function(y){zs.forEach(function(z){brace(xMin, y, z, xMax, y, z, 0.10, matH);});xs.forEach(function(x){for(var i=0;i<zs.length-1;i++){brace(x, y, zs[i], x, y, zs[i+1], 0.10, matH);}});});// 剪刀撑:四周最外立面 X 形(每相邻两层平联之间)for(var k=0;k<levels.length-1;k++){var y1=levels[k], y2=levels[k+1];[zMin, zMax].forEach(function(z){for(var i=0;i<xs.length-1;i++){brace(xs[i], y1, z, xs[i+1], y2, z, 0.09, matD);brace(xs[i], y2, z, xs[i+1], y1, z, 0.09, matD);}});[xMin, xMax].forEach(function(x){for(var i=0;i<zs.length-1;i++){brace(x, y1, zs[i], x, y2, zs[i+1], 0.09, matD);brace(x, y2, zs[i], x, y1, zs[i+1], 0.09, matD);}});}}// 塔1 0号块:4排×5根(Z=-8.5/-4.5/4.5/8.5,X=±5.5)addBracing([-8.5, -4.5, 4.5, 8.5], [-5.5, -2.75, 0, 2.75, 5.5]);// 塔1 边跨现浇段:3排×5根(Z=-109.5/-114/-118.5,X=±8.5)addBracing([-109.5, -114, -118.5], [-8.5, -4.25, 0, 4.25, 8.5]);// 塔2 0号块:镜像(中心 Z=+214)addBracing([205.5, 209.5, 218.5, 222.5], [-5.5, -2.75, 0, 2.75, 5.5]);// 塔2 边跨现浇段:镜像(中心 Z=+328.5)addBracing([323.5, 328, 332.5], [-8.5, -4.25, 0, 4.25, 8.5]);scene.add(groups.bracing);}function buildBentley(){groups.bentley = new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0xf2c14e });var mat2 = new THREE.MeshPhongMaterial({ color:0xd9a832 });// 塔1 0号块贝雷梁平台:5列沿 Z(长17,跨4排桩),4排横向分配梁var xs = [-5.5, -2.75, 0, 2.75, 5.5];xs.forEach(function(x){var b = new THREE.Mesh(new THREE.BoxGeometry(1.1, 2, 17), mat);b.position.set(x, 39, 0);groups.bentley.add(b);var e = new THREE.EdgesGeometry(b.geometry);groups.bentley.add(new THREE.LineSegments(e, new THREE.LineBasicMaterial({ color:0x8a6d1c })));});[-8.5, -4.5, 4.5, 8.5].forEach(function(z){var h = new THREE.Mesh(new THREE.BoxGeometry(11, 0.5, 0.5), mat2);h.position.set(0, 39.75, z);groups.bentley.add(h);});// 塔1 边跨现浇段贝雷梁平台:5列沿 Z(长12),3排横向分配梁var xs2 = [-8.5, -4.25, 0, 4.25, 8.5];xs2.forEach(function(x){var b = new THREE.Mesh(new THREE.BoxGeometry(1.1, 2, 12), mat);b.position.set(x, 39, -114);groups.bentley.add(b);var e2 = new THREE.EdgesGeometry(b.geometry);groups.bentley.add(new THREE.LineSegments(e2, new THREE.LineBasicMaterial({ color:0x8a6d1c })));});[-109.5, -114, -118.5].forEach(function(z){var h = new THREE.Mesh(new THREE.BoxGeometry(17, 0.5, 0.5), mat2);h.position.set(0, 39.75, z);groups.bentley.add(h);});// 塔2 0号块贝雷梁平台(镜像,中心 Z=+214)xs.forEach(function(x){var b = new THREE.Mesh(new THREE.BoxGeometry(1.1, 2, 17), mat);b.position.set(x, 39, 214);groups.bentley.add(b);var e3 = new THREE.EdgesGeometry(b.geometry);groups.bentley.add(new THREE.LineSegments(e3, new THREE.LineBasicMaterial({ color:0x8a6d1c })));});[205.5, 209.5, 218.5, 222.5].forEach(function(z){var h = new THREE.Mesh(new THREE.BoxGeometry(11, 0.5, 0.5), mat2);h.position.set(0, 39.75, z);groups.bentley.add(h);});// 塔2 边跨现浇段贝雷梁平台(镜像,中心 Z=+328.5)xs2.forEach(function(x){var b = new THREE.Mesh(new THREE.BoxGeometry(1.1, 2, 12), mat);b.position.set(x, 39, 328.5);groups.bentley.add(b);var e4 = new THREE.EdgesGeometry(b.geometry);groups.bentley.add(new THREE.LineSegments(e4, new THREE.LineBasicMaterial({ color:0x8a6d1c })));});[323.5, 328, 332.5].forEach(function(z){var h = new THREE.Mesh(new THREE.BoxGeometry(17, 0.5, 0.5), mat2);h.position.set(0, 39.75, z);groups.bentley.add(h);});scene.add(groups.bentley);}function buildCantilever(){groups.cant = new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0x3fa06b });var matD = new THREE.MeshPhongMaterial({ color:0x2f7d52 });// z0 = 0号块端部 Z 坐标(挂篮向 sign 方向悬伸)function addCrane(sign, z0){var beam = new THREE.Mesh(new THREE.BoxGeometry(0.8, 0.8, 7), mat);beam.position.set(0, 46.5, z0 + 3.5 * sign);groups.cant.add(beam);[-3, 3].forEach(function(x){var slant = new THREE.Mesh(new THREE.BoxGeometry(0.6, 6, 0.6), mat);slant.position.set(x, 43.5, z0 + 1 * sign);slant.rotation.z = 0.5 * sign;groups.cant.add(slant);});var base = new THREE.Mesh(new THREE.BoxGeometry(7, 0.6, 6), matD);base.position.set(0, 36.8, z0 + 3 * sign);groups.cant.add(base);[-3, 3].forEach(function(x){var rod = new THREE.Mesh(new THREE.CylinderGeometry(0.12, 0.12, 9.5, 6), matD);rod.position.set(x, 42, z0 + 1.5 * sign);groups.cant.add(rod);});}// 塔1:0号块 Z=-10~+10,主跨侧端 +10、边跨侧端 -10addCrane(1, 10);addCrane(-1, -10);// 塔2:0号块 Z=+204~+224,主跨侧端 +204(朝 Z- 方向)、边跨侧端 +224(朝 Z+ 方向)addCrane(-1, 204);addCrane(1, 224);scene.add(groups.cant);}// ================== V12 施工措施设备:塔吊 / 施工电梯 / 混凝土泵管 / 液压爬模 ==================// 塔吊:附壁式(附着于塔柱外侧面),每塔1台,位于桥面右侧外侧 X=+15,塔身 H=150m,起重臂朝主跨侧function buildCrane(towerZ, dir){groups.crane = groups.crane || new THREE.Group();var matM = new THREE.MeshPhongMaterial({ color:0xf0c040, emissive:0x4a3208 }); // 塔身 亮黄var matD = new THREE.MeshPhongMaterial({ color:0xd9a520, emissive:0x3a2806 }); // 深黄(横撑/配重)var matCab = new THREE.MeshPhongMaterial({ color:0x5d7186, emissive:0x232c38 }); // 驾驶室 灰蓝var X = 15, hx = 0.5, hz = 0.8;function bar3(x1,y1,z1, x2,y2,z2, r, mat){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), mat);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.crane.add(m);}// ① 塔身格构(标准节):4 立柱 + 每10m横框 + 每20m层间对角斜撑[[-hx,-hz],[hx,-hz],[-hx,hz],[hx,hz]].forEach(function(c){var col = new THREE.Mesh(new THREE.CylinderGeometry(0.13, 0.13, 148, 6), matM);col.position.set(X+c[0], 74, towerZ+c[1]);groups.crane.add(col);});for(var y=6; y<146; y+=10){bar3(X-hx, y, towerZ-hz, X+hx, y, towerZ-hz, 0.07, matD);bar3(X+hx, y, towerZ-hz, X+hx, y, towerZ+hz, 0.07, matD);bar3(X+hx, y, towerZ+hz, X-hx, y, towerZ+hz, 0.07, matD);bar3(X-hx, y, towerZ+hz, X-hx, y, towerZ-hz, 0.07, matD);if((y-6) % 20 === 0){bar3(X-hx, y, towerZ-hz, X+hx, y+10, towerZ+hz, 0.06, matD);bar3(X+hx, y, towerZ-hz, X-hx, y+10, towerZ+hz, 0.06, matD);bar3(X-hx, y, towerZ+hz, X+hx, y+10, towerZ-hz, 0.06, matD);bar3(X+hx, y, towerZ+hz, X-hx, y+10, towerZ-hz, 0.06, matD);}}// ② 附墙杆(附着于塔柱外侧面 X=12.25,每20m一道 + 斜撑)for(var ay=20; ay<=140; ay+=20){bar3(X, ay, towerZ, 12.25, ay, towerZ, 0.07, matD);bar3(X, ay, towerZ, 12.25, ay+4, towerZ, 0.05, matD);}// ③ 回转台 + 驾驶室var tt = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.7, 1.8), matD);tt.position.set(X, 148.35, towerZ);groups.crane.add(tt);var cab = new THREE.Mesh(new THREE.BoxGeometry(0.9, 0.9, 0.9), matCab);cab.position.set(X+0.62, 149.6, towerZ+0.62);groups.crane.add(cab);// ④ 塔顶(A架):4杆汇聚 + 顶部滑轮 + 顶横梁var topY = 160.5;[[-hx,-hz],[hx,-hz],[-hx,hz],[hx,hz]].forEach(function(c){bar3(X+c[0], 148.7, towerZ+c[1], X, topY, towerZ, 0.08, matM);});var tip = new THREE.Mesh(new THREE.SphereGeometry(0.22, 8, 8), matM);tip.position.set(X, topY, towerZ);groups.crane.add(tip);bar3(X-hx, topY-1.2, towerZ, X+hx, topY-1.2, towerZ, 0.07, matM);// ⑤ 起重臂(朝主跨,L=30m,上弦2+下弦1+竖腹杆桁架)var boomY = 148.1, lowY = 147.2, boomLen = 30;[-0.35, 0.35].forEach(function(dx){var bm = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.06, boomLen, 6), matM);bm.rotation.x = Math.PI/2;bm.position.set(X+dx, boomY, towerZ + dir*(0.8 + boomLen/2));groups.crane.add(bm);});var low = new THREE.Mesh(new THREE.CylinderGeometry(0.05, 0.05, boomLen, 6), matM);low.rotation.x = Math.PI/2;low.position.set(X, lowY, towerZ + dir*(0.8 + boomLen/2));groups.crane.add(low);for(var k=0; k<=6; k++){var zb = towerZ + dir*(0.8 + k*5);bar3(X-0.35, boomY, zb, X, lowY, zb, 0.045, matD);bar3(X+0.35, boomY, zb, X, lowY, zb, 0.045, matD);}// 臂端吊钩bar3(X, lowY, towerZ + dir*(0.8+boomLen), X, lowY-3.2, towerZ + dir*(0.8+boomLen), 0.05, matM);var hook = new THREE.Mesh(new THREE.SphereGeometry(0.28, 8, 8), matD);hook.position.set(X, lowY-3.5, towerZ + dir*(0.8+boomLen));groups.crane.add(hook);// ⑥ 平衡臂(反向 L=11m)+ 配重块var cwY = 147.8, cwEnd = towerZ - dir*(0.8+11);var cw = new THREE.Mesh(new THREE.CylinderGeometry(0.06, 0.06, 11, 6), matM);cw.rotation.x = Math.PI/2;cw.position.set(X, cwY, towerZ - dir*(0.8+5.5));groups.crane.add(cw);[-0.45, 0.45].forEach(function(dx){var w = new THREE.Mesh(new THREE.BoxGeometry(0.7, 1.3, 1.0), matD);w.position.set(X+dx, cwY-0.75, cwEnd);groups.crane.add(w);});bar3(X, topY-2, towerZ, X, cwY, cwEnd, 0.05, matD);// ⑦ 起重臂拉索(塔顶→臂上弦 2/3 处 + 端部)bar3(X, topY-2, towerZ, X-0.35, boomY, towerZ + dir*21, 0.05, matD);bar3(X, topY-2, towerZ, X+0.35, boomY, towerZ + dir*21, 0.05, matD);bar3(X, topY-2, towerZ, X, lowY, towerZ + dir*(0.8+boomLen), 0.05, matD);scene.add(groups.crane);}// 施工电梯(人货梯):附壁于塔柱外侧,双导轨架 + 吊笼 + 附墙 + 天轮function buildLift(towerZ){groups.lift = groups.lift || new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0x4db8a0, emissive:0x123a30 }); // 青绿var matR = new THREE.MeshPhongMaterial({ color:0x3a8f7c, emissive:0x0e2a24 }); // 深青var X = -15, Z = towerZ + 1.6, H = 141;function bar3(x1,y1,z1, x2,y2,z2, r, mat){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), mat);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.lift.add(m);}// 双导轨立柱(沿 X 向间距 0.6m)[X-0.3, X+0.3].forEach(function(rx){var m = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, H, 6), mat);m.position.set(rx, H/2, Z);groups.lift.add(m);});// 横档每4mfor(var y=4; y<H; y+=4){bar3(X-0.3, y, Z, X+0.3, y, Z, 0.045, matR);}// 附墙杆(连至塔柱外侧 X=-12.25,每12m一道)for(var ay=12; ay<=132; ay+=12){bar3(X+0.3, ay, Z, -12.25, ay, Z, 0.06, matR);bar3(X+0.3, ay, Z, -12.25, ay+3, Z, 0.04, matR);}// 吊笼(运行在 y=95 示意)var cage = new THREE.Mesh(new THREE.BoxGeometry(1.15, 2.5, 1.55), mat);cage.position.set(X, 95, Z);groups.lift.add(cage);var ce = new THREE.LineSegments(new THREE.EdgesGeometry(cage.geometry), new THREE.LineBasicMaterial({ color:0x1d5c4c }));ce.position.copy(cage.position);groups.lift.add(ce);// 顶部天轮var wheel = new THREE.Mesh(new THREE.CylinderGeometry(0.35, 0.35, 0.2, 10), matR);wheel.rotation.z = Math.PI/2;wheel.position.set(X, H+0.7, Z);groups.lift.add(wheel);// 底部基础var base = new THREE.Mesh(new THREE.BoxGeometry(1.8, 0.4, 1.8), matR);base.position.set(X, 0.2, Z);groups.lift.add(base);scene.add(groups.lift);}// 混凝土泵管:塔柱附壁竖管(供索塔混凝土)+ 梁面水平管(供主梁挂篮浇筑)function buildPump(towerZ, dir){groups.pump = groups.pump || new THREE.Group();var matP = new THREE.MeshPhongMaterial({ color:0xd43a2f, emissive:0x3a0e0a }); // 红var matF = new THREE.MeshPhongMaterial({ color:0x8a2218, emissive:0x2a0a06 }); // 法兰 深红var X = 13.5, Z = towerZ + 2.3, H = 140;// 竖直主管(附壁于塔柱外侧 X=13.5)var pipe = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, H, 8), matP);pipe.position.set(X, H/2, Z);groups.pump.add(pipe);// 法兰卡箍每10mfor(var y=0; y<=H; y+=10){var f = new THREE.Mesh(new THREE.CylinderGeometry(0.135, 0.135, 0.07, 8), matF);f.position.set(X, y, Z);groups.pump.add(f);}// 底部水平引入段 + 弯头(地面泵站来管)var hp = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, 5, 8), matP);hp.rotation.z = Math.PI/2;hp.position.set(X-2.5, 0.4, Z);groups.pump.add(hp);var elbow = new THREE.Mesh(new THREE.SphereGeometry(0.14, 8, 8), matP);elbow.position.set(X, 0.55, Z);groups.pump.add(elbow);// 梁面水平段(沿 0号块/悬浇段顶面 y=43.2 向主跨延伸,至挂篮浇筑区)var hlen = 24, hz = towerZ + dir*(2.3 + hlen/2);var dp = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, hlen, 8), matP);dp.rotation.x = Math.PI/2;dp.position.set(12.0, 43.2, hz);groups.pump.add(dp);scene.add(groups.pump);}// 液压爬模(索塔施工模板体系):紧贴塔肢外圈 4 面板 + 顶部操作平台 + 液压爬升缸function buildForm(legX, towerZ){groups.form = groups.form || new THREE.Group();var matP = new THREE.MeshPhongMaterial({ color:0xc8a04e, emissive:0x3a2c0e }); // 模板 黄褐var matW = new THREE.MeshPhongMaterial({ color:0x8f9aad, emissive:0x28303c }); // 平台 灰蓝var matH = new THREE.MeshPhongMaterial({ color:0xa8822f, emissive:0x2a2008 }); // 液压缸 深棕var y0 = 56, y1 = 62;// 前后面板(X 向宽 4.4m,塔肢3.5m 外扩 0.9m)[towerZ-1.78, towerZ+1.78].forEach(function(z){var f = new THREE.Mesh(new THREE.BoxGeometry(4.4, 6, 0.14), matP);f.position.set(legX, (y0+y1)/2, z);groups.form.add(f);var fe = new THREE.LineSegments(new THREE.EdgesGeometry(f.geometry), new THREE.LineBasicMaterial({ color:0x5c4a1e }));fe.position.copy(f.position);groups.form.add(fe);});// 左右面板(Z 向宽 3.56m)[legX-1.78, legX+1.78].forEach(function(x){var f = new THREE.Mesh(new THREE.BoxGeometry(0.14, 6, 3.56), matP);f.position.set(x, (y0+y1)/2, towerZ);groups.form.add(f);var fe = new THREE.LineSegments(new THREE.EdgesGeometry(f.geometry), new THREE.LineBasicMaterial({ color:0x5c4a1e }));fe.position.copy(f.position);groups.form.add(fe);});// 顶部操作平台(外挑一圈)var plat = new THREE.Mesh(new THREE.BoxGeometry(6.0, 0.12, 5.0), matW);plat.position.set(legX, y1+0.26, towerZ);groups.form.add(plat);// 平台护栏[[-2.7,-2.3],[2.7,-2.3],[-2.7,2.3],[2.7,2.3]].forEach(function(c){var rail = new THREE.Mesh(new THREE.CylinderGeometry(0.04, 0.04, 1.0, 6), matW);rail.position.set(legX+c[0], y1+0.8, towerZ+c[1]);groups.form.add(rail);});// 液压爬升缸(四角短竖杆)[[-1.9,-1.9],[1.9,-1.9],[-1.9,1.9],[1.9,1.9]].forEach(function(c){var cyl = new THREE.Mesh(new THREE.CylinderGeometry(0.07, 0.07, 5.6, 6), matH);cyl.position.set(legX+c[0], (y0+y1)/2, towerZ+c[1]);groups.form.add(cyl);});scene.add(groups.form);}// ================== V13 施工措施设备:塔顶缆索吊机 / 混凝土拌合站+泵站 ==================// 塔顶缆索吊机:无水山区大峡谷 → 不设栈桥,以塔顶缆索吊为主吊运手段// 两塔顶间张拉主索(跨中垂度 f≈18m),起重小车(跑车)沿索横移吊装;塔顶索鞍桁架;两端背索锚固于地锚function buildCableCrane(){groups.cablecrane = new THREE.Group();var matM = new THREE.MeshPhongMaterial({ color:0xff7f2a, emissive:0x6a2c05 }); // 主索/吊绳 亮橙var matD = new THREE.MeshPhongMaterial({ color:0xd9681e, emissive:0x50240a }); // 深橙(小车/索鞍)var matB = new THREE.MeshPhongMaterial({ color:0x8f6fc7, emissive:0x2e1c4a }); // 背索 紫var matC = new THREE.MeshPhongMaterial({ color:0xe8a63c, emissive:0x4a3208 }); // 吊装构件 金黄function bar3(x1,y1,z1, x2,y2,z2, r, mat){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), mat);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.cablecrane.add(m);}var topY = 141.5; // 索鞍顶高程(塔顶140m 之上)var z1 = 0, z2 = 214, L = z2 - z1, f = 18; // 主索跨中垂度// ① 主索(承重索):两端塔顶高、跨中下垂(抛物线垂度 f=18m),用分段折线模拟(每段约7m)var segs = Math.round(L / 7);for(var i=0; i<segs; i++){var za = z1 + L*i/segs, zb = z1 + L*(i+1)/segs;var ya = topY - 4*f*(za-z1)*(z2-za)/(L*L);var yb = topY - 4*f*(zb-z1)*(z2-zb)/(L*L);bar3(0, ya, za, 0, yb, zb, 0.11, matM);}// ② 塔顶索鞍桁架(横跨两塔肢,X 从 -10.5 到 +10.5,高 y=140~143)[-10.5, 10.5].forEach(function(legX){var sadd = new THREE.Mesh(new THREE.BoxGeometry(1.0, 3.0, 2.4), matD);sadd.position.set(legX, 141.5, z1);groups.cablecrane.add(sadd);var sadd2 = sadd.clone();sadd2.position.z = z2;groups.cablecrane.add(sadd2);// 索鞍支承斜撑(塔肢顶→索鞍底)bar3(legX, 138.5, z1, legX + (legX>0?1:-1)*0.9, 142.2, z1, 0.09, matD);bar3(legX, 138.5, z2, legX + (legX>0?1:-1)*0.9, 142.2, z2, 0.09, matD);});// 横向连接桁架(两索鞍之间,索塔顶部)bar3(-10.5, 141.5, z1, 10.5, 141.5, z1, 0.08, matD);bar3(-10.5, 141.5, z2, 10.5, 141.5, z2, 0.08, matD);bar3(-10.5, 140.6, z1, 10.5, 142.4, z1, 0.06, matD);bar3(10.5, 140.6, z1, -10.5, 142.4, z1, 0.06, matD);bar3(-10.5, 140.6, z2, 10.5, 142.4, z2, 0.06, matD);bar3(10.5, 140.6, z2, -10.5, 142.4, z2, 0.06, matD);// ③ 起重小车(跑车,位于主跨中 Z=107,挂在主索上)var cz = 107, cy = topY - 4*f*(cz-z1)*(z2-cz)/(L*L);var car = new THREE.Mesh(new THREE.BoxGeometry(1.6, 0.7, 2.4), matD);car.position.set(0, cy - 0.35, cz);groups.cablecrane.add(car);// 小车行走轮(两个,骑在主索上)[[-0.55, -0.8], [0.55, -0.8], [-0.55, 0.8], [0.55, 0.8]].forEach(function(w){var wheel = new THREE.Mesh(new THREE.CylinderGeometry(0.32, 0.32, 0.22, 10), matM);wheel.rotation.x = Math.PI/2;wheel.position.set(w[0], cy - 0.62, cz + w[1]);groups.cablecrane.add(wheel);});// 吊绳(小车→吊钩,下放至桥面附近)+吊装构件(钢筋笼示意)bar3(0, cy - 0.7, cz, 0, 38.5, cz, 0.05, matM);var hook = new THREE.Mesh(new THREE.ConeGeometry(0.3, 0.9, 8), matM);hook.rotation.x = Math.PI;hook.position.set(0, 38.2, cz);groups.cablecrane.add(hook);var load = new THREE.Mesh(new THREE.BoxGeometry(2.6, 1.6, 6.0), matC);load.position.set(0, 37.0, cz);groups.cablecrane.add(load);// 钢筋笼外轮廓线var le = new THREE.LineSegments(new THREE.EdgesGeometry(load.geometry), new THREE.LineBasicMaterial({ color:0x7a4a0a }));le.position.copy(load.position);groups.cablecrane.add(le);// ④ 背索(主索两端经塔顶索鞍锚固于两岸地锚)[-121, 335].forEach(function(az){bar3(0, topY, az > 100 ? z2 : z1, 0, 3, az, 0.09, matB);bar3(0, topY, az > 100 ? z2 : z1, -14, 3, az, 0.06, matB);bar3(0, topY, az > 100 ? z2 : z1, 14, 3, az, 0.06, matB);// 地锚块var anc = new THREE.Mesh(new THREE.BoxGeometry(6, 2.4, 4), new THREE.MeshPhongMaterial({ color:0x7d8a99 }));anc.position.set(0, 1.2, az);groups.cablecrane.add(anc);var ac = new THREE.Mesh(new THREE.BoxGeometry(6, 2.4, 4), new THREE.MeshBasicMaterial({ color:0x000000, wireframe:true }));ac.position.set(0, 1.2, az);groups.cablecrane.add(ac);});// ⑤ 牵引索(主索旁的工作索,示意:两塔顶间略平行细线)bar3(-0.8, topY-0.8, z1, -0.8, topY-0.8, z2, 0.04, matD);scene.add(groups.cablecrane);}// 混凝土拌合站 + 泵站:全桥泵送施工,平均运距3km → 峡谷左岸设场站,泵管沿便道接至桥位function buildPlant(){groups.plant = new THREE.Group();var matB = new THREE.MeshPhongMaterial({ color:0x5f8fa8, emissive:0x1c3a4a }); // 搅拌楼主体 青蓝var matS = new THREE.MeshPhongMaterial({ color:0x8a97a5, emissive:0x2e3640 }); // 筒仓 灰蓝var matR = new THREE.MeshPhongMaterial({ color:0xd43a2f, emissive:0x3a0e0a }); // 泵车 红var matG = new THREE.MeshPhongMaterial({ color:0xc8a86a, emissive:0x4a3a1a }); // 骨料 沙黄var matY = new THREE.MeshPhongMaterial({ color:0xf2c14e, emissive:0x5c4408 }); // 皮带机 金黄var matD = new THREE.MeshPhongMaterial({ color:0xd43a2f, emissive:0x3a0e0a }); // 泵送管线 红var PX = -46, PZ = -172; // 左岸场站位置(桥左端 Z=-121 外约 51m)function box(w, h, d, x, y, z, mat){var m = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), mat);m.position.set(x, y, z);groups.plant.add(m);return m;}// ① 搅拌楼(HZS120 双机):4 立柱 + 主体箱体 + 顶部配料斗 + 出料口var MLX = PX, MLZ = PZ + 8;[[-3.2,-2.2],[3.2,-2.2],[-3.2,2.2],[3.2,2.2]].forEach(function(c){var col = new THREE.Mesh(new THREE.CylinderGeometry(0.22, 0.22, 8, 8), matS);col.position.set(MLX+c[0], 4, MLZ+c[1]);groups.plant.add(col);});box(7.4, 5.2, 5.4, MLX, 10.6, MLZ, matB);box(7.4, 5.2, 5.4, MLX, 10.6, MLZ, new THREE.MeshBasicMaterial({ color:0x000000, wireframe:true }));// 顶部配料斗(倒锥体,开口朝上)var hopper = new THREE.Mesh(new THREE.ConeGeometry(1.6, 1.8, 8), matB);hopper.rotation.x = Math.PI;hopper.position.set(MLX, 14.4, MLZ);groups.plant.add(hopper);// 出料斗(下方锥斗,伸向泵车)var out = new THREE.Mesh(new THREE.ConeGeometry(0.9, 1.4, 8), matB);out.position.set(MLX, 6.7, MLZ);groups.plant.add(out);// ② 粉料筒仓 ×4(水泥×2 + 粉煤灰×2,高12m)[-6.5, -2.2, 2.2, 6.5].forEach(function(dx, i){var sx = PX + dx, sz = PZ - 9;var silo = new THREE.Mesh(new THREE.CylinderGeometry(1.5, 1.5, 10, 12), matS);silo.position.set(sx, 5, sz);groups.plant.add(silo);var cone = new THREE.Mesh(new THREE.ConeGeometry(1.5, 2.2, 12), matS);cone.position.set(sx, 11.1, sz);groups.plant.add(cone);var leg = new THREE.Mesh(new THREE.CylinderGeometry(0.12, 0.12, 0.8, 6), matS);leg.position.set(sx, 0.4, sz);groups.plant.add(leg);});// ③ 骨料仓(砂/碎石 3 堆,半锥形)[[-8.5, -2.2], [-2.8, -2.2], [2.9, -2.2]].forEach(function(g){var pile = new THREE.Mesh(new THREE.ConeGeometry(2.4, 1.7, 8), matG);pile.position.set(PX+g[0], 0.85, PZ+g[1]);groups.plant.add(pile);});// ④ 斜皮带输送机(骨料仓→搅拌楼顶)var belt = new THREE.Mesh(new THREE.CylinderGeometry(0.3, 0.3, 16, 8), matY);belt.rotation.x = 0.30;belt.position.set(PX - 5.5, 6.6, PZ + 1.6);groups.plant.add(belt);// ⑤ 操作室 / 配电房box(4.5, 2.4, 3.0, PX + 9, 1.2, PZ + 6, new THREE.MeshPhongMaterial({ color:0xa9b6c2, emissive:0x3a444e }));// ⑥ 泵站(HBT90 拖泵 ×2,紧邻出料斗)var pz = PZ + 13;[-1.5, 1.5].forEach(function(dx){box(2.8, 1.7, 5.6, PX + dx, 1.15, pz, matR);// 泵车料斗(开口朝上,接收搅拌楼混凝土)var tl = new THREE.Mesh(new THREE.ConeGeometry(0.7, 1.0, 8), matR);tl.rotation.x = Math.PI;tl.position.set(PX + dx, 2.5, pz);groups.plant.add(tl);// 出料软管var hose = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, 2.2, 6), matR);hose.rotation.z = Math.PI/2;hose.position.set(PX + dx + 1.4, 1.7, pz + 3.4);groups.plant.add(hose);});// 泵站雨棚box(7.6, 0.12, 7.4, PX, 3.4, pz, matS);[[-3.6, -3.4], [3.6, -3.4], [-3.6, 3.4], [3.6, 3.4]].forEach(function(c){var pole = new THREE.Mesh(new THREE.CylinderGeometry(0.08, 0.08, 3.4, 6), matS);pole.position.set(PX+c[0], 1.7, pz+c[1]);groups.plant.add(pole);});// ⑦ 泵送管线(泵站→桥位:沿便道地面管线,接入塔1泵管底部 X=13.5, y=0.4, Z=2.3)function line(x1, y1, z1, x2, y2, z2, r){var dx=x2-x1, dy=y2-y1, dz=z2-z1;var len = Math.sqrt(dx*dx+dy*dy+dz*dz);if(len < 0.5) return;var m = new THREE.Mesh(new THREE.CylinderGeometry(r, r, len, 6), matD);m.position.set((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), new THREE.Vector3(dx,dy,dz).normalize());groups.plant.add(m);}// 泵站出口 → 桥左端(Z=-121)→ 沿地面至塔1竖管接入点(Z=2.3, X=13.5)line(PX, 0.5, pz, 13.5, 0.5, -121, 0.05); // 沿便道泵送line(13.5, 0.5, -121, 13.5, 0.5, 2.3, 0.05); // 桥台/边坡段// 场站与桥位间运距示意虚线(3km → 图上标注)var dpts = [];for(var t=0; t<=1.001; t+=0.05){dpts.push(new THREE.Vector3(PX + t*(13.5-PX), 0.9, pz + t*(2.3-pz)));}var dl = new THREE.Line(new THREE.BufferGeometry().setFromPoints(dpts),new THREE.LineBasicMaterial({ color:0xd43a2f, transparent:true, opacity:0.35 }));groups.plant.add(dl);scene.add(groups.plant);}function buildCables(){groups.cables = new THREE.Group();var mat = new THREE.MeshPhongMaterial({ color:0x9aa4b0, transparent:true, opacity:0.5 });function cable(x1, y1, z1, x2, y2, z2){var v = new THREE.Vector3(x2 - x1, y2 - y1, z2 - z1);var len = v.length();var mid = new THREE.Vector3((x1+x2)/2, (y1+y2)/2, (z1+z2)/2);var mesh = new THREE.Mesh(new THREE.CylinderGeometry(0.09, 0.09, len, 6), mat);mesh.position.copy(mid);mesh.quaternion.setFromUnitVectors(new THREE.Vector3(0, 1, 0), v.clone().normalize());groups.cables.add(mesh);}// 塔1(Z=0):向两侧各 12 根(锚固点 z=±(9+9i),i=0..11 → ±9~±108)[-1, 1].forEach(function(sx){[-1, 1].forEach(function(sz){for (var i = 0; i < 12; i++){var z = 9 + i * 9;cable(sx * 10.5, 136.5, 0, sx * 10.5, 42.9, sz * z);}});});// 塔2(Z=214):向两侧各 12 根(主跨侧 205~106,边跨侧 223~322)[-1, 1].forEach(function(sx){[-1, 1].forEach(function(sz){for (var j = 0; j < 12; j++){var z = 9 + j * 9;cable(sx * 10.5, 136.5, 214, sx * 10.5, 42.9, 214 + sz * z);}});});scene.add(groups.cables);}function buildLabels(){groups.labels = new THREE.Group();function roundRect(ctx, x, y, w, h, r){ctx.beginPath();ctx.moveTo(x + r, y);ctx.arcTo(x + w, y, x + w, y + h, r);ctx.arcTo(x + w, y + h, x, y + h, r);ctx.arcTo(x, y + h, x, y, r);ctx.arcTo(x, y, x + w, y, r);ctx.closePath();}function label(text, x, y, z, scale){var c = document.createElement('canvas');c.width = 512; c.height = 128;var ctx = c.getContext('2d');ctx.fillStyle = 'rgba(35,50,70,0.78)';roundRect(ctx, 6, 10, 500, 108, 22);ctx.fill();ctx.font = 'bold 46px "Microsoft YaHei","PingFang SC",sans-serif';ctx.fillStyle = '#ffffff';ctx.textAlign = 'center';ctx.textBaseline = 'middle';ctx.fillText(text, 256, 66);var tex = new THREE.CanvasTexture(c);var sp = new THREE.Sprite(new THREE.SpriteMaterial({ map:tex, transparent:true, depthTest:false }));sp.position.set(x, y, z);var s = scale || 16;sp.scale.set(s, s * 0.25, 1);groups.labels.add(sp);return sp;}function dimLine(a, b, labelText, lx, ly, lz, scale){var geo = new THREE.BufferGeometry().setFromPoints([a, b]);var ln = new THREE.Line(geo, new THREE.LineBasicMaterial({ color:0x33475e }));groups.labels.add(ln);if (labelText) label(labelText, lx, ly, lz, scale);}function tick(p, dx, dz){var geo = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(p.x - dx, p.y, p.z - dz),new THREE.Vector3(p.x + dx, p.y, p.z + dz)]);groups.labels.add(new THREE.Line(geo, new THREE.LineBasicMaterial({ color:0x33475e })));}// 结构名称标签label('索塔1 H=140m', -15, 148, 0, 18);label('劲性骨架(塔肢内)', 11.2, 126, -4, 12);label('锚固区骨架加密段 95~140m(平联5m/道)', 15, 118, -4, 11);label('6m节段分缝·节点板+M20螺栓', 15, 34, 4, 11);label('下横梁', 0, 32.5, 7.5, 13);label('塔1 0号块 20m', 0, 47.6, -13, 14);label('贝雷梁平台 2m', 7.8, 42.8, 8.5, 11);label('钢管桩 Φ60cm×40m', 8.8, 21, 10.8, 13);label('塔肢投影 · 禁布桩', -15, 2.2, 4, 12);label('挂篮(示意)', 0, 51.5, 17.5, 11);label('塔吊 H≈150m(附壁式)', 16, 165, 4, 12);label('施工电梯(附壁)', -16.5, 153, 8, 11);label('混凝土泵管', 13.5, 148, 8, 10);label('液压爬模(爬升平台)', -10.5, 67.5, 5, 11);label('塔顶缆索吊机(主索+跑车)', 0, 150, 132, 12);label('混凝土拌合站 / 泵站', -46, 20, -172, 12);label('泵送管线 · 平均运距≈3km', 26, 6, -60, 11);label('斜拉索(双索面)', 15, 105, 0, 13);label('峡谷地面(支架基础面)', 0, 2.2, -34, 14);// 塔1 边跨现浇段标签label('边跨现浇段 13m', 0, 47.8, -126, 13);label('过渡墩', -6, 45.5, -122.5, 11);label('过渡墩投影 · 禁布桩', -7, 2.2, -122.5, 10);label('边跨合拢段 2m', 0, 47.2, -107, 10);label('中跨合拢段 2m', 0, 47.2, 107, 10);label('边跨桩 3排×5根', 10.5, 21, -114, 11);label('0号块桩 4排×5根(20根)', 11, 21, 0, 11);label('边跨悬浇段 16段×6m', 0, 47.8, -62, 12);label('中跨悬浇段 16段×6m', 0, 47.8, 62, 12);label('主跨悬浇段(塔2侧)16段×6m', 0, 47.8, 158, 11);// 塔2 结构标签label('索塔2 H=140m', 15, 148, 214, 18);label('塔2 0号块 20m', 0, 47.6, 201, 14);label('塔2 0号块桩 4排×5根(20根)', 11, 21, 214, 11);label('塔2边跨悬浇段 16段×6m', 0, 47.8, 270, 11);label('塔2边跨合拢段 2m', 0, 47.2, 321, 10);label('塔2边跨现浇段 13m', 0, 47.8, 331, 11);label('塔2过渡墩', -6, 45.5, 336, 11);label('塔2边跨桩 3排×5根', 10.5, 21, 328, 11);label('塔2边跨现浇段投影 · 禁布桩', 7, 2.2, 337, 10);// 40m 支架高dimLine(new THREE.Vector3(8.9, 0, 9.8), new THREE.Vector3(8.9, 40, 9.8), '40m', 8.9, 20, 12.2, 10);tick(new THREE.Vector3(8.9, 0, 9.8), 0.5, 0);tick(new THREE.Vector3(8.9, 40, 9.8), 0.5, 0);// 20m 0号块长dimLine(new THREE.Vector3(-1.2, 46.8, -10), new THREE.Vector3(-1.2, 46.8, 10), '20m', -1.2, 48.6, 0, 10);tick(new THREE.Vector3(-1.2, 46.8, -10), 0, 0.5);tick(new THREE.Vector3(-1.2, 46.8, 10), 0, 0.5);// 24.5m 桥宽dimLine(new THREE.Vector3(-12.25, 43, 11.2), new THREE.Vector3(12.25, 43, 11.2), '24.5m', 0, 44.8, 11.2, 10);tick(new THREE.Vector3(-12.25, 43, 11.2), 0.5, 0);tick(new THREE.Vector3(12.25, 43, 11.2), 0.5, 0);// 140m 塔高dimLine(new THREE.Vector3(-13.8, 0, -3.5), new THREE.Vector3(-13.8, 139.5, -3.5), '140m', -13.8, 70, -6.5, 10);tick(new THREE.Vector3(-13.8, 0, -3.5), 0.5, 0);tick(new THREE.Vector3(-13.8, 139.5, -3.5), 0.5, 0);// 塔肢中心距dimLine(new THREE.Vector3(-10.5, 0.8, 5.5), new THREE.Vector3(10.5, 0.8, 5.5), '塔肢中心距 21m', 0, 3, 8, 11);// 贝雷梁 2mdimLine(new THREE.Vector3(5, 38, 9.3), new THREE.Vector3(5, 40, 9.3), '2m', 5, 41.2, 9.3, 8);// 边跨现浇段 13mdimLine(new THREE.Vector3(-1.2, 46.8, -121), new THREE.Vector3(-1.2, 46.8, -108), '13m', -1.2, 48.6, -114.5, 10);tick(new THREE.Vector3(-1.2, 46.8, -121), 0, 0.5);tick(new THREE.Vector3(-1.2, 46.8, -108), 0, 0.5);// 边跨桩排距示意(3排)dimLine(new THREE.Vector3(9.5, 0.8, -118.5), new THREE.Vector3(9.5, 0.8, -109.5), '排距4.5m×2', 9.5, 3.2, -114, 9);// 0号块桩横向5根间距示意dimLine(new THREE.Vector3(-5.5, 0.8, -11), new THREE.Vector3(5.5, 0.8, -11), '横向5根 · 间距2.75m', 0, 3.2, -11, 9);scene.add(groups.labels);}function setGroupOpacity(grp, op){grp.traverse(function(o){if (o.isMesh && o.material){o.material.transparent = (op < 1);o.material.opacity = op;o.material.depthWrite = (op >= 1);o.material.needsUpdate = true;}});}function bindUI(){document.getElementById('chk-rotate').onchange = function(e){ controls.autoRotate = e.target.checked; };document.getElementById('chk-cables').onchange = function(e){ groups.cables.visible = e.target.checked; };document.getElementById('chk-cant').onchange = function(e){ groups.cant.visible = e.target.checked; };document.getElementById('chk-labels').onchange = function(e){ groups.labels.visible = e.target.checked; };document.getElementById('chk-nogo').onchange = function(e){ groups.nogo.visible = e.target.checked; };document.getElementById('chk-seg').onchange = function(e){groups.seg.visible = e.target.checked;groups.closure.visible = e.target.checked;groups.segLong.visible = e.target.checked && document.getElementById('chk-seg-long').checked;groups.segTrans.visible = e.target.checked && document.getElementById('chk-seg-trans').checked;groups.segVert.visible = e.target.checked && document.getElementById('chk-seg-vert').checked;};document.getElementById('chk-seg-long').onchange = function(e){groups.segLong.visible = e.target.checked && document.getElementById('chk-seg').checked;};document.getElementById('chk-seg-trans').onchange = function(e){groups.segTrans.visible = e.target.checked && document.getElementById('chk-seg').checked;};document.getElementById('chk-seg-vert').onchange = function(e){groups.segVert.visible = e.target.checked && document.getElementById('chk-seg').checked;};document.getElementById('chk-tower').onchange = function(e){ setGroupOpacity(groups.tower, e.target.checked ? 0.22 : 1); };document.getElementById('chk-brace').onchange = function(e){ groups.bracing.visible = e.target.checked; };// 劲性骨架:勾选 → 骨架可见 + 塔柱联动半透明(透视内部桁架);取消 → 恢复实心document.getElementById('chk-frame').onchange = function(e){var on = e.target.checked;groups.frame.visible = on;var tw = document.getElementById('chk-tower');if(on){tw.checked = true;setGroupOpacity(groups.tower, 0.22);} else {tw.checked = false;setGroupOpacity(groups.tower, 1);}};// 节段分缝(节点板+螺栓):勾选时若骨架被隐藏则联动显示骨架document.getElementById('chk-joint').onchange = function(e){var on = e.target.checked;groups.frameJoints.visible = on;if(on && !document.getElementById('chk-frame').checked){document.getElementById('chk-frame').checked = true;groups.frame.visible = true;document.getElementById('chk-tower').checked = true;setGroupOpacity(groups.tower, 0.22);}};document.getElementById('chk-crane').onchange = function(e){ groups.crane.visible = e.target.checked; };document.getElementById('chk-lift').onchange = function(e){ groups.lift.visible = e.target.checked; };document.getElementById('chk-pump').onchange = function(e){ groups.pump.visible = e.target.checked; };document.getElementById('chk-form').onchange = function(e){ groups.form.visible = e.target.checked; };document.getElementById('chk-cablecrane').onchange = function(e){ groups.cablecrane.visible = e.target.checked; };document.getElementById('chk-plant').onchange = function(e){ groups.plant.visible = e.target.checked; };// 初始同步:骨架默认显示 → 塔柱联动半透明setGroupOpacity(groups.tower, 0.22);var views = {'整体': [[280, 190, 450], [0, 55, 107]],'正面': [[0, 90, 560], [0, 50, 107]],'侧面': [[540, 95, 0], [0, 50, 107]],'俯视': [[0, 440, 5], [0, 0, 107]],'近景': [[60, 28, 62], [0, 25, 0]],'边跨近景': [[72, 26, -104], [0, 24, -114]],'边跨合拢': [[0, 40, -70], [0, 42, -107]],'中跨合拢': [[0, 40, 145], [0, 42, 107]],'塔2近景': [[260, 26, 176], [0, 25, 214]],'塔吊近景': [[42, 120, 64], [15, 88, 10]],'缆索吊近景': [[26, 105, 78], [0, 60, 107]],'拌合站近景': [[-80, 26, -138], [-46, 6, -172]],'横断面': [[0, 44, 36], [0, 42, 0]]};document.querySelectorAll('.views button').forEach(function(b){b.onclick = function(){var v = views[b.dataset.v];if (b.dataset.v === '横断面') setCrossSection(true);else setCrossSection(false);moveCamera(new THREE.Vector3(v[0][0], v[0][1], v[0][2]), new THREE.Vector3(v[1][0], v[1][1], v[1][2]));};});document.getElementById('xs-close').onclick = function(){setCrossSection(false);var v = views['整体'];moveCamera(new THREE.Vector3(v[0][0], v[0][1], v[0][2]), new THREE.Vector3(v[1][0], v[1][1], v[1][2]));};}var _clip = null;var _xsState = { cant:null, labels:null, rotate:null, crane:null, lift:null, pump:null, form:null, cablecrane:null, plant:null };var _xsHide = ['cant','crane','lift','pump','form','cablecrane','plant'];// 在塔中心 Z=0.05 处剖切,露出横断面:切掉 Z>0.05 的主梁/塔/悬浇段/合拢段function setCrossSection(on){var p = document.getElementById('xsect');var rk = document.getElementById('chk-rotate');if (on){if (!_clip) _clip = new THREE.Plane(new THREE.Vector3(0, 0, -1), 0.05);['tower','girder','side','seg','segLong','segTrans','segVert','closure','frame','frameJoints','crane','lift','pump','form'].forEach(function(k){groups[k].traverse(function(o){if (o.material){if (o.material._saveClip === undefined) o.material._saveClip = o.material.clippingPlanes;o.material.clippingPlanes = [_clip];}});});if (_xsState.rotate === null) _xsState.rotate = rk ? rk.checked : true;_xsHide.forEach(function(k){if (_xsState[k] === null) _xsState[k] = groups[k].visible;groups[k].visible = false; // 挂篮/塔吊/电梯/泵管/爬模挡横断面视线,临时隐藏});groups.labels.visible = false; // 3D 标注同样遮挡,由 2D 面板承担标注controls.autoRotate = false;if (rk) rk.checked = false;if (p) p.style.display = 'block';} else {Object.keys(groups).forEach(function(k){if (!groups[k]) return;groups[k].traverse(function(o){if (o.material){if (o.material._saveClip !== undefined){ o.material.clippingPlanes = o.material._saveClip; }else { o.material.clippingPlanes = null; }}});});_xsHide.forEach(function(k){if (_xsState[k] !== null){ groups[k].visible = _xsState[k]; _xsState[k] = null; }});if (_xsState.labels !== null){ groups.labels.visible = _xsState.labels; _xsState.labels = null; }if (_xsState.rotate !== null){controls.autoRotate = _xsState.rotate;if (rk) rk.checked = _xsState.rotate;_xsState.rotate = null;}if (p) p.style.display = 'none';}}function moveCamera(pos, target){var start = camera.position.clone();var startT = controls.target.clone();var t0 = performance.now();function anim(now){var t = Math.min(1, (now - t0) / 900);var e = t * t * (3 - 2 * t);camera.position.lerpVectors(start, pos, e);controls.target.lerpVectors(startT, target, e);controls.update();if (t < 1) requestAnimationFrame(anim);}requestAnimationFrame(anim);}function animate(){requestAnimationFrame(animate);controls.update();renderer.render(scene, camera);}boot();})();</script></body></html>
本文来自网友投稿或网络内容,如有侵犯您的权益请联系我们删除,联系邮箱:wyl860211@qq.com 。