fix(shape): 꺾임점 계단면을 미터면과 일치시킨다
계단 경계를 꺾임점에 맞춰도 각 구간의 계단면은 자기 축에 직각이고 미터면은 θ/2 기울어, 코핑 폭 안에서 ±(B/2)·tan(θ/2) (P11 ±0.12 m)의 삼각형 조각이 남았다. 꺾임점의 계단면을 각 구간 프로파일에서 미터 퍼짐 + 10 mm만큼 잘려 나가는 쪽으로 옮겨, 구간 0은 앞 상면을, 구간 1은 뒤 상면을 미터면까지 가져가게 한다. 3D와 도면 투영이 모두 미터면으로 자르므로 둘 다 반영된다. 퍼짐이 블럭 반폭 이상이면 바꾸지 않는다. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a39a1ba8d2
commit
9f336e2be4
2 files changed
+36
-3
No files matched your search
+10
-3
@@ -405,6 +405,13 @@ export function buildPier(input: PierInput, ctx: PierContext = {}): PierModel {
|
||||
};
|
||||
// Each stretch uses the same outline shifted to its own base; the mitre plane trims the overlap at the kink.
|
||||
const shifted = (pts: [number, number][], b: number): [number, number][] => pts.map(([s, z]) => [s - b, z]);
|
||||
// A step at the kink (2026-11-10): each stretch's step face is square to its own axis, the mitre is not, so the face
|
||||
// moves past the mitre spread (B/2)·tan(θ/2) into the trimmed side: stretch 0 keeps its left top up to the mitre and
|
||||
// stretch 1 its right top back to it, and the visible step is the mitre plane itself (no sliver on either half).
|
||||
const mitreSpread = (B / 2) * Math.tan((Math.abs(ip4.angleDeg) * Math.PI) / 360) + 0.01;
|
||||
const atKink = (pts: [number, number][], k: number): [number, number][] =>
|
||||
kinkG === null || mitreSpread >= halfBlock ? pts
|
||||
: pts.map(([s, z]) => [Math.abs(s - kinkG) < 1e-9 ? kinkG + (k === 0 ? mitreSpread : -mitreSpread) : s, z]);
|
||||
|
||||
const meanN = (rows: { n: number }[]) => rows.reduce((sum, r) => sum + r.n, 0) / rows.length;
|
||||
const copingParts: CopingPart[] = [];
|
||||
@@ -424,11 +431,11 @@ export function buildPier(input: PierInput, ctx: PierContext = {}): PierModel {
|
||||
// side of its own row; the order stays [front, back].
|
||||
const frontLow = (fRows.length && bRows.length ? meanN(fRows) - meanN(bRows) : meanN(frontPlaced) - meanN(backPlaced)) <= 0;
|
||||
copingParts.push(
|
||||
{ k, nFrom: frontLow ? -planHalfB : nStep, nTo: frontLow ? nStep : planHalfB, profile: shifted(outline(segments), base[k]) },
|
||||
{ k, nFrom: frontLow ? nStep : -planHalfB, nTo: frontLow ? planHalfB : nStep, profile: shifted(outline(backSegments), base[k]) },
|
||||
{ k, nFrom: frontLow ? -planHalfB : nStep, nTo: frontLow ? nStep : planHalfB, profile: shifted(atKink(outline(segments), k), base[k]) },
|
||||
{ k, nFrom: frontLow ? nStep : -planHalfB, nTo: frontLow ? planHalfB : nStep, profile: shifted(atKink(outline(backSegments), k), base[k]) },
|
||||
);
|
||||
} else {
|
||||
copingParts.push({ k, nFrom: -planHalfB, nTo: planHalfB, profile: shifted(outline(segments), base[k]) });
|
||||
copingParts.push({ k, nFrom: -planHalfB, nTo: planHalfB, profile: shifted(atKink(outline(segments), k), base[k]) });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user