feat(B07 CAD): 337-4b 다-2 늘이기 · 재기 · 치수 오토캐드 조작 — LENGTHEN · DIVIDE · MEASURE · DIST · DIM 류

- LENGTHEN 새 도구(lengthen-tool.ts) — 측정할 객체 [증분(DE)/퍼센트(P)/전체(T)] <마지막 방식> · 누름 = 현재 길이 알림 · 방식별 값 기억 · 변경할 객체 되풀이 · U = 이 명령 안 바꿈만 · 빈 Enter · Esc 끝 · 선 · 호
- DIVIDE · MEASURE — 기본값 없음 · 정수 2~32767 · 양수 · 블록(B) 없음 안내 · MEASURE 누른 끝부터
- DIST — 오토캐드 꼴 두 줄 기록(거리 · 각도 · 증분) · 다중 점(M) 없음 안내
- DIMLINEAR · DIMALIGNED — 빈 Enter = 객체 선택 · [문자(T)/수평(H)/수직(V)] · 치수 문자 = 기록 · 치수 객체 문자 바꿈 칸(<> = 잰 값)
- DIMCONTINUE · DIMBASELINE — 되풀이 · 명령 취소(U) · 빈 Enter 끝 · DIMRADIUS · DIMDIAMETER [문자(T)] · 그 밖 치수 물음 글
- 시험 measure-acad 11

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014utrjfoW831Vc5wJUd13kL
This commit is contained in:
2026-10-16 00:15:35 +09:00
co-authored by Claude Opus 5.5
parent 7c35341002
commit c15be5116a
8 changed files with 1022 additions and 148 deletions
@@ -1,6 +1,8 @@
/** 조회 명령 — 거리·반지름·각도·면적·좌표·리스트·계산기 (조사표 3절 유틸리티) */
import { Circle, type Point } from '@flatten-js/core';
import { toast } from 'react-toastify';
import type { OptionSpec } from '../../commands/prompt';
import { logLine } from '../../commands/run-command';
import { EntityName } from '../../entities/Entity';
import { entitiesToLoop } from '../../helpers/geometry/entity-loop';
import { polylineLength, sampleEntityPoints } from '../../helpers/geometry/sample-entity';
@@ -22,21 +24,30 @@ export function polygonArea(points: Point[]): number {
return Math.abs(total) / 2;
}
const MULTIPLE_POINTS: OptionSpec = { key: 'MULTIPLE', kw: 'M', en: 'MULTIPLE', label: '다중 점' };
/** DIST 결과 두 줄(오토캐드 꼴 · 길이 소수 넷 · 각도 AUPREC 0) */
export function distanceReport(first: Point, second: Point): [string, string] {
const dx = second.x - first.x;
const dy = second.y - first.y;
const angle = (toDegrees(Math.atan2(dy, dx)) + 360) % 360;
return [
`거리 = ${format(Math.hypot(dx, dy), 4)}, XY 평면에서의 각도 = ${Math.round(angle) % 360}, XY 평면으로부터의 각도 = 0`,
`X 증분 = ${format(dx, 4)}, Y 증분 = ${format(dy, 4)}, Z 증분 = ${format(0, 4)}`,
];
}
export const distanceToolStateMachine = createSequenceTool({
tool: Tool.DIST,
steps: [
{ kind: 'point', instructions: '거리를 잴 첫 점을 지정하십시오.' },
{ kind: 'point', instructions: '두 번째 점을 지정하십시오.' },
{ kind: 'point', prompt: { text: '첫 번째 점 지정' } },
{ kind: 'point', prompt: { text: '두 번째 점 지정', absent: [MULTIPLE_POINTS] } },
],
commit: (input) => {
const [first, second] = input.points();
const distance = first.distanceTo(second)[0];
const angle = toDegrees(Math.atan2(second.y - first.y, second.x - first.x));
toast.info(
`거리 ${format(distance)} · X 증분 ${format(second.x - first.x)} · Y 증분 ${format(
second.y - first.y
)} · 각도 ${format(angle, 2)}°`
);
const lines = distanceReport(first, second);
for (const line of lines) logLine(line);
toast.info(lines.join('\n'));
},
});