Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 96 additions & 0 deletions dataset/scenarios/scenario1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import pygame
import pymunk
import pymunk.pygame_util
import cv2
import datetime
import os

def setup_pygame():
"""Inicializa o Pygame e a tela."""
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Cenario 1")
return screen, pygame.time.Clock()

def create_scenario(space):
"""Cria o chão estático do cenário."""
body_chao = pymunk.Body(body_type=pymunk.Body.STATIC)
segment_chao = pymunk.Segment(body_chao, (0, 550), (800, 550), 5)
segment_chao.elasticity = 0.9
segment_chao.friction = 1.0
space.add(body_chao, segment_chao)

def add_ball_at_mouse_position(space, pos):
"""Adiciona uma nova bola no espaço, na posição do mouse."""
massa = 1
raio = 15
inercia = pymunk.moment_for_circle(massa, 0, raio)
bola_body = pymunk.Body(massa, inercia)
bola_body.position = pos
bola_shape = pymunk.Circle(bola_body, raio)
bola_shape.elasticity = 0.9
bola_shape.friction = 0.8
space.add(bola_body, bola_shape)

def run_simulation_and_record():
"""Roda a simulação e grava um vídeo."""
screen, clock = setup_pygame()

# Gerar um nome de arquivo unico com data e hora
timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
video_filename = f"cenario1:{timestamp}.mp4"

# Salva o vídeo na pasta 'videos', um nivel acima da atual
video_path = os.path.join(os.path.dirname(__file__), '..', 'videos', video_filename)

FPS = 60
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(video_path, fourcc, FPS, (800, 600))

# Configurar o espaço do Pymunk
space = pymunk.Space()
space.gravity = 0, 980
draw_options = pymunk.pygame_util.DrawOptions(screen)

# Criar o cenário (o chão)
create_scenario(space)

running = True
while running:
# Gerenciamento de eventos
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
# Ao clicar, adiciona uma bola
add_ball_at_mouse_position(space, event.pos)

# Limpar a tela
screen.fill((255, 255, 255))

# Desenhar os objetos do Pymunk
space.debug_draw(draw_options)

# Atualizar a simulação
space.step(1 / 60.0)

# Atualizar a tela do Pygame
pygame.display.flip()

# Gravar o quadro atual para o vídeo
img_array = pygame.surfarray.array3d(screen)
img_array = cv2.cvtColor(img_array.swapaxes(0, 1), cv2.COLOR_RGB2BGR)
out.write(img_array)

# Controlar o FPS
clock.tick(60)

# Liberar o gravador e fechar o Pygame
out.release()
pygame.quit()
print(f"Vídeo salvo como {video_path}")

# Executar a simulação e a gravação
if __name__ == "__main__":
run_simulation_and_record()
136 changes: 136 additions & 0 deletions dataset/scenarios/scenario2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import pygame
import pymunk
import pymunk.pygame_util
import cv2
import numpy as np
import datetime
import os

def setup_pygame():
"""Inicializa o Pygame e a tela."""
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("Cenario 2")
return screen, pygame.time.Clock()

def add_ball(space, pos):
"""Adiciona uma nova bola no espaco."""
massa = 1
raio = 15
inercia = pymunk.moment_for_circle(massa, 0, raio)
bola_body = pymunk.Body(massa, inercia)
bola_body.position = pos
bola_shape = pymunk.Circle(bola_body, raio)
bola_shape.elasticity = 0.9
bola_shape.friction = 0.8
space.add(bola_body, bola_shape)

def add_box(space, pos):
"""Adiciona uma nova caixa no espaco."""
massa = 1
size = 30
inercia = pymunk.moment_for_box(massa, (size, size))
caixa_body = pymunk.Body(massa, inercia)
caixa_body.position = pos
caixa_shape = pymunk.Poly.create_box(caixa_body, (size, size))
caixa_shape.elasticity = 0.5
caixa_shape.friction = 0.7
space.add(caixa_body, caixa_shape)

def create_static_segment(space, points):
"""Cria uma superficie estatica a partir de uma lista de pontos."""
if len(points) < 2:
return

for i in range(len(points) - 1):
p1 = points[i]
p2 = points[i+1]
static_body = pymunk.Body(body_type=pymunk.Body.STATIC)
segment = pymunk.Segment(static_body, p1, p2, 5)
segment.elasticity = 0.95
segment.friction = 0.8
space.add(static_body, segment)

# --- Loop Principal de Simulação e Gravação ---
def run_simulation_and_record():
"""Roda a simulação e grava um vídeo."""
screen, clock = setup_pygame()

timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
video_filename = f"cenario2:{timestamp}.mp4"
video_path = os.path.join(os.path.dirname(__file__), '..', 'videos', video_filename)

FPS = 60
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(video_path, fourcc, FPS, (800, 600))

space = pymunk.Space()
space.gravity = 0, 980
draw_options = pymunk.pygame_util.DrawOptions(screen)

drawing_mode = False
drawing_points = []
current_object_type = 'ball'

running = True
while running:
# Gerenciamento de eventos
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1:
if current_object_type == 'ball':
add_ball(space, event.pos)
elif current_object_type == 'box':
add_box(space, event.pos)
elif event.button == 3:
drawing_mode = True
drawing_points.append(event.pos)
elif event.type == pygame.MOUSEBUTTONUP:
if event.button == 3:
drawing_mode = False
if len(drawing_points) > 1:
create_static_segment(space, drawing_points)
drawing_points = []
elif event.type == pygame.MOUSEMOTION:
if drawing_mode:
drawing_points.append(event.pos)
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_b:
current_object_type = 'ball'
elif event.key == pygame.K_q:
current_object_type = 'box'

