260725_4
This commit is contained in:
@@ -195,6 +195,8 @@ class _SectionGeometry:
|
||||
self._ground_at = ground_at
|
||||
self._rock_offset = rock_boundary_offset_m or 0.0
|
||||
self._rock_knee: dict[str, tuple[float, float] | None] = {}
|
||||
# 절토 사면·지반 최초 교차거리(측별 캐시) — 교차 후 절토 종료용(N-2-4).
|
||||
self._cut_cross: dict[str, float | None] = {}
|
||||
self.ditch_type = ditch_type
|
||||
# 횡단경사: 측구 방향으로 내려가는 단일 사면 (좌=+offset 규약).
|
||||
slope = cross_slope_pct / 100.0
|
||||
@@ -311,6 +313,41 @@ class _SectionGeometry:
|
||||
self._rock_knee[side] = result
|
||||
return result
|
||||
|
||||
def _cut_slope_z(self, side: str, dist: float) -> float:
|
||||
"""절토 사면선 표고(2단계 무릎 반영). 지반 교차 클램프는 하지 않는다."""
|
||||
start_dist, start_z = self._slope_start(side)
|
||||
knee = self.knee(side) if self.two_stage else None
|
||||
if knee is not None:
|
||||
knee_dist, knee_z = knee
|
||||
if dist <= knee_dist: # 암반 구간(경계 아래): 암 경사
|
||||
return start_z + (dist - start_dist) / self.cut_ratio
|
||||
return knee_z + (dist - knee_dist) / self.soil_cut_ratio # 토사 구간: 완만
|
||||
return start_z + (dist - start_dist) / self.cut_ratio
|
||||
|
||||
def cut_cross_dist(self, side: str) -> float | None:
|
||||
"""절토 사면이 지반선과 처음 만나는 거리(절대 오프셋). 이후는 절토 없음(N-2-4).
|
||||
|
||||
지면과 1회 교차하면 그다음 경사(2단계 전환 포함)는 의미가 없으므로 교차점에서
|
||||
절토를 종료한다. 시작(노면 끝)부터 사면이 지반 위면 교차거리=시작(절토 없음),
|
||||
끝까지 못 만나면 None.
|
||||
"""
|
||||
if side in self._cut_cross:
|
||||
return self._cut_cross[side]
|
||||
result: float | None = None
|
||||
if self._ground_at is not None:
|
||||
start_dist, _start_z = self._slope_start(side)
|
||||
step = 0.05
|
||||
dist = start_dist
|
||||
max_dist = start_dist + 500.0
|
||||
while dist <= max_dist:
|
||||
signed = dist if side == "left" else -dist
|
||||
if self._cut_slope_z(side, dist) - self._ground_at(signed) >= 0:
|
||||
result = dist
|
||||
break
|
||||
dist += step
|
||||
self._cut_cross[side] = result
|
||||
return result
|
||||
|
||||
def design_z(self, offset_m: float, ground_m: float) -> float:
|
||||
"""offset 하나의 설계 표고(사면은 지반 교차점 이후 지반 추종)."""
|
||||
side = "left" if offset_m >= 0 else "right"
|
||||
@@ -339,16 +376,11 @@ class _SectionGeometry:
|
||||
dist = abs(offset_m)
|
||||
run = dist - start_dist
|
||||
if role == "cut":
|
||||
knee = self.knee(side) if self.two_stage else None
|
||||
if knee is not None:
|
||||
knee_dist, knee_z = knee
|
||||
if dist <= knee_dist: # 암반 구간(경계 아래): 암 경사
|
||||
slope_line = start_z + (dist - start_dist) / self.cut_ratio
|
||||
else: # 토사 구간(경계 위): 무릎에서 토사 경사로 완만
|
||||
slope_line = knee_z + (dist - knee_dist) / self.soil_cut_ratio
|
||||
else:
|
||||
slope_line = start_z + run / self.cut_ratio
|
||||
return min(slope_line, ground_m)
|
||||
# 지반과 1회 교차하면 그 이후 절토는 의미 없음 → 지반 추종(N-2-4).
|
||||
cross = self.cut_cross_dist(side)
|
||||
if cross is not None and dist >= cross:
|
||||
return ground_m
|
||||
return min(self._cut_slope_z(side, dist), ground_m)
|
||||
fill_line = start_z - run / self.fill_ratio
|
||||
return max(fill_line, ground_m)
|
||||
|
||||
@@ -362,6 +394,13 @@ class _SectionGeometry:
|
||||
knee = self.knee(side) if role == "cut" else None
|
||||
if knee is not None:
|
||||
points.append(knee[0] if side == "left" else -knee[0])
|
||||
# 절토 사면·지반 교차점을 꼭짓점에 넣어 면적 절단을 정확히 한다(N-2-4).
|
||||
for side in ("left", "right"):
|
||||
role = self.left_role if side == "left" else self.right_role
|
||||
if role == "cut":
|
||||
cross = self.cut_cross_dist(side)
|
||||
if cross is not None:
|
||||
points.append(cross if side == "left" else -cross)
|
||||
return points
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user