メインコンテンツまでスキップ

境界線分 — 壁がどこに立つか

壁を置く操作は存在しない。壁の位置は、二つの空間の凸片の関係から現れる。boundary の一行が言うのは「この二つのあいだに何があるか」であって、線がどこを走るかではない。

form.boundaries[0].segment
// { x1: 3600, y1: 0, x2: 3600, y2: 4500, horizontal: false, edgeOfA: "E" }

一つの境界は線分を複数持ちうるForm は線分ごとに一つの FormBoundary を持ち、どれも同じ ref を共有する。

辺の方位

凸片の反時計回りの頂点列を一周し、軸に平行な辺だけを読む。

進む向き
+xS
−xN
+yE
−yW

したがって N = +Y、S = −Y、E = +X、W = −X の面を指す。斜めの辺は方位を持たない。

二つの辺が「向かい合う」とは、方位が互いに逆 (N↔S / E↔W) であり、かつ固定座標の差が EPS 以下であることをいう。

edgeOfAa 側(先に書いた空間)から見た方位である。boundary /L1/a /L1/bboundary /L1/b /L1/a は同じ関係の二つの綴りだが、edge: が指す辺は逆になる。

線分の導出 — 順序が意味を持つ

境界の線分は次の順で決まる。先に当たった枝で決着する。

  1. 両端のどちらかの空間が存在しなければ、線分は無い
  2. typestair / shaft / void なら線分は無い(垂直の境界は壁を持たない)
  3. 描かれた線があれば、それが境界の実現である。共線マージも edge: の絞り込みも掛からない
  4. 両側が領域を持つなら共有辺。レベルが違えば線分は無い(異なるレベル間に壁は立たない)
  5. 片側だけが領域を持つなら外周。相手は「同じレベルの、この二空間以外のすべての空間の領域」である
  6. どちらも領域を持たなければ線分は無い

4 と 5 の結果には共線マージを掛け、最後に edge: があれば「a 側から見た辺」で絞る。

共有辺

A の各凸片の軸平行な辺と B の各凸片の辺のうち、向かい合っていて重なる区間を持つものを取る。重なりが EPS 以下なら共有辺にならない — 点接触は接触ではない。線分は座標の昇順に向き、a 側から見た方位を持つ。

外周

各凸片の各辺から、向かい合う相手の辺が覆う区間を引いた残りである。同じ空間の他の凸片も相手に数えるので、L 字を二矩形で書いても内部の継ぎ目に壁は立たない。相手を引く順序は結果に影響しない。

外周は複数の辺に割れる。だから外部への開口を置くには edge:N/E/S/W で辺を選ぶ必要がある(OPN05)。

共線マージ

同じ直線上に並ぶ線分を一本にまとめる。まとめる単位は (向き・固定座標・a 側から見た方位) の三つ組で、固定座標は厳密に一致していなければならない。同じ組の中で座標の昇順に並べ、隙間が EPS 以下なら伸ばし、超えたら切る。

背中合わせの辺は併合されない。同じ直線上に N の辺と S の辺があっても、方位が違うので別の線分のままである。

マージがあるおかげで、複数の矩形にまたがる一枚の窓を一つの線分の上に置ける。

描かれた線が実現する区間

一本の設計線は複数の境界に共有される。貫通通路の壁は、その前を通る区画の数だけ境界を持つ。各境界が線の全長を実現すると、平面には同じ壁が何本も重なる。

そうならないよう、線は両空間の凸片の辺で切られ、各区間の中点から法線方向へ探り距離 PROBE(5mm)だけ離れた二点を取り、左右がちょうど a と b になっている区間だけを残す。片側が領域を持たない相手なら、持つ側が片側だけに居ることで境界になる。この判定は a と b について対称である。

PROBE形の解像度の下限である — この幅を下回る空間は左右のどちらにも判定できず、境界の線分が一本も出ない。

出力の線分は正準の端点の順(解決座標の昇順)を保ち、a 側から見た方位を持たない。したがって line を持つ境界に edge: を書いても効かない。

通行可能性

線分の有無と、人が通れるかは別の話である。

type通れるか
wall扉があるときだけ。window では通れない
open常に通れる
stair常に通れる(垂直の通行)
shaft通れない — 空間としては連続するが人は通らない
void通れない — 床が無い

air:1遮蔽の話であって通行の話ではない。扉の無い手すり壁は wall + air:1 なので、自動的に通れない。

passable(boundary) がこれを返す。合否は言わない — 「外へ出られるか」は判定の面が別に答える。

外皮の穴

空間の外周のうち、他の空間とも、宣言された外部境界とも向かい合っていない区間がある。これが外皮の穴である。envelopeGaps(model, space) が線分として返す。

接する空間の既定は壁だが、領域を持たない空間(外部)との境界は導出されない — 相手の名指しが情報だからである。だから外部への boundary の書き忘れは、黙って壁の不在になる。check はこれを言わない。言うのは判定の面envelope.gap である。

隣り合う頁