# -*- coding: utf-8 -*-
"""
房屋平面图生成器（第四版 · 按用户手绘布局对照图）
单位：米。x 向东（图纸右），y 向南（图纸下）。

用户对照图确定的布局：
  左列 x 0～3.5   ：主卧(4.5高) / 主卫(1.5高) / 厨房(4.75高)
  中列 x 3.5～6.0 ：入户门厅(上部) / 楼梯(下部) / 卧室(南侧)
  右列 x 6.0～9.5 ：卧室(4.75高) / 公卫(2.0高) / 卧室(4.25高)
尺寸标注（对照图上写的）：左 4.5/1.5/4.75；右 4.75/2/4.25；上 3.5/3.5；下 2.5/3.5/3.5/3.5
"""
import math

S = 72.0
M = 215.0
MT = 285.0
MB = 255.0
WALL = 0.18
CW = WALL * S

IMG_W = 13.2 * S + 2 * M
IMG_H = 11.0 * S + MT + MB

def X(x): return M + x * S
def Y(y): return MT + y * S

out = []
def add(s): out.append(s)

FONT = '"Source Han Mono SC","思源等宽","GB_HT_GB18030","国标黑体",sans-serif'

add(f'''<svg xmlns="http://www.w3.org/2000/svg" width="{IMG_W:.0f}" height="{IMG_H:.0f}" viewBox="0 0 {IMG_W:.0f} {IMG_H:.0f}">
<style>
  .wall {{ fill:#242424; }}
  .lbl  {{ font-family:{FONT}; font-size:23px; fill:#1c1c1c; text-anchor:middle; }}
  .lbl-s{{ font-family:{FONT}; font-size:16px; fill:#8a8a8a; text-anchor:middle; }}
  .dim  {{ font-family:"DejaVu Sans",sans-serif; font-size:18px; fill:#1b5e9b; text-anchor:middle; }}
  .dl   {{ stroke:#1b5e9b; stroke-width:1.1; fill:none; }}
  .door {{ stroke:#c1621b; stroke-width:2.4; fill:none; }}
  .win  {{ stroke:#1b5e9b; stroke-width:1.7; fill:none; }}
  .stair{{ stroke:#8c8c8c; stroke-width:1.3; fill:none; }}
  .note {{ font-family:{FONT}; font-size:15px; fill:#9a9a9a; }}
  .title{{ font-family:{FONT}; font-size:31px; fill:#111; font-weight:600; }}
  .sub  {{ font-family:{FONT}; font-size:17px; fill:#666; }}
</style>
<rect width="{IMG_W:.0f}" height="{IMG_H:.0f}" fill="#ffffff"/>''')

D = "#fdfdfb"; WET = "#f2f0ea"; CIR = "#f5f3ee"

rooms = [
    # 左列 x 0～2.5
    ("主卫",   0.00, 4.50, 2.50,  6.00, WET),
    ("厨房",   0.00, 6.00, 2.50, 10.75, WET),
    # 主卧（3.5 宽，右侧向下伸出到与主卫底边齐平）
    ("主卧",   0.00, 0.00, 3.80,  4.50, D),
    ("主卧",   2.50, 4.50, 3.80,  6.00, D),
    # 中区
    ("门厅·入户", 3.80, 0.00, 9.40,  6.75, "#f7f6f2"),
    ("餐厅·客厅", 2.50, 6.00, 5.90, 10.75, D),
    ("楼梯间",    5.90, 6.75, 9.40, 10.75, CIR),
    # 右列 x 9.5～13.0
    ("卧室",   9.40, 0.00, 13.20, 4.75, D),
    ("公卫",   10.70, 4.75, 13.20, 6.75, WET),
    ("过道",   9.40, 4.75, 10.70, 6.75, "#f7f6f2"),
    ("卧室",   9.40, 6.75, 13.20, 10.75, D),
]
for name, x1, y1, x2, y2, fill in rooms:
    add(f'<rect x="{X(x1):.1f}" y="{Y(y1):.1f}" width="{(x2-x1)*S:.1f}" height="{(y2-y1)*S:.1f}" fill="{fill}"/>')

