Python - Cálculos geométricos com finalidade de aplicação em renderização
Python - Cálculos geométricos | ||
Canal Qb |
Transformações geométricas: Implementação de rotações, translações e escalas em objetos geométricos para renderização em diferentes posições e tamanhos.
import numpy as npimport matplotlib.pyplot as plt# Função para realizar uma rotação de um ponto em torno de um ponto de referênciadef rotacionar_ponto(ponto, angulo, referencia):theta = np.radians(angulo)R = np.array([[np.cos(theta), -np.sin(theta)],[np.sin(theta), np.cos(theta)]])return np.dot(R, ponto - referencia) + referencia# Função para realizar uma translação em um pontodef transladar_ponto(ponto, dx, dy):return ponto[0] + dx, ponto[1] + dy# Função para realizar uma escala em um ponto em relação a um ponto de referênciadef escalar_ponto(ponto, escala, referencia):return referencia[0] + escala * (ponto[0] - referencia[0]), referencia[1] + escala * (ponto[1] - referencia[1])# Pontos do objeto geométricopontos = np.array([[1, 1],[2, 1],[2, 2],[1, 2],[1, 1]])# Rotação de 45 graus em torno do ponto (1.5, 1.5)referencia_rotacao = np.array([1.5, 1.5])angulo_rotacao = 45# Translação de (1, 1)dx = 1dy = 1# Escala de 1.5 em relação ao ponto (1.5, 1.5)referencia_escala = np.array([1.5, 1.5])escala = 1.5# Aplicar transformações geométricas aos pontospontos_rotacionados = np.array([rotacionar_ponto(ponto, angulo_rotacao, referencia_rotacao) for ponto in pontos])pontos_transladados = np.array([transladar_ponto(ponto, dx, dy) for ponto in pontos])pontos_escalados = np.array([escalar_ponto(ponto, escala, referencia_escala) for ponto in pontos])# Plotar os pontos originais e transformadosplt.plot(pontos[:, 0], pontos[:, 1], label='Original')plt.plot(pontos_rotacionados[:, 0], pontos_rotacionados[:, 1], label='Rotacionado')plt.plot(pontos_transladados[:, 0], pontos_transladados[:, 1], label='Transladado')plt.plot(pontos_escalados[:, 0], pontos_escalados[:, 1], label='Escalado')plt.legend()plt.xlabel('X')plt.ylabel('Y')plt.title('Transformações geométricas')plt.grid(True)plt.axis('equal')plt.show()
Projeções: Cálculo de projeções em perspectiva e ortográficas para transformar objetos 3D em 2D para renderização.
import numpy as npimport matplotlib.pyplot as plt# Função para realizar a projeção em perspectiva de um ponto 3D para um ponto 2Ddef projetar_ponto_perspectiva(ponto, distancia_projecao):fator = distancia_projecao / ponto[2]return ponto[0] * fator, ponto[1] * fator# Função para realizar a projeção ortográfica de um ponto 3D para um ponto 2Ddef projetar_ponto_ortografica(ponto):return ponto[0], ponto[1]# Pontos do objeto 3Dpontos_3d = np.array([[1, 1, 1],[2, 1, 1],[2, 2, 1],[1, 2, 1],[1, 1, 2],[2, 1, 2],[2, 2, 2],[1, 2, 2]])# Configurações de projeçãodistancia_projecao_perspectiva = 5# Aplicar projeções aos pontos 3Dpontos_2d_perspectiva = np.array([projetar_ponto_perspectiva(ponto, distancia_projecao_perspectiva) for ponto in pontos_3d])pontos_2d_ortografica = np.array([projetar_ponto_ortografica(ponto) for ponto in pontos_3d])# Plotar os pontos 2D resultantesfig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))ax1.plot(pontos_2d_perspectiva[:, 0], pontos_2d_perspectiva[:, 1], 'ro')ax1.set_title('Projeção em Perspectiva')ax1.set_xlabel('X')ax1.set_ylabel('Y')ax1.grid(True)ax1.axis('equal')ax2.plot(pontos_2d_ortografica[:, 0], pontos_2d_ortografica[:, 1], 'bo')ax2.set_title('Projeção Ortográfica')ax2.set_xlabel('X')ax2.set_ylabel('Y')ax2.grid(True)ax2.axis('equal')plt.tight_layout()plt.show()
Interseções de objetos: Cálculo de interseções entre objetos para evitar a sobreposição de polígonos na renderização.
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.patches import Polygon# Função para verificar se dois polígonos se intersectamdef poligonos_se_intersectam(poligono1, poligono2):polygon1 = Polygon(poligono1)polygon2 = Polygon(poligono2)return polygon1.intersects(polygon2)# Polígonos de exemplopoligono1 = np.array([[1, 1],[2, 1],[2, 2],[1, 2]])poligono2 = np.array([[1.5, 1.5],[2.5, 1.5],[2.5, 2.5],[1.5, 2.5]])poligono3 = np.array([[2, 1.5],[3, 1.5],[3, 2.5],[2, 2.5]])# Verificar interseções entre os polígonosintersecao_1_2 = poligonos_se_intersectam(poligono1, poligono2)intersecao_1_3 = poligonos_se_intersectam(poligono1, poligono3)intersecao_2_3 = poligonos_se_intersectam(poligono2, poligono3)# Imprimir resultadoprint("Interseção entre polígono 1 e polígono 2:", intersecao_1_2)print("Interseção entre polígono 1 e polígono 3:", intersecao_1_3)print("Interseção entre polígono 2 e polígono 3:", intersecao_2_3)# Plotar os polígonosfig, ax = plt.subplots()poligonos = [poligono1, poligono2, poligono3]cores = ['r', 'g', 'b']legendas = ['Polígono 1', 'Polígono 2', 'Polígono 3']for i, poligono in enumerate(poligonos):patch = Polygon(poligono, facecolor=cores[i], alpha=0.5)ax.add_patch(patch)ax.set_xlim([0, 4])ax.set_ylim([0, 4])ax.set_aspect('equal', 'box')ax.set_title('Interseções entre polígonos')ax.set_xlabel('X')ax.set_ylabel('Y')plt.legend(legendas)plt.grid(True)plt.show()
Sombreamento: Cálculo de sombreamento para simular a iluminação em um ambiente 3D.
import numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3D# Função para calcular o sombreamento em um ponto com base na posição da fonte de luzdef calcular_sombreamento(ponto, fonte_de_luz):vetor_normal = np.array([0, 0, 1]) # Vetor normal fixo para este exemplovetor_luz = fonte_de_luz - pontovetor_luz_normalizado = vetor_luz / np.linalg.norm(vetor_luz)sombreamento = np.dot(vetor_normal, vetor_luz_normalizado)return sombreamento# Pontos do objeto 3Dx = np.array([1, 2, 2, 1])y = np.array([1, 1, 2, 2])z = np.array([0, 0, 0, 0])# Posição da fonte de luzfonte_de_luz = np.array([0, 0, 5])# Calcular sombreamento para cada pontosombreamento = np.array([calcular_sombreamento(ponto, fonte_de_luz) for ponto in zip(x, y, z)])# Plotar o objeto 3D com sombreamentofig = plt.figure()ax = fig.add_subplot(111, projection='3d')# Plotar os pontos do objetoax.plot_trisurf(x, y, z, triangles=[[0, 1, 2], [0, 2, 3]], cmap='gray', shade=False)# Ajustar a cor dos triângulos com base no sombreamentoax.collections[0].set_facecolors(plt.cm.gray(sombreamento))# Configurações de visualizaçãoax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.set_title('Sombreamento em um ambiente 3D')ax.view_init(elev=20, azim=-45)plt.show()
Texturas: Implementação de texturas para aplicar padrões e imagens em objetos 3D para uma renderização mais realista.
import numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3D# Função para aplicar uma textura em um objeto 3Ddef aplicar_textura(objeto_3d, textura):objeto_3d.set_facecolor(textura)# Pontos do objeto 3Dx = np.array([1, 2, 2, 1])y = np.array([1, 1, 2, 2])z = np.array([0, 0, 0, 0])# Definir as coordenadas de texturau = np.array([0, 1, 1, 0])v = np.array([0, 0, 1, 1])# Carregar a imagem de texturatextura = plt.imread('exemplo_textura.jpg')# Plotar o objeto 3D com a texturafig = plt.figure()ax = fig.add_subplot(111, projection='3d')# Plotar os pontos do objetoobjeto_3d = ax.plot_trisurf(x, y, z, triangles=[[0, 1, 2], [0, 2, 3]], shade=False)# Aplicar a textura ao objeto 3Daplicar_textura(objeto_3d, textura)# Configurações de visualizaçãoax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.set_title('Texturas em um objeto 3D')plt.show()
Curvas e superfícies: Implementação de curvas e superfícies para criar objetos 3D complexos para renderização.
import numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3D# Função para criar uma superfície a partir de uma equação matemáticadef criar_superficie(equacao, intervalo_x, intervalo_y):x = np.linspace(intervalo_x[0], intervalo_x[1], 100)y = np.linspace(intervalo_y[0], intervalo_y[1], 100)X, Y = np.meshgrid(x, y)Z = equacao(X, Y)return X, Y, Z# Função para criar uma curva a partir de uma equação paramétricadef criar_curva(equacao_x, equacao_y, equacao_z, intervalo):t = np.linspace(intervalo[0], intervalo[1], 100)x = equacao_x(t)y = equacao_y(t)z = equacao_z(t)return x, y, z# Equações matemáticas para criar uma superfície e uma curvadef equacao_superficie(x, y):return np.sin(x) * np.cos(y)def equacao_curva_x(t):return np.cos(t)def equacao_curva_y(t):return np.sin(t)def equacao_curva_z(t):return t# Criação da superfícieintervalo_x = [-np.pi, np.pi]intervalo_y = [-np.pi, np.pi]X, Y, Z = criar_superficie(equacao_superficie, intervalo_x, intervalo_y)# Criação da curvaintervalo_curva = [-np.pi, np.pi]x_curva, y_curva, z_curva = criar_curva(equacao_curva_x, equacao_curva_y, equacao_curva_z, intervalo_curva)# Plotagem da superfície e da curvafig = plt.figure()ax = fig.add_subplot(111, projection='3d')# Plotar a superfícieax.plot_surface(X, Y, Z, cmap='viridis')# Plotar a curvaax.plot(x_curva, y_curva, z_curva, 'r')# Configurações de visualizaçãoax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.set_title('Curvas e Superfícies em um objeto 3D')plt.show()
Clipping: Implementação de clipping para recortar objetos que estão fora da área de visualização para aumentar a eficiência da renderização.
import numpy as npimport matplotlib.pyplot as plt# Função para realizar o clipping de um objeto em relação à janela de visualizaçãodef clipping(objeto, janela):objeto_recortado = []for i in range(len(objeto)):ponto_atual = objeto[i]ponto_proximo = objeto[(i + 1) % len(objeto)]if dentro_janela(ponto_atual, janela):objeto_recortado.append(ponto_atual)if cruzou_janela(ponto_atual, ponto_proximo, janela):ponto_intersecao = calcular_intersecao(ponto_atual, ponto_proximo, janela)objeto_recortado.append(ponto_intersecao)return objeto_recortado# Função para verificar se um ponto está dentro da janela de visualizaçãodef dentro_janela(ponto, janela):x, y = pontox_min, y_min, x_max, y_max = janelareturn x_min <= x <= x_max and y_min <= y <= y_max# Função para verificar se uma aresta cruza a janela de visualizaçãodef cruzou_janela(ponto1, ponto2, janela):x1, y1 = ponto1x2, y2 = ponto2x_min, y_min, x_max, y_max = janelaif (x1 < x_min and x2 > x_max) or (x1 > x_max and x2 < x_min):return Trueif (y1 < y_min and y2 > y_max) or (y1 > y_max and y2 < y_min):return Truereturn False# Função para calcular a interseção entre uma aresta e a janela de visualizaçãodef calcular_intersecao(ponto1, ponto2, janela):x1, y1 = ponto1x2, y2 = ponto2x_min, y_min, x_max, y_max = janelaif x1 != x2:m = (y2 - y1) / (x2 - x1)c = y1 - m * x1if x1 < x_min:x_intersecao = x_miny_intersecao = m * x_min + celse:x_intersecao = x_maxy_intersecao = m * x_max + celse:x_intersecao = x1if y1 < y_min:y_intersecao = y_minelse:y_intersecao = y_maxreturn [x_intersecao, y_intersecao]# Pontos do objeto a ser renderizadoobjeto = [[1, 1], [4, 1], [3, 4], [2, 4]]# Janela de visualização (área a ser mantida)janela = [2, 2, 3, 3]# Realizar o clipping do objeto em relação à janela de visualizaçãoobjeto_recortado = clipping(objeto, janela)# Plotar o objeto original e o objeto recortadofig, ax = plt.subplots()# Plotar o objeto originalx, y = zip(*objeto)ax.plot(x, y, 'b', label='Objeto Original')# Plotar o objeto recortadox_recortado, y_recortado = zip(*objeto_recortado)ax.plot(x_recortado, y_recortado, 'r', label='Objeto Recortado')# Plotar a janela de visualizaçãox_janela = [janela[0], janela[2], janela[2], janela[0], janela[0]]y_janela = [janela[1], janela[1], janela[3], janela[3], janela[1]]ax.plot(x_janela, y_janela, 'g--', label='Janela de Visualização')# Configurações de visualizaçãoax.set_xlim([0, 5])ax.set_ylim([0, 5])ax.set_aspect('equal')ax.set_xlabel('X')ax.set_ylabel('Y')ax.set_title('Clipping - Recorte de Objetos')# Legendaax.legend()plt.show()
Algoritmos de rasterização: Implementação de algoritmos de rasterização para converter objetos vetoriais em pixels para renderização em um dispositivo de exibição.
import numpy as npimport matplotlib.pyplot as plt# Função para realizar a rasterização de um polígonodef rasterizar_poligono(vertices):x_min, y_min = np.min(vertices, axis=0)x_max, y_max = np.max(vertices, axis=0)largura = int(x_max - x_min) + 1altura = int(y_max - y_min) + 1imagem = np.zeros((altura, largura), dtype=np.uint8)for i in range(len(vertices)):ponto_atual = vertices[i]ponto_proximo = vertices[(i + 1) % len(vertices)]x1, y1 = ponto_atualx2, y2 = ponto_proximodx = abs(x2 - x1)dy = abs(y2 - y1)if x1 < x2:sx = 1else:sx = -1if y1 < y2:sy = 1else:sy = -1erro = dx - dywhile True:imagem[int(y1 - y_min), int(x1 - x_min)] = 255if x1 == x2 and y1 == y2:breakerro_2 = 2 * erroif erro_2 > -dy:erro -= dyx1 += sxif erro_2 < dx:erro += dxy1 += syreturn imagem# Definição dos vértices do polígonovertices = np.array([[2, 1], [5, 4], [4, 7], [1, 6]])# Rasterização do polígonoimagem_rasterizada = rasterizar_poligono(vertices)# Plotagem da imagem rasterizadaplt.imshow(imagem_rasterizada, cmap='gray', origin='lower')# Configurações de visualizaçãoplt.xlabel('Pixels')plt.ylabel('Pixels')plt.title('Rasterização de um Polígono')plt.show()
Nenhum comentário
Comente só assim vamos crescer juntos!
Observação: somente um membro deste blog pode postar um comentário.