오토캐드(AutoCAD) 위치 변경 없이 미러 시키는 리습

AutoCAD에서 도면에 위치한 블록이나 폴리선 객체를 미러(mirror)시키면 위치가 조금씩 변경되는데요. 미러 작업을 마치면 추가로 객체를 정렬해야 하는 불편함이 있습니다. 오늘은 위치 변경 없이 미러 시키는 리습을 작성해보겠습니다.

1. 위치 변경 없이 미러(mirror) 시키기 리습

AutoCAD에서 위치 변경 없이 미러(mirror)시키기 위해서 객체의 중심 위치를 선택해야 는데요. 객체 스냅에서 선택할 수 있는 “기하학적 중심”을 이용하면 위치 변경 없이 미러(대칭 복사)를 실행할 수 있습니다. 하지만 비대칭 형상의 객체는 기하학적 중심을 이용하더라도 미러 작업 후에 위치가 변경됩니다.
또한 “기하학적 중심”을 선택할 수 없는 객체는 미러 실행 후에 객체를 정렬해야 하는 불편함이 있습니다.

AUTOCAD-위치-변경-없이-미러-기하학적-중심

1) 미러(mirror) 리습 동작 설명

위치 변경 없이 정렬된 공간에서 미러(대칭 복사) 시키려면 선택한 객체의 중심점을 선택해야 하는데요. 이건 선택한 블록이나 폴리선의 가장 큰 X, Y 좌표값과 가장 작은 X, Y 좌표값을 구하면 해결할 수 있습니다. 연산 과정을 거쳐 중심점을 구했다면 Command 구문을 통해 위치 변경 없이 미러(mirror)를 실행할 수 있습니다.

2) 미러(mirror) 리습 구문 및 설명

▼ 리습 구동을 위해 시스템 변수와 객체 선택을 설정합니다. 미러(대칭 복사)를 실행하기 위한 객체는 폴리선, 블록으로 지정합니다. 구문 해석을 위한 주석을 달아놓았으니 참고하세요.

