Merge remote-tracking branch 'origin/main_laptop_1' into sub_desktop_1
This commit is contained in:
@@ -639,6 +639,56 @@ def _num(value: Any, fallback: float = 0.0) -> float:
|
||||
return float(value) if isinstance(value, (int, float)) else fallback
|
||||
|
||||
|
||||
#: 벽 두께를 **사용자가 덮어쓰는 칸** — 비우면 실무 구조물도 식으로 돈다(확정 2차 ② 후반
|
||||
#: 「사용자가 값을 바꿀 수 있게」). 야면석 계수·채움 강도와 같은 자리다.
|
||||
WALL_THICKNESS_KEYS: tuple[str, str] = ("thickness_top_m", "thickness_bottom_m")
|
||||
|
||||
|
||||
def wall_thickness(
|
||||
options: dict[str, Any], *, back_cm: float, height_m: float
|
||||
) -> tuple[float, float, str]:
|
||||
"""(상부 두께 m, 하부 두께 m, 근거 문구) — **사용자가 넣은 값이 식을 이긴다.**
|
||||
|
||||
⚠ 빈 칸은 「안 정함」이다 — 자동으로 나온 값을 저장에 박지 않는다(`face_slope_ratio`
|
||||
와 같은 태도). 상부만 넣으면 하부는 **그 상부 위에서** 식을 이어 간다 — 벽 모양
|
||||
(아래로 벌어지는 기울기)을 사용자 값 위에 그대로 얹는 것이 자연스럽다.
|
||||
"""
|
||||
|
||||
def given(key: str) -> float | None:
|
||||
raw = options.get(key)
|
||||
if raw in (None, ""):
|
||||
return None
|
||||
try:
|
||||
value = float(raw)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
return value if value > 0 else None
|
||||
|
||||
constants = STONE_MASONRY
|
||||
back_m = back_cm / 100.0
|
||||
top_given = given(WALL_THICKNESS_KEYS[0])
|
||||
top = top_given if top_given is not None else back_m + constants["thickness_top_add_m"]
|
||||
rise = constants["thickness_slope_per_m"] * max(
|
||||
height_m - constants["thickness_height_base_m"], 0.0
|
||||
)
|
||||
bottom_given = given(WALL_THICKNESS_KEYS[1])
|
||||
bottom = bottom_given if bottom_given is not None else top + rise
|
||||
top_basis = (
|
||||
f"상부 {top:.2f}(사용자 입력)"
|
||||
if top_given is not None
|
||||
else f"상부 {top:.2f}(뒷길이 {back_cm:g}㎝ + {constants['thickness_top_add_m']:g})"
|
||||
)
|
||||
bottom_basis = (
|
||||
f"하부 {bottom:.2f}(사용자 입력)"
|
||||
if bottom_given is not None
|
||||
else (
|
||||
f"하부 {bottom:.2f}(상부 + {constants['thickness_slope_per_m']:g}"
|
||||
f"×(H−{constants['thickness_height_base_m']:g}))"
|
||||
)
|
||||
)
|
||||
return top, bottom, f"실무 구조물도 식 — {top_basis} · {bottom_basis}"
|
||||
|
||||
|
||||
#: 큰돌쌓기(품셈 13-6) 직경 갈래 — **저장 제원 `stone_cm` 과 글자까지 같다**(레지스트리 확인).
|
||||
#: ⚠ 돌쌓기(13-4)의 **뒷길이** 축과 섞지 않는다. 앞서 섞여 있어 직경 60~80 짜리가
|
||||
#: 「뒷길이 45㎝」 계수로 돌던 자리다.
|
||||
@@ -871,16 +921,12 @@ def stone_masonry(
|
||||
# 실무 시트의 「정면적 × 1.04」가 바로 이 값이다(1:0.3 에서 1.0440 ≈ 1.04).
|
||||
masonry_area = face_area * math.hypot(1.0, slope_ratio)
|
||||
# 벽 두께 — 실무 구조물도 식(확정 2차 ②). **뒷길이가 들어간다.**
|
||||
back_m = back_cm / 100.0
|
||||
top_thickness = back_m + constants["thickness_top_add_m"]
|
||||
bottom_thickness = top_thickness + constants["thickness_slope_per_m"] * max(
|
||||
height_m - constants["thickness_height_base_m"], 0.0
|
||||
# ⚠ 표준도 제원에 상부·하부 두께 칸이 있으면 **그 값이 식을 이긴다**(확정 ② 후반).
|
||||
back_m = back_cm / 100.0 # 석적(아래)이 뒷길이를 m 로 쓴다
|
||||
top_thickness, bottom_thickness, thickness_basis = wall_thickness(
|
||||
options, back_cm=back_cm, height_m=height_m
|
||||
)
|
||||
thickness = (top_thickness + bottom_thickness) / 2.0
|
||||
thickness_basis = (
|
||||
f"실무 구조물도 식 — 상부 {top_thickness:.2f}(뒷길이 {back_cm}㎝ + 0.30) ·"
|
||||
f" 하부 {bottom_thickness:.2f}(상부 + 0.30×(H−1))"
|
||||
)
|
||||
volume = face_area * thickness # 입적
|
||||
|
||||
components = [
|
||||
|
||||
Reference in New Issue
Block a user