def hwall(x1, x2, y, t=WALL):
    add(f'<rect class="wall" x="{X(x1):.1f}" y="{Y(y)-t*S/2:.1f}" width="{(x2-x1)*S:.1f}" height="{t*S:.1f}"/>')

def vwall(x, y1, y2, t=WALL):
    add(f'<rect class="wall" x="{X(x)-t*S/2:.1f}" y="{Y(y1):.1f}" width="{t*S:.1f}" height="{(y2-y1)*S:.1f}"/>')

# 矩形外轮廓 13.0 × 10.75（入户门内凹门斗）
hwall(-WALL/2, 3.80 + WALL/2, 0.00)          # 北外墙（左段：主卧北墙，到 x=3.8）
hwall(9.40 - WALL/2, 13.2 + WALL/2, 0.00)    # 北外墙（右段：右列卧室北墙，从 x=9.4 起）
hwall(-WALL/2, 13.2 + WALL/2, 10.75)         # 南外墙
vwall(0.00, 0.00, 10.75)                     # 西外墙
vwall(13.20, 0.00, 10.75)                    # 东外墙
hwall(3.80, 9.40, 1.00)                      # 门墙：主卧东墙↔右上卧室西墙，整条后退 1.0 m（大门所在）
# 内墙
vwall(2.50, 4.50, 10.75)                     # 厨房/主卫 东墙（= 2.5 那道墙）
vwall(3.80, 0.00, 6.00)                      # 主卧右侧墙（完整，y 0～6.0；主卧开间 3.8）
hwall(0.00, 2.50, 4.50)                      # 主卧 / 主卫
hwall(0.00, 2.50, 6.00)                      # 主卫 / 厨房
hwall(2.50, 3.80, 6.00)                      # 主卧下伸段底墙（含主卧门）
hwall(5.90, 9.40, 6.75)                      # 门厅 / 楼梯间（与公卫底边、右卧顶边对齐）
vwall(5.90, 6.75, 10.75)                     # 餐厅·客厅 / 楼梯间
vwall(9.40, 0.00, 4.75)                      # 中区 / 右列（上段）
vwall(9.40, 6.75, 10.75)                     # 中区 / 右列（下段，中间 4.75～6.75 敞开）
vwall(10.70, 4.75, 6.75)                     # 公卫西墙（公卫净宽 2.5）
hwall(9.40, 13.20, 4.75)                     # 卧室 / 公卫
hwall(9.40, 13.20, 6.75)                     # 公卫 / 卧室

def clear_v(x, y1, y2):
    add(f'<rect x="{X(x)-CW/2:.1f}" y="{Y(y1):.1f}" width="{CW:.1f}" height="{(y2-y1)*S:.1f}" fill="#ffffff"/>')

def clear_h(x1, x2, y):
    add(f'<rect x="{X(x1):.1f}" y="{Y(y)-CW/2:.1f}" width="{(x2-x1)*S:.1f}" height="{CW:.1f}" fill="#ffffff"/>')

def arc(cx, cy, r, a0, a1):
    x0, y0 = cx + r*math.cos(a0), cy + r*math.sin(a0)
    x1, y1 = cx + r*math.cos(a1), cy + r*math.sin(a1)
    large = 1 if abs(a1 - a0) > math.pi else 0
    sweep = 1 if a1 > a0 else 0
    add(f'<path class="door" d="M {x0:.1f} {y0:.1f} A {r:.1f} {r:.1f} 0 {large} {sweep} {x1:.1f} {y1:.1f}"/>')
    add(f'<line class="door" x1="{cx:.1f}" y1="{cy:.1f}" x2="{x0:.1f}" y2="{y0:.1f}"/>')

def door_on_h(x1, x2, y, hinge, open_to):
    clear_h(x1, x2, y)
    r = (x2 - x1) * S
    cx = X(x1) if hinge == 'L' else X(x2)
    cy = Y(y)
    a = [0, math.pi/2*open_to] if hinge == 'L' else [math.pi, math.pi - math.pi/2*open_to]
    arc(cx, cy, r, min(a), max(a))

