01 - Desenhando um linha Manualmente¶
In [1]:
Copied!
# Código base para produzir o grid interativo
import sys
if 'google.colab' in sys.modules:
!pip install ipycanvas
from google.colab import output
output.enable_custom_widget_manager()
from ipycanvas import Canvas
import numpy as np
import ipywidgets as widgets
def cria_grid(d=(8,8), p=[], cor='#FF0000'):
# Grid size and cell size for a compact display
rows, cols = d
cell_size = 32
label_space = 22 # space for row/col numbers
canvas_width = cols * cell_size + label_space
canvas_height = rows * cell_size + label_space
# Create a blank grid
grid = np.zeros((rows, cols), dtype=int)
def draw_grid():
canvas.clear()
# Draw column numbers
canvas.font = '16px sans-serif'
canvas.fill_style = '#222'
for j in range(cols):
canvas.fill_text(str(j), label_space + j*cell_size + cell_size//2 - 6, label_space - 6)
# Draw row numbers
for i in range(rows):
canvas.fill_text(str(i), 2, label_space + i*cell_size + cell_size//2 + 6)
# Draw grid lines
for i in range(rows+1):
canvas.stroke_style = '#bbb'
canvas.stroke_line(label_space, label_space + i*cell_size, canvas_width, label_space + i*cell_size)
for j in range(cols+1):
canvas.stroke_style = '#bbb'
canvas.stroke_line(label_space + j*cell_size, label_space, label_space + j*cell_size, canvas_height)
# Draw painted cells
for i in range(rows):
for j in range(cols):
if grid[i, j] == 1:
canvas.fill_style = '#1976d2'
canvas.fill_rect(label_space + j*cell_size + 1, label_space + i*cell_size + 1, cell_size-2, cell_size-2)
# Draw start and end points
canvas.fill_style = cor
for point in p:
canvas.fill_rect(label_space + point[1]*cell_size + 1, label_space + point[0]*cell_size + 1, cell_size-2, cell_size-2)
canvas = Canvas(width=canvas_width, height=canvas_height)
draw_grid()
painting = [False]
def paint_cell(x, y):
col = int((x - label_space) // cell_size)
row = int((y - label_space) // cell_size)
if 0 <= row < rows and 0 <= col < cols:
if grid[row, col] == 0 and (row, col) not in p:
grid[row, col] = 1
draw_grid()
def on_mouse_down(x, y):
painting[0] = True
paint_cell(x, y)
def on_mouse_up(x, y):
painting[0] = False
def on_mouse_move(x, y):
if painting[0]:
paint_cell(x, y)
canvas.on_mouse_down(on_mouse_down)
canvas.on_mouse_up(on_mouse_up)
canvas.on_mouse_move(on_mouse_move)
# Button to clear grid
def clear_grid(_):
grid[:, :] = 0
draw_grid()
clear_btn = widgets.Button(description='Limpar grade')
clear_btn.on_click(clear_grid)
# Center the canvas using a Box with layout
centered = widgets.HBox([canvas], layout=widgets.Layout(justify_content='center'))
display(widgets.VBox([centered, clear_btn]))
# Código base para produzir o grid interativo
import sys
if 'google.colab' in sys.modules:
!pip install ipycanvas
from google.colab import output
output.enable_custom_widget_manager()
from ipycanvas import Canvas
import numpy as np
import ipywidgets as widgets
def cria_grid(d=(8,8), p=[], cor='#FF0000'):
# Grid size and cell size for a compact display
rows, cols = d
cell_size = 32
label_space = 22 # space for row/col numbers
canvas_width = cols * cell_size + label_space
canvas_height = rows * cell_size + label_space
# Create a blank grid
grid = np.zeros((rows, cols), dtype=int)
def draw_grid():
canvas.clear()
# Draw column numbers
canvas.font = '16px sans-serif'
canvas.fill_style = '#222'
for j in range(cols):
canvas.fill_text(str(j), label_space + j*cell_size + cell_size//2 - 6, label_space - 6)
# Draw row numbers
for i in range(rows):
canvas.fill_text(str(i), 2, label_space + i*cell_size + cell_size//2 + 6)
# Draw grid lines
for i in range(rows+1):
canvas.stroke_style = '#bbb'
canvas.stroke_line(label_space, label_space + i*cell_size, canvas_width, label_space + i*cell_size)
for j in range(cols+1):
canvas.stroke_style = '#bbb'
canvas.stroke_line(label_space + j*cell_size, label_space, label_space + j*cell_size, canvas_height)
# Draw painted cells
for i in range(rows):
for j in range(cols):
if grid[i, j] == 1:
canvas.fill_style = '#1976d2'
canvas.fill_rect(label_space + j*cell_size + 1, label_space + i*cell_size + 1, cell_size-2, cell_size-2)
# Draw start and end points
canvas.fill_style = cor
for point in p:
canvas.fill_rect(label_space + point[1]*cell_size + 1, label_space + point[0]*cell_size + 1, cell_size-2, cell_size-2)
canvas = Canvas(width=canvas_width, height=canvas_height)
draw_grid()
painting = [False]
def paint_cell(x, y):
col = int((x - label_space) // cell_size)
row = int((y - label_space) // cell_size)
if 0 <= row < rows and 0 <= col < cols:
if grid[row, col] == 0 and (row, col) not in p:
grid[row, col] = 1
draw_grid()
def on_mouse_down(x, y):
painting[0] = True
paint_cell(x, y)
def on_mouse_up(x, y):
painting[0] = False
def on_mouse_move(x, y):
if painting[0]:
paint_cell(x, y)
canvas.on_mouse_down(on_mouse_down)
canvas.on_mouse_up(on_mouse_up)
canvas.on_mouse_move(on_mouse_move)
# Button to clear grid
def clear_grid(_):
grid[:, :] = 0
draw_grid()
clear_btn = widgets.Button(description='Limpar grade')
clear_btn.on_click(clear_grid)
# Center the canvas using a Box with layout
centered = widgets.HBox([canvas], layout=widgets.Layout(justify_content='center'))
display(widgets.VBox([centered, clear_btn]))
- Desenhe uma linha usando o algoritmo de Bresenham, ligando os pontos A(3, 2) e B(9, 7). Use o mouse para pintar uma linha entre os dois pontos destacados na grade abaixo. Clique e arraste para "pintar" as células.
In [2]:
Copied!
cria_grid(d=(9, 13), p=[(2,3), (7,9)], cor='#43a047') # Call the function to display the grid
cria_grid(d=(9, 13), p=[(2,3), (7,9)], cor='#43a047') # Call the function to display the grid
VBox(children=(HBox(children=(Canvas(height=310, width=438),), layout=Layout(justify_content='center')), Butto…
- Novamente com o algoritmo de Bresenham, desenhe uma linha reta ligando os pontos C(2, 1) e D(4, 17).
In [ ]:
Copied!
cria_grid(d=(9, 13), p=[(2,1), (7,4)], cor='#e36047') # Call the function to display the grid
cria_grid(d=(9, 13), p=[(2,1), (7,4)], cor='#e36047') # Call the function to display the grid
- O resultado obtido no item 2 foi certamente muito pior do que o do item 1.
a) A que você atribui essa diferença?
b) Proponha uma alteração no algoritmo de forma a se obter um resultado satisfatório na linha do item 2.
c) Tente imaginar outras situações em que o algoritmo de Bresenham deveria ser adaptado para proporcionar um resultado satisfatório na construção de uma linha.