"""Atividade — Aros Olímpicos com a Pilha de Matrizes (ponto de partida). Aula 04 — Instanciamento e Transformações Geométricas 2D. Execute com: python aros2d_matrizes_base.py A janela, o contexto e a projeção já estão prontos. ``_desenhar_aro`` também já está pronta — e é DIFERENTE da versão da Aula 03 (aros2d_base.py): não recebe ``cx, cy``, só ``raio`` e ``cor``. Ela desenha sempre em torno da própria origem; quem decide onde cada aro aparece na tela é a matriz corrente no momento em que ela é chamada, não mais a conta dentro da função. Cada TODO corresponde a um passo do roteiro publicado na página da aula. Guarde ``aros2d_solucao.py`` da Aula 03 ao lado deste arquivo: a comparação entre os dois é o próprio objetivo da atividade. `Esc` fecha a janela. """ from __future__ import annotations import math import sys from PySide6.QtCore import Qt from PySide6.QtGui import QSurfaceFormat from PySide6.QtWidgets import QApplication from PySide6.QtOpenGLWidgets import QOpenGLWidget from OpenGL.GL import * from OpenGL.GLU import gluOrtho2D MUNDO = 50.0 RAIO = 13.0 LADOS = 64 ESPESSURA = 6.0 DX = 27.0 TOPO_Y = 7.0 BASE_Y = -6.0 AZUL = (0.00, 0.51, 0.78) PRETO = (0.00, 0.00, 0.00) VERMELHO = (0.93, 0.20, 0.31) AMARELO = (0.99, 0.69, 0.19) VERDE = (0.00, 0.65, 0.32) # TODO 2 — preencha com as cinco tuplas (cx, cy, cor), reaproveitando as # posições e as cores que você já validou na Aula 03. Aqui (cx, cy) é só o # CENTRO de cada aro — nenhuma conta de vértice depende dele. AROS: list[tuple[float, float, tuple[float, float, float]]] = [] class Aros2D(QOpenGLWidget): """Os cinco aros olímpicos, desenhados com a pilha de matrizes.""" def initializeGL(self) -> None: # O símbolo pede fundo claro: o aro preto some no escuro (Aula 03). glClearColor(1.0, 1.0, 1.0, 1.0) def resizeGL(self, w: int, h: int) -> None: w, h = max(1, w), max(1, h) glViewport(0, 0, w, h) glMatrixMode(GL_PROJECTION) glLoadIdentity() if w <= h: gluOrtho2D(-MUNDO, MUNDO, -MUNDO * h / w, MUNDO * h / w) else: gluOrtho2D(-MUNDO * w / h, MUNDO * w / h, -MUNDO, MUNDO) glMatrixMode(GL_MODELVIEW) glLoadIdentity() @staticmethod def _desenhar_aro(raio: float, cor: tuple[float, float, float]) -> None: """Um aro centrado na PRÓPRIA ORIGEM — não recebe cx, cy. Compare com ``_desenhar_aro`` da Aula 03: lá o centro era somado a cada vértice; aqui não há centro nenhum para somar. Quem posiciona o aro é a matriz corrente quando esta função é chamada. """ glColor3f(*cor) glBegin(GL_LINE_LOOP) for k in range(LADOS): ang = 2.0 * math.pi * k / LADOS glVertex2f(raio * math.cos(ang), raio * math.sin(ang)) glEnd() def paintGL(self) -> None: glClear(GL_COLOR_BUFFER_BIT) glLineWidth(ESPESSURA) # TODO 3 — para cada (cx, cy, cor) de AROS: empilhe a matriz, # translade para (cx, cy), desenhe o aro com _desenhar_aro(RAIO, cor) # e desempilhe. Releia o Exemplo 3 da aula se travar na ordem das # chamadas. def keyPressEvent(self, event) -> None: if event.key() == Qt.Key.Key_Escape: self.close() def main() -> int: fmt = QSurfaceFormat() fmt.setVersion(2, 1) fmt.setProfile(QSurfaceFormat.OpenGLContextProfile.NoProfile) fmt.setDepthBufferSize(0) QSurfaceFormat.setDefaultFormat(fmt) app = QApplication(sys.argv) janela = Aros2D() janela.setWindowTitle("Atividade — Aros Olímpicos com a Pilha de Matrizes") janela.resize(760, 480) janela.show() return app.exec() if __name__ == "__main__": raise SystemExit(main())