VBA에서 두 도형의 교차 혹은 충돌여부를 판단할 때
단순한 사각형의 경우 AABB 방식으로 두 도형의 좌표와 넓이와 높이를 비교해서 알아낼 수 있습니다.
하지만 도형이 회전한 경우나 사각형이 아닌 복잡한 도형의 경우 AABB방식은 실패합니다.
그래서 두 도형간에 선을 그어서 교차하는 점이 몇개인지 검사하거나 다른 복잡한 알고리즘들을 사용합니다.
두 도형간의 교차 여부를 알려주는 프로그램언어도 있지만
VBA에서는 도형의 충돌체크가 간단하지 않습니다.
이 경우
시간은 좀 걸릴 수 있지만
간단히 두 도형을 도형병합(교차)을 이용해서
교차시켜보고 나오는 도형이 있는지 검사해본다면
쉽게 충돌여부를 알아낼 수 있습니다.
(단, 도형병합을 지원하는 2010버전 이상이어야겠습니다.)
위의 그림에서 왼쪽 두 번개는 충돌하지 않고
오른쪽 두 번개는 약간의 교차도형이 발생해서 충돌로 판단이 됩니다.
Option Explicit
Sub Test()
Dim sr As ShapeRange
If ActiveWindow.Selection.Type <> ppSelectionShapes Then GoTo Err
Set sr = ActiveWindow.Selection.ShapeRange
If sr.Count <> 2 Then GoTo Err
MsgBox IIf(MergeTest(sr(1), sr(2)), "충돌!", "충돌하지 않음!")
Exit Sub
Err:
MsgBox "도형 충돌여부를 체크하려면 두 도형을 선택하세요."
End Sub
Function MergeTest(A As Shape, B As Shape) As Boolean
Dim sld As Slide
Dim AA As Shape, BB As Shape
Dim oldCnt As Long, newCnt As Long
Set sld = A.Parent
Set AA = A.Duplicate(1): DoEvents
AA.Left = A.Left
AA.Top = A.Top
Set BB = B.Duplicate(1): DoEvents
BB.Left = B.Left
BB.Top = B.Top
oldCnt = sld.Shapes.Count
'도형병합(교차하기)
sld.Shapes.Range(Array(AA.ZOrderPosition, BB.ZOrderPosition)).MergeShapes msoMergeIntersect
newCnt = sld.Shapes.Count
If newCnt = oldCnt - 1 Then
sld.Shapes(newCnt).Delete
MergeTest = True
Else
MergeTest = False
End If
End Function
도형병합 전의 도형개수와 도형병합 후의 도형개수를 비교하는 방법으로 검사합니다.
도형병합결과 연결되지 않은 복잡한 도형이 생기더라도 1개의 도형으로 생성되기 때문에 개수비교방식은 문제가 없습니다.
아래와 같이 여러가지 도형의 경우를 테스트를 해볼 수 있습니다.
첨부파일을 매크로 허용해서 열고 나서
(365버전의 경우 최초 1회 다운로드 받은 pptm 파일 속성에서 차단해제 체크하고 '확인' 클릭 필수)
원하는 두 개의 도형을 선택하고 Alt-F8 등으로 Test 매크로를 실행합니다.
단점은 두 도형을 매번 복제하고 교차도형이 생길 경우 삭제를 하게 되어 속도가 느려질 수 있다는 것입니다.
장점은 그 어떤 자유형 도형이라도 도형의 교차여부를 정확히 테스트할 수 있다는 것입니다.
특히 아래와 같은 경우도 충돌여부를 정확히 알 수 있습니다.
(파워포인트 내부적인 도형병합 알고리즘이 무척 궁금하긴 합니다.)
샘플 파일 첨부합니다.
'PPT+VBA' 카테고리의 다른 글
원둘레에 여러개의 원 그리기 (0) | 2022.09.05 |
---|---|
VBA로 이동경로 애니메이션 추가 (0) | 2022.08.30 |
연결된 차트의 시트변경시 연결 자동 복구 (0) | 2022.08.20 |
PPT의 표(테이블)를 엑셀시트에 일괄 복사 (0) | 2022.08.13 |
그룹도형, 차트, 스마트아트, 표 등의 텍스트 일괄 변경 (0) | 2022.08.08 |
[Chart Merge] 차트 복제하여 엑셀 데이터 일괄 반영 (0) | 2022.08.06 |
텍스트박스를 일괄 도형으로 변환하기 (0) | 2022.07.10 |
[Web Viewer 추가기능]온라인 구글문서 PPT슬라이드에 띄우기 (1) | 2022.06.24 |
최근댓글