글목록

2022년 3월 12일

PowerPoint 매크로 - 그림, 도형 정렬/배열하기 (3) - 순서 정하기

아래와 같이 그림이 무작위로 배열되어 있는 경우, 사람은 대충 3x2 배열로 하는 것이 좋겠다고 쉽게 생각할 수 있습니다. 그러나, 이러한 배열은 인접한 도형간 간격이 분포를 통계적으로 계산해보면, 그림과 같이 4x2 배열에서, 윗줄의 오른쪽 끝과 아래쪽에 각 1개씩 빠진 형태에 더 가깝습니다.

(배열 전)



(배열 후)



또한 어떤 사람은 3x2 배열을 필요로 하는 사람이 있고, 어떤 사람은 6x1, 2x3, 4x2 등의 배열로 만들고 싶어할 수도 있습니다. 따라서, 컴퓨터는 적절한 배열 상태를 추전해줄 수는 있으나, 최종 판단은 사용자가 해야 하며, 사용자가 배열 크기를 지정해주면, 가장 근접한 위치에 있는 개체를 찾아서 배열해주기만 하면 됩니다.

배열하려는 위치와 가로, 세로 분할 갯수가 지정되면, 격자점이 자동으로 지정되기 때문에, 각 도형과 격자점이 가장 근접한 도형을 찾아서 배열해주면 쉽게 해결될 것 같습니다만, 사용자가 그림을 배열할 때, 보이지 않는 격자점의 위치에 잘 갖다 놓는 것이 생각보다 쉽지 않습니다.

예를 들어, 아래와 같은 경우를 보겠습니다.


6개의 그림을 빨간 점선으로 된 박스 안에 3x2 배열로 배치하고 싶다고 했을 때, 각 격자점과 가장 가까운 도형들을 배치하는 방식으로 하게 된다면, 2번과 6번 그림은 순서가 바뀌거나, 원하지 않는 위치에 배치가 됩니다. 만약 빨간 점선 박스의 위치가 현재 도형 위치가 전혀 다른 곳이라고 한다면 격자점과 도형 간의 거리를 계산하는 방식으로는 도형 배치가 되지 않습니다. 따라서, 현재의 도형 배열을 파악할 때, 상대 위치 혹은 배치된 순서로부터 재배열할 위치를 지정해주어야 합니다.

우선, 현재 그림 배열 상태에서 그림 간의 상대적인 위치 또는 순서를 파악하기 위해 각 그림들의 위치 정보를 읽어온 후 순서를 지정해주어야 합니다. (본 글에서는 각 그림의 중심점 위치 정보를 가지고 그림 위치로 판단하였습니다.)

각각의 위치 정보를 X(i), Y(i)에 파악해두었다면, 왼쪽으로부터 1번째, 2번째,... 그림이 어떤 것인지 알 수 있도록 순서를 정해주어야 합니다. 예를 들어, 위의 그림에서 3번 삼각형은 '왼쪽에서 5번째, 위에서 3번째에 있는 그림'이라는 정보를 파악해야 합니다.

순서를 정하기 위해서는 정렬 기능이 필요합니다. 정렬 알고리즘은 엑셀 매크로를 위해 이미 소개해드린 정렬함수를 사용하시면 됩니다. 다만, 엑셀에서 사용하기 위해 만든 함수이기 때문에 input/output 형식이 Double 형식의 데이터입니다만, Variant나 Single 형태로 선언을 바꿔 주기만 하면 됩니다. 여기에서는 Varitant 형태로 바꾸어 사용하도록 하겠습니다.

링크의 정렬함수를 이용하더라도 각 도형의 순서는 바로 얻을 수는 없습니다. 따라서, 아래와 같이 직관적인 도형의 순서를 얻을 수 있도록 함수를 하나 추가해줍니다.

'-------------------------------------------
Function GetRank(iData(), Optional iIncrease As Boolean = True) As Variant()
  Dim tRank(), tOrder(), i As Long, j As Long, n As Long
  ReDim tRank(LBound(iData) To UBound(iData))
  tOrder = GetSorted(iData, True, iIncrease, False)
  For i = LBound(iData) To UBound(iData)
    tRank(tOrder(i)) = i - LBound(iData) + 1
  Next
  GetRank = tRank
  Erase tRank, tOrder
End Function

'-------------------------------------------


정렬함수와 함께 위의 함수를 조합하게 되면, 그림들의 좌/우 순서, 상/하 순서를 각각 구할 수 있게 됩니다. 예를 들어, 위의 그림에서 1~6번 그림에 대해, 좌우로 1~6번, 상하로 1~6번의 번호를 갖도록 해줍니다.

다음글에서는 그림의 순서로부터 가로, 세로 줄에 배치하기 위해 그룹화하는 함수를 만들도록 하겠습니다.

많이 본 글 :