diff --git a/B06_Section/B06_Section_Engine_Design.py b/B06_Section/B06_Section_Engine_Design.py index 367b2bec..7c7a86a7 100644 --- a/B06_Section/B06_Section_Engine_Design.py +++ b/B06_Section/B06_Section_Engine_Design.py @@ -351,12 +351,18 @@ class _SectionGeometry: berm_rise = math.tan(math.radians(self.berm.slope_deg)) * self.berm.width_m if abs(rise - berm_rise) < 1e-9: continue + # 재료는 **그 구간을 실제로 그린 경사비**로 가른다 — 경계선을 다시 재면 + # 안 된다. 무릎을 지난 뒤에도 경계선은 지반을 따라 계속 오르므로, 토사 + # 경사로 그린 구간이 경계 아래로 되돌아가 있는 일이 흔하다. 그것을 경계로 + # 재면 「경사비는 토사인데 재료는 암」인 구간이 생긴다(2026-09-07 다른 창 + # 실측: 용화 63측점에서 13구간). 그린 대로 적는 것이 맞다. material: str | None = None - if self.two_stage: - middle_d = (start_d + end_d) / 2.0 - middle_z = (start_z + end_z) / 2.0 + if self.two_stage and abs(self.soil_cut_ratio - self.cut_ratio) > 1e-9: + drawn = run / rise material = ( - "soil" if middle_z >= self._rock_boundary_z(side, middle_d) else "rock" + "soil" + if abs(drawn - self.soil_cut_ratio) < abs(drawn - self.cut_ratio) + else "rock" ) segments.append( { diff --git a/common_util/common_util_cross_design_geometry.ts b/common_util/common_util_cross_design_geometry.ts index 87d84ae8..7e7f6d27 100644 --- a/common_util/common_util_cross_design_geometry.ts +++ b/common_util/common_util_cross_design_geometry.ts @@ -381,11 +381,13 @@ export class SectionGeometry { const bermRise = Math.tan((this.berm.slopeDeg * Math.PI) / 180) * this.berm.widthM; if (Math.abs(rise - bermRise) < 1e-9) continue; // 소단(평탄부) } + // 재료는 **그 구간을 실제로 그린 경사비**로 가른다(짝 파이썬과 같은 까닭) — + // 경계선을 다시 재면 「경사비는 토사인데 재료는 암」인 구간이 생긴다. let material: string | null = null; - if (this.twoStage) { - const middleD = (startD + endD) / 2; - const middleZ = (startZ + endZ) / 2; - material = middleZ >= this.rockBoundaryZ(side, middleD) ? "soil" : "rock"; + if (this.twoStage && Math.abs(this.soilCutRatio - this.cutRatio) > 1e-9) { + const drawn = run / rise; + material = + Math.abs(drawn - this.soilCutRatio) < Math.abs(drawn - this.cutRatio) ? "soil" : "rock"; } segments.push({ side,