파이썬 예제 (도형 회전)

오늘은 Python + PyQt5를 이용, 사각형의 회전을 구현해 봤습니다.

[사각형 회전]



우선, 어떤 도형(원, 삼각형, 사각형 등)을 회전하는 방법을 생각하면 가장 먼저 드는 생각은 아래와 같습니다.

  • 도형 중심 좌표를 기준으로 도형의 끝점들을 찾아 원하는 각도로 cos, sin 함수를 이용, 회전된 좌표를 찾아낸 후 다시 좌표를 직선으로 이어 그리는 방식
그런데 회전시켜야 할 도형이 많다거나, 글자 등도 회전시켜야 하는 경우는 모든 대상마다 적용해야 하므로 코드가 지저분해지기 쉽습니다.

하지만 Qt의 QPainter class를 이용하면 간편하게 좌표 회전이 가능합니다.

QPainter의 rotate() 함수를 이용하면, 내부적으로 행렬 연산(Matrix)을 통해 Coordinate System 자체를 회전시킵니다.

회전시킨 후 그림을 그리면 회전된 모습으로 그림이 그려지는 방식입니다.

[Qt 좌표변환, 출처 : Qt 홈페이지]

위 그림을 참조하면 회전, 이동, 확대, 축소까지 모두 가능한 것을 확인해 볼 수 있습니다.

그럼 소스 코드를 살펴보겠습니다.
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)

class CWidget(QWidget):

    def __init__(self):
        super().__init__()  
        self.deg = 0.0
        self.dia = 50
        self.rad = self.dia/2

        self.timer = QBasicTimer()

        self.initUI()

    def initUI(self):        
       
        self.setGeometry(100,100,200,200)
        self.timer.start(10, self) # 10ms 마다
        self.show()

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        self.draw(qp)
        qp.end()

    def draw(self, qp):
        qp.setBrush(QColor(0,255,255,128))
        # 사각형 그리기                
        qp.translate(self.rect().center())        
        qp.rotate(360-self.deg)
        rect = QRectF(-self.rad,-self.rad,self.dia,self.dia)
        qp.drawRect(rect)
        qp.drawText(rect, Qt.AlignCenter, '돈다')
        qp.resetTransform() 

    def timerEvent(self, e):
        self.deg+=1
        self.update()

    def closeEvent(self, e):
        self.timer.stop()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = CWidget()
    sys.exit(app.exec_())

1. 먼저 위젯 생성 (사이즈 200x200)

2. 계속 회전하는 모습을 그려야 하므로 QBasicTimer 생성 (10ms 주기)

3. 매 10ms 주기마다 timerEvent() 함수호출

4. timerEvent() 함수호출 시, 각도 -1도 변경, update() 함수호출해 위젯 새로 그림

5. paintEvent() 함수에서 실제 도형을 그릴 draw() 함수 호출

6. QPainter translate(), 위젯 중심점 위치로 좌표계 이동

[이동]

7. QPainter rotate(), 좌표 회전
[회전]

8. QPainter drawRect(), 사각형 그리기
[회전된 좌표계에 그리기]

9. QPainter resetTransform(), 좌표계 초기화

   모든 translate(), rotate(), scale() 등 효과 리셋 처리


이상으로 코드 설명을 마칩니다.

C++ MFC 클래스를 사용해 본 경험이 있다면 Gdiplus의 Graphics와 거의 사용법이 같습니다.

감사합니다.

댓글

이 블로그의 인기 게시물

Qt Designer 설치하기

C++ 예제 (소켓 서버, 이미지, 파일전송)