; 오토캐드 명령을 로드합니다.
  (vl-load-com)
  ; 명령 에코를 끕니다.
  (SETVAR "CMDECHO" 0)
  ; 현재 osmode를 저장합니다.
  (setq now_osmode (getvar "osmode"))
  ; osmode를 0으로 설정합니다.
  (setvar "osmode" 0 )
  ; LWPOLYLINE 유형의 객체를 선택합니다.
  (setq objs (ssget '((0 . "LWPOLYLINE,INSERT"))))
  ; 객체 수를 초기화합니다.
  (setq n 0)
  ; 모든 선택된 객체에 대해 반복합니다.

▼ “Repeat 함수 구문입니다. 선택한 객체의 수만큼 반복하도록 구성하였습니다. “(vlax-ename->vla-object entname)”은 VLA 함수를 사용하기 위해 도면 요소의 이름을 VLA 객체로 변환합니다. 사용빈도가 높은 구문으로 자세히 살펴보시기 바랍니다.

“vla-getboundingbox” 함수를 통해 변수 vlentname의 좌하단 좌표와 우상단 좌표를 minpoint, maxpoint 변수에 저장합니다. 여기서 추출되는 좌표의 순서(좌하단, 우상단)를 잘 기억해 두시기 바랍니다.

(vlax-safearray->list minpoint) 구문은 추출된 좌표를 리습에서 사용할 수 있는 리스트 형태의 좌표로 변환합니다. 추출된 좌표는 X 좌표와 Y 좌표를 분리하여 리스트를 작성하는데요. 여기서 X, Y 좌표를 분리하여 작성하는 이유는 다음 구문을 살펴보면 이해할 수 있습니다.

  (repeat (sslength objs)
    ; 객체의 이름을 가져옵니다.
    (setq entname (ssname objs n))
    ; VLAX-ENAME을 사용하여 도면요소 이름을 VLA 객체로 변환
    (setq vlentname (vlax-ename->vla-object entname))
    ; vlentname의 좌측하단 = minpoint 우측상단 = maxpoint 포인트를 출력
    (vla-getboundingbox vlentname 'minpoint 'maxpoint)
    ; 좌하단 점(minpoint)를 좌표로 변경, 변경된 좌표는 lowleftpoint 변수에 저장
    (setq lowleftpoint (vlax-safearray->list minpoint))
    ; 좌하단 좌표의 x좌표를 분리
    (setq lowleftpointx (car lowleftpoint))
    (setq lowleftpointxlist (cons lowleftpointx lowleftpointxlist))
    (setq lowleftpointy (cadr lowleftpoint))
    (setq lowleftpointylist (cons lowleftpointy lowleftpointylist))
    ; 우상단 점을 가져와서 X 및 Y 좌표로 분리
    (setq uprightpoint (vlax-safearray->list maxpoint))
    (setq uprightpointx (car uprightpoint))
    (setq uprightpointxlist (cons uprightpointx uprightpointxlist))
    (setq uprightpointy (cadr uprightpoint))
    (setq uprightpointylist (cons uprightpointy uprightpointylist))
    ; 객체 인덱스 증가
    (setq n (1+ n))
  )

▼ 이제 위에서 추출하여 분리된 X, Y 좌표 리스트를 오름차순 및 내림차순으로 정렬합니다. 위 구문에서 X, Y 좌표리스트를 따로 분리했는데요. 이건 각 좌표를 분리하여 비교 정렬하기 편리하게 데이터 형태로 나누기 위함이었습니다. 좌표 정렬을 위해 vl-sort 함수가 사용되었으며 등호(<,>)를 사용하여 내림차순, 오름차순으로 정렬합니다.

  ; 좌하단 X 좌표 목록을 정렬, 좌하단 좌표의 작은 값을 찾기 위해 오름차순으로 정렬
  (setq lowleftpointxlist (vl-sort lowleftpointxlist '<))
  ; 좌하단 Y 좌표 목록을 정렬
  (setq lowleftpointylist (vl-sort lowleftpointylist '<))
  ; 우상단 X 좌표 목록을 정렬, 우상단 좌표의 큰 값을 찾기 위해 내림차순으로 정렬함
  (setq uprightpointxlist (vl-sort uprightpointxlist '>))
  ; 우상단 Y 좌표 목록을 정렬
  (setq uprightpointylist (vl-sort uprightpointylist '>))

▼ 구해진 가장 큰 X, Y 좌표와 가장 작은 X, Y 좌표를 연산하여 중심점을 구합니다. 사용한 공식은 아래 구문에서 살펴보시기 바랍니다. 이제 계산된 좌표를 리스트로 저장하면 객체의 중심이 되는 점을 구할 수 있습니다.
이제 미러를 실행하기 위한 Command 구문을 작성합니다. 이때 중심점은 자동으로 선택되도록 구성하였으며, 추가로 선택하는 2번째 점은 사용자의 입력을 받을 수 있도록 “pause” 명령을 사용하였습니다. 미러 작업을 마치면 원본 객체는 삭제됩니다.

(setq pointx (/ (+ (nth 0 lowleftpointxlist) (nth 0 uprightpointxlist))2))
(setq pointy (/ (+ (nth 0 lowleftpointylist) (nth 0 uprightpointylist))2))
(setq point (list pointx pointy))
  ; 미러를 실행합니다.
(command "mirror" objs "" point pause "y"))
  ; 이전 osmode로 복원합니다.
  (setvar "osmode" now_osmode)
  (PRINC)

3) 미러(mirror) 리습 동작

아래 영상은 비대칭 블록을 미러 리습을 이용하여 위치 이동 없이 정렬하는 영상입니다. 명령어 “mib”를 입력하고 객체를 선택하면 미러(mirror)를 실행합니다. 리습을 통해 계산된 중심점은 미러 첫 점으로 사용되며, 두 번째 점은 사용자의 입력을 받습니다. 두 번째 점을 선택할 때 직교모드(F8)를 사용하면 추가로 정렬 작업이 필요 없이 미러 되는 것을 확인할 수 있습니다.

<미러 리습 작동법>
mib → 블록 및 폴리선 객체 선택 → Enter → 직교모드 실행(F8) →미러 위치 지정(두 번째 지점 선택)

4) 미러 리습 활용

블록이나 폴리선 객체의 중심점을 이용하면 다양한 작업에 활용할 수 있는데요. 아래 코드와 같이 Command 구문을 수정하면 객체의 중심을 이용한 회전(rotate) 작업을 할 수 있는 리습으로 변경할 수 있습니다.

<위치 이동 없이 회전하는 리습 command 구문>
(command "rotate" objs "" point pause))

Leave a Comment