def door_on_v(x, y1, y2, hinge, open_to):
    clear_v(x, y1, y2)
    r = (y2 - y1) * S
    cx = X(x)
    cy = Y(y1) if hinge == 'T' else Y(y2)
    if hinge == 'T':
        a = [math.pi/2, math.pi/2 - math.pi/2*open_to]
    else:
        a = [-math.pi/2, -math.pi/2 + math.pi/2*open_to]
    arc(cx, cy, r, min(a), max(a))

def slide_door_v(x, y1, y2, thick=0.045, off=0.07):
    """竖直墙上的推拉门：清出洞口 + 两扇错位门板（平面图常用画法）"""
    clear_v(x, y1, y2)
    L = y2 - y1
    half = 0.58 * L
    panels = [(y1, y1 + half, -off), (y2 - half, y2, +off)]
    for ya, yb, o in panels:
        add(f'<rect x="{X(x)+o*S:.1f}" y="{Y(ya):.1f}" width="{thick*S:.1f}" height="{(yb-ya)*S:.1f}" fill="#c1621b"/>')


# 入户双开门：总宽 1.8 m（= 普通门 0.9 m 的两倍），对开两扇、向内开，居中于门厅(x 5.7～7.5)
clear_h(5.70, 7.50, 1.00)
_r = 0.9 * S
arc(X(5.70), Y(1.00), _r, 0.0, math.pi/2)          # 左扇 0.9 m
arc(X(7.50), Y(1.00), _r, math.pi, math.pi/2)      # 右扇 0.9 m
door_on_v(2.50, 4.95, 5.75, 'T', -1)      # 主卫门：开在右侧墙 x=2.5 上，向里（卫生间内）开
door_on_h(2.55, 3.45, 6.00, 'R', -1)      # 主卧门：下伸段底端 y=6.0（原有）
slide_door_v(2.50, 6.90, 8.10)            # 餐厅·客厅 -> 厨房（推拉门 1.2 m）
door_on_v(5.90, 9.30, 10.20, 'B', -1)     # 楼梯间门：左墙(x=5.9)下侧，朝餐厅·客厅开
door_on_h(9.55, 10.45, 4.75, 'L', -1)     # 卧室(右上)门：下墙左段、向内开
door_on_h(9.55, 10.45, 6.75, 'L', +1)     # 卧室(右下)门：上墙左段、向内开
door_on_v(10.70, 4.95, 5.85, 'T', +1)     # 公卫门：西墙 x=10.70，向里（公卫内）开

def win_v(x, y1, y2):
    clear_v(x, y1, y2)
    for dx in (-0.05, 0.05):
        add(f'<line class="win" x1="{X(x)+dx*S:.1f}" y1="{Y(y1):.1f}" x2="{X(x)+dx*S:.1f}" y2="{Y(y2):.1f}"/>')

def win_h(x1, x2, y):
    clear_h(x1, x2, y)
    for dy in (-0.05, 0.05):
        add(f'<line class="win" x1="{X(x1):.1f}" y1="{Y(y)+dy*S:.1f}" x2="{X(x2):.1f}" y2="{Y(y)+dy*S:.1f}"/>')

win_h(0.80, 2.80, 0.00)        # 主卧北窗
win_v(0.00, 0.90, 3.40)        # 主卧西窗
win_v(0.00, 4.80, 5.80)        # 主卫西窗
win_v(0.00, 6.60, 9.20)        # 厨房西窗
win_h(0.40, 2.10, 10.75)       # 厨房南窗
win_h(3.40, 5.60, 10.75)       # 餐厅·客厅南窗
win_h(10.00, 12.40, 0.00)      # 卧室(上) 北窗
win_v(13.20, 1.00, 3.60)       # 卧室(上) 东窗
win_v(13.20, 7.60, 10.20)      # 卧室(下) 东窗
win_h(10.00, 12.40, 10.75)     # 卧室(下) 南窗