# Adiciona multiplos objetos
mouse_buttons = pygame.mouse.get_pressed()
keys = pygame.key.get_mods()
if mouse_buttons[0] and keys & pygame.KMOD_SHIFT:
if current_object_type == 'ball':
add_ball(space, pygame.mouse.get_pos())
elif current_object_type == 'box':
add_box(space, pygame.mouse.get_pos())

# Limpar a tela
screen.fill((255, 255, 255))

if drawing_mode and len(drawing_points) > 1:
pygame.draw.lines(screen, (0, 0, 0), False, drawing_points, 2)

space.debug_draw(draw_options)
space.step(1 / 60.0)

pygame.display.flip()

img_array = pygame.surfarray.array3d(screen)
img_array = cv2.cvtColor(img_array.swapaxes(0, 1), cv2.COLOR_RGB2BGR)
out.write(img_array)

clock.tick(60)

out.release()
pygame.quit()
print(f"Vídeo salvo como {video_path}")

if __name__ == "__main__":
run_simulation_and_record()
67 changes: 67 additions & 0 deletions dataset/scenarios/scenarios.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Cenários para criação do dataset

## Cenário 1: Bola e chão

> Esse cenário foca em testar colisões, gravidade e perda de energia. Ele foi projetado para ser interativo, proporcionando uma variedade de possibilidades de simulação.

### 1. Objetivos

- Verificar o comportamento de objetos em queda livre.

- Testar a colisão com uma superfície estática (chão) e com outros objetos (bolas dinâmicamente inseridas)

- Analisar o quique e a perda de energia (elasticidade).

### 1. Objetos

1. **Chão (Objeto estático)**: O chão é a única superfície estática do cenário, agindo como a principal barreira de colisão. Sua elasticidade e fricção podem ser alteradas em código para simular diferentes superfícies.

2. **Bolas (Objetos dinâmicos)**: As bolas são os objetos dinâmicos do cenário, e podem ser criadas com um clique do mouse esquerdo. Sua massa, raio, elasticidade e fricção podem ser alterados em código. Além de colidirem com o chão, as bolas podem colidir entre si, o que permite a análise de colisões entre corpos dinâmicos e reações em cadeia.

### 1. Interação com o usuário

A principal forma de interação com o usuário é por meio da adição de bolas usando o mouse. Essa interação permite fazer várias aplicações do mesmo cenário, contribuindo para a geração de um dataset mais diversificado. Clicando com o botão esquerdo do mouse, será adicionada uma nova bola na posição que o mouse se encontra.

### 1. Saída em forma de vídeo

Dado que o objetivo dos cenários é criar um dataset, a simulação foi configurada para gravar um vídeo, desde o início até o momento em que a janela é fechada. O vídeo é salvo automaticamente com o nome `cenario1: data`, em que a "data" se refere ao dia e horário que a simulação foi salva. A simulação é salva na pasta `videos` em formato .mp4

### 1. Conclusão

A diversidade do dataset pode ser alcaçada ao juntar a interação com o usuário mencionada e a alteração dos objetos da simulação. Dessa forma, esse cenário é uma forma flexível de testar colisões simples, gravidade e perda de energia.

## Cenário 2: Bolas e obstáculos

> Esse cenário foca em testar a interação entre múltiplos objetos e colisões com superfícies mais complexas e dinâmicas, que podem ser criadas pelo próprio usuário.

### 2. Objetivos

- Testar a física de colisão em superfícies não-planas (como rampas e curvas)

- Analisar a interação entre diferentes formas de objetos (círculos e quadrados).

- Avaliar a dinâmica de empilhamento e dispersão de um grande número de objetos.

### 2. Objetos

1. Obstáculos e Superfícies (Objetos Estáticos): Dessa vez, as superfícies estáticas são definidas diretamente pelo usuário, e atuam como paredes e obstáculos, com propriedades de elasticidade e fricção ajustáveis.

2. Bolas e quadrados (Objetos Dinâmicos): O cenário agora suporta dois tipos de formas dinâmicas, que podem ser alternadas pelo usuário. A adição dos quadrados proporciona uma interação mais complexa, podendo deslizar ou tombar ao interagir com os obstáculos.

### 2. Interação com o usuário

A interação com o usuário é mais presente nesse cenário. Nele, podemos realizar:

- Desenho Livre: Clique e arraste o botão direito do mouse para desenhar superfícies estáticas livres. Ao soltar o botão, o desenho é finalizado e se torna uma barreira de colisão.

- Criar objetos: pressione `b` para selecionar o modo "bolas" ou `q` para selecionar o modo "quadrados". Apertar o botão esquerdo do mouse cria um objeto selecionado novo.

- Criação em massa: Segurar o botão `Shift` enquanto aperta o botão esquerdo do mouse cria múltiplos objetos simultaneamente.

### 2. Saída em forma de vídeo

Novamente, a saída é salva em formato de vídeo com o dia e horario da simulação, e fica armazenado na pasta `videos` sob o formato .mp4

### 2. Conclusão

A adição de obstáculos dinâmicos determinados pelo usuário, a funcionalidade de criação em massa e a possibilidade de simular mais uma forma geométrica contribuem para a flexibilidade do cenário, o que ajudará na criação do dataset futuramente.
Binary file added dataset/videos/cenario1:2025-09-14_14-32-13.mp4
Binary file not shown.
Binary file added dataset/videos/cenario2:2025-09-14_14-46-55.mp4
Binary file not shown.