sx1, sx2 = 6.15, 9.15
sy1, sy2 = 7.00, 10.50
add(f'<rect class="stair" x="{X(sx1):.1f}" y="{Y(sy1):.1f}" width="{(sx2-sx1)*S:.1f}" height="{(sy2-sy1)*S:.1f}"/>')
n = 11
for i in range(1, n):
    yy = sy1 + (sy2 - sy1) * i / n
    add(f'<line class="stair" x1="{X(sx1):.1f}" y1="{Y(yy):.1f}" x2="{X(sx2):.1f}" y2="{Y(yy):.1f}"/>')
add(f'<path class="stair" d="M {X(7.75):.1f} {Y(10.30):.1f} L {X(7.75):.1f} {Y(7.20):.1f} '
    f'M {X(7.60):.1f} {Y(7.55):.1f} L {X(7.75):.1f} {Y(7.20):.1f} L {X(7.90):.1f} {Y(7.55):.1f}"/>')

def label(name, x1, y1, x2, y2, area=None, ty=0):
    cx, cy = (x1+x2)/2, (y1+y2)/2
    a = area if area is not None else (x2-x1)*(y2-y1)
    add(f'<text class="lbl" x="{X(cx):.1f}" y="{Y(cy)+ty:.1f}">{name}</text>')
    add(f'<text class="lbl-s" x="{X(cx):.1f}" y="{Y(cy)+ty+21:.1f}">{a:.1f} ㎡</text>')

label("主卫",      0.00, 4.50, 2.50,  6.00, ty=-6)
label("厨房",      0.00, 6.00, 2.50, 10.75, ty=-40)
label("主卧",      0.00, 0.00, 3.80,  4.50, area=3.8*4.5+1.3*1.5)  # 含右侧下伸部分
label("门厅·入户", 3.80, 0.00, 9.40,  6.75, area=5.6*6.75, ty=-52)
label("餐厅·客厅", 2.50, 6.00, 5.90, 10.75, ty=-20)
label("楼梯间",    5.90, 6.75, 9.40, 10.75, area=3.5*4.0, ty=95)
label("卧室",      9.40, 0.00, 13.20, 4.75)
label("公卫",      10.70, 4.75, 13.20, 6.75, area=2.5*2.0, ty=2)
label("卧室",      9.40, 6.75, 13.20, 10.75)

def dim_h(x1, x2, y, txt, off):
    yy = Y(y + off)
    add(f'<line class="dl" x1="{X(x1):.1f}" y1="{yy:.1f}" x2="{X(x2):.1f}" y2="{yy:.1f}"/>')
    for xx in (X(x1), X(x2)):
        add(f'<line class="dl" x1="{xx:.1f}" y1="{yy-5:.1f}" x2="{xx:.1f}" y2="{yy+5:.1f}"/>')
    add(f'<text class="dim" x="{(X(x1)+X(x2))/2:.1f}" y="{yy-10:.1f}">{txt}</text>')

def dim_v(y1, y2, x, txt, off):
    xx = X(x + off)
    add(f'<line class="dl" x1="{xx:.1f}" y1="{Y(y1):.1f}" x2="{xx:.1f}" y2="{Y(y2):.1f}"/>')
    for yy in (Y(y1), Y(y2)):
        add(f'<line class="dl" x1="{xx-5:.1f}" y1="{yy:.1f}" x2="{xx+5:.1f}" y2="{yy:.1f}"/>')
    ym = (Y(y1) + Y(y2)) / 2
    add(f'<text class="dim" x="{xx-13:.1f}" y="{ym:.1f}" transform="rotate(-90 {xx-13:.1f} {ym:.1f})">{txt}</text>')

# 底边（你写的 4 段，一一对应）
dim_h(0.00, 2.50, 10.75, "2.5", 0.95)
dim_h(2.50, 5.90, 10.75, "3.4", 0.95)
dim_h(5.90, 9.40, 10.75, "3.5", 0.95)
dim_h(9.40, 13.20, 10.75, "3.8", 0.95)
# 顶边（主卧开间、右侧卧室开间）
dim_h(0.00, 3.80, 0.0, "3.8", -0.95)
dim_h(9.40, 13.20, 0.0, "3.8", -0.95)
# 西边
dim_v(0.00, 4.50, 0.0, "4.5", -0.95)
dim_v(4.50, 6.00, 0.0, "1.5", -0.95)
dim_v(6.00, 10.75, 0.0, "4.75", -0.95)
# 东边
dim_v(0.00, 4.75, 13.20, "4.75", 0.95)
dim_v(4.75, 6.75, 13.20, "2.0", 0.95)
dim_v(6.75, 10.75, 13.20, "4.0", 0.95)

ytop = MT - 104
add(f'<line class="dl" x1="{X(0):.1f}" y1="{ytop:.1f}" x2="{X(13.2):.1f}" y2="{ytop:.1f}"/>')
for xx in (X(0), X(13.2)):
    add(f'<line class="dl" x1="{xx:.1f}" y1="{ytop-6:.1f}" x2="{xx:.1f}" y2="{ytop+6:.1f}"/>')
add(f'<text class="dim" x="{(X(0)+X(13.2))/2:.1f}" y="{ytop-12:.1f}">底边 4 段：2.5 厨房 / 3.4 餐厅·客厅 / 3.5 楼梯间 / 3.8 卧室</text>')
xleft = X(0) - 105
add(f'<line class="dl" x1="{xleft:.1f}" y1="{Y(0):.1f}" x2="{xleft:.1f}" y2="{Y(10.75):.1f}"/>')
ym = Y(10.75) / 2
add(f'<text class="dim" x="{xleft-13:.1f}" y="{ym:.1f}" transform="rotate(-90 {xleft-13:.1f} {ym:.1f})">西边各段：4.5 + 1.5 + 4.75 = 10.75</text>')

add(f'<text class="title" x="{M:.1f}" y="66">自建房屋 · 一层平面图（按你的布局对照图）</text>')
add(f'<text class="sub" x="{M:.1f}" y="100">单位：米　外包 13.2 × 10.75 m（矩形；入户门内凹）　左列 主卧/主卫/厨房　中列 门厅(入户门)/楼梯　右列 卧室/公卫/卧室</text>')

nx, ny = IMG_W - 112, 100
add(f'<path d="M {nx} {ny-36} L {nx-15} {ny+16} L {nx} {ny+5} L {nx+15} {ny+16} Z" fill="#c1621b"/>')
add(f'<text class="lbl" x="{nx}" y="{ny+50}">N</text>')

bx, by = M, IMG_H - 78
add(f'<line class="dl" x1="{bx:.1f}" y1="{by:.1f}" x2="{bx+3*S:.1f}" y2="{by:.1f}"/>')
for i in range(4):
    add(f'<line class="dl" x1="{bx+i*S:.1f}" y1="{by-6:.1f}" x2="{bx+i*S:.1f}" y2="{by+6:.1f}"/>')
    add(f'<text class="note" x="{bx+i*S:.1f}" y="{by+27:.1f}" style="text-anchor:middle">{i}</text>')
add(f'<text class="note" x="{bx+3*S+20:.1f}" y="{by+7:.1f}">m</text>')

ly = IMG_H - 150
add(f'<text class="note" x="{M:.1f}" y="{ly}">图例：黑色粗线 = 墙体　橙色弧线 = 平开门（弧线为开启方向）　橙色错位双线 = 推拉门　蓝色双线 = 窗　灰色横线 = 楼梯踏步　浅灰填充 = 厨卫湿区</text>')
add(f'<text class="note" x="{M:.1f}" y="{ly+24:.1f}">底边 2.5 厨房 / 3.4 餐厅·客厅 / 3.5 楼梯间 / 3.8 卧室；x=2.5 那道墙同时定厨房与主卫宽；主卧开间 3.8、向右下伸至与主卫底边齐平。</text>')

add('</svg>')

with open("/home/zyw/Downloads/dl-hub/36-户型图绘制/房屋平面图.svg", "w", encoding="utf-8") as f:
    f.write("\n".join(out))
print("svg ok", IMG_W, IMG_H)
