Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
10 views

Colisiones Python OpenGL

The document describes a practical implementation of collision detection using the Separating Axis Theorem (SAT) in a 2D graphics context. It includes source code for rendering various shapes and handling their rotations and movements, while ensuring they do not overlap during interactions. The code also features functions for shape initialization, transformation, and collision checking between shapes based on their vertices and axes.

Uploaded by

Emilio Chávez
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

Colisiones Python OpenGL

The document describes a practical implementation of collision detection using the Separating Axis Theorem (SAT) in a 2D graphics context. It includes source code for rendering various shapes and handling their rotations and movements, while ensuring they do not overlap during interactions. The code also features functions for shape initialization, transformation, and collision checking between shapes based on their vertices and axes.

Uploaded by

Emilio Chávez
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

PRACTICA 3: COLISIONES.

Me base en el método SAT que estaba en los recursos, investigué un poco


mas y lo implemente al anterior de rotaciones.

Básicamente una vez separadas las figuras ya no puedo volver a juntarlas,


es una desventaja del método.
CÓDIGO FUENTE:

from OpenGL.GL import *


from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
import math

ShapeID = 0
jump = 0.05
rotation_jump = 15.0
rotations = {
1: 0.0, 2: 0.0, 3: 0.0, 4: 0.0,
5: 0.0, 6: 0.0, 7: 0.0
}
rotation_direction = 1
positions = {
1: [0.0, 0.0],
2: [0.0, 0.0],
3: [0.25, 0.25],
4: [0.0, 0.0],
5: [0.0, 0.0],
6: [-0.25, -0.25],
7: [0.5, 0.0]
}

shape_vertices = {}
shape_centroids = {}

def BlueTriangle():
inc = 0.5
vertices = [(0.0, 0.0), (-inc, inc), (inc, inc)]
centroid = (0.0, inc * 2/3)
glColor3f(0.0, 1.0, 1.0)
glBegin(GL_TRIANGLES)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def RedTriangle():
inc = 0.5
vertices = [(0.0, 0.0), (-inc, -inc), (-inc, inc)]
centroid = (-inc * 2/3, 0.0)
glColor3f(1.0, 0.0, 0.0)
glBegin(GL_TRIANGLES)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def GreenTriangle():
inc = 0.25
vertices = [(0.0, 0.0), (inc, inc), (inc, -inc)]
centroid = (inc * 2/3, 0.0)
glColor3f(0.0, 1.0, 0.0)
glBegin(GL_TRIANGLES)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def YellowSquare():
inc = 0.25
vertices = [(0.0, 0.0), (inc, inc), (2.0 * inc, 0.0), (inc, -inc)]
centroid = ((0.0 + 2.0*inc)/2, (0.0 + 0.0)/2) # = (inc, 0.0)
glColor3f(1.0, 1.0, 0.0)
glBegin(GL_QUADS)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def PinkTriangle():
inc = 0.25
vertices = [(0.0, 0.0), (inc, -inc), (-inc, -inc)]
centroid = (0.0, -inc * 2/3)
glColor3f(1.0, 0.0, 0.5)
glBegin(GL_TRIANGLES)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def WhiteRhomboid():
inc = 0.25
vertices = [(0.0, 0.0), (2.0 * inc, 0.0), (inc, -inc), (-inc, -inc)]
centroid = ((0.0 + inc)/2, (0.0 - inc)/2) # (inc/2, -inc/2)
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_QUADS)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def NavyTriangle():
inc = 0.5
vertices = [(0.0, 0.0), (0.0, -inc), (-inc, -inc)]
centroid = (-inc / 3, -inc * 2/3) # Revisado
glColor3f(0.3, 0.6, 1.0)
glBegin(GL_TRIANGLES)
for v in vertices: glVertex2f(*v)
glEnd()
return vertices, centroid

def init_shapes():
global shape_vertices, shape_centroids
shape_vertices[1], shape_centroids[1] = BlueTriangle()
shape_vertices[2], shape_centroids[2] = RedTriangle()
shape_vertices[3], shape_centroids[3] = GreenTriangle()
shape_vertices[4], shape_centroids[4] = YellowSquare()
shape_vertices[5], shape_centroids[5] = PinkTriangle()
shape_vertices[6], shape_centroids[6] = WhiteRhomboid()
shape_vertices[7], shape_centroids[7] = NavyTriangle()

def GetCentroid(shape_id):
return shape_centroids.get(shape_id, (0.0, 0.0))

def DrawShape(shape_id):
if shape_id == 1: BlueTriangle()
elif shape_id == 2: RedTriangle()
elif shape_id == 3: GreenTriangle()
elif shape_id == 4: YellowSquare()
elif shape_id == 5: PinkTriangle()
elif shape_id == 6: WhiteRhomboid()
elif shape_id == 7: NavyTriangle()
def DrawScene():
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
for shape_id, (x, y) in positions.items():
centroid_x, centroid_y = GetCentroid(shape_id)
glPushMatrix()
glTranslatef(x, y, 0.0)
glTranslatef(centroid_x, centroid_y, 0.0)
glRotatef(rotations[shape_id], 0.0, 0.0, 1.0)
glTranslatef(-centroid_x, -centroid_y, 0.0)
DrawShape(shape_id)
glPopMatrix()
glutSwapBuffers()

def get_transformed_vertices(shape_id, pos=None, rot=None):


if pos is None:
pos = positions[shape_id]
if rot is None:
rot = rotations[shape_id]

base_vertices = shape_vertices[shape_id]
centroid = shape_centroids[shape_id]
angle_rad = math.radians(rot)
cos_a = math.cos(angle_rad)
sin_a = math.sin(angle_rad)

transformed = []
for vx, vy in base_vertices:
vx_c = vx - centroid[0]
vy_c = vy - centroid[1]
vx_rot = vx_c * cos_a - vy_c * sin_a
vy_rot = vx_c * sin_a + vy_c * cos_a
vx_rc = vx_rot + centroid[0]
vy_rc = vy_rot + centroid[1]
final_x = vx_rc + pos[0]
final_y = vy_rc + pos[1]
transformed.append((final_x, final_y))
return transformed
def get_axes(vertices):
axes = []
for i in range(len(vertices)):
p1 = vertices[i]
p2 = vertices[(i + 1) % len(vertices)]
edge_x = p2[0] - p1[0]
edge_y = p2[1] - p1[1]
normal_x = -edge_y
normal_y = edge_x
mag = math.sqrt(normal_x**2 + normal_y**2)
if mag != 0:
axes.append((normal_x / mag, normal_y / mag))
return axes

def project_polygon(axis, vertices):


min_proj = float('inf')
max_proj = float('-inf')
for vx, vy in vertices:
projection = vx * axis[0] + vy * axis[1]
min_proj = min(min_proj, projection)
max_proj = max(max_proj, projection)
return min_proj, max_proj

def check_collision(shape_id1, shape_id2, pos1=None, rot1=None,


pos2=None, rot2=None):
verts1 = get_transformed_vertices(shape_id1, pos1, rot1)
verts2 = get_transformed_vertices(shape_id2, pos2, rot2)
axes1 = get_axes(verts1)
axes2 = get_axes(verts2)

for axis in axes1 + axes2:


min1, max1 = project_polygon(axis, verts1)
min2, max2 = project_polygon(axis, verts2)
if max1 < min2 or max2 < min1:
return False
return True

def handle_key(key, x, y):


global ShapeID, rotation_direction
if isinstance(key, bytes):
key = key.decode("utf-8")
if key.isdigit():
new_id = int(key)
if new_id in positions:
ShapeID = new_id

if ShapeID in positions:
if key == 'r':
potential_rotation = rotations[ShapeID] + rotation_direction *
rotation_jump
collides = False
for other_id in positions:
if other_id != ShapeID:
if check_collision(ShapeID, other_id, rot1=potential_rotation):
collides = True
break
if not collides:
rotations[ShapeID] = potential_rotation % 360 # Mantener en 0-
360
glutPostRedisplay()
elif key == 'd':
rotation_direction *= -1

def handle_special_key(key, x, y):


global ShapeID
if ShapeID in positions:
current_x, current_y = positions[ShapeID]
potential_x, potential_y = current_x, current_y
if key == GLUT_KEY_UP:
potential_y += jump
elif key == GLUT_KEY_DOWN:
potential_y -= jump
elif key == GLUT_KEY_RIGHT:
potential_x += jump
elif key == GLUT_KEY_LEFT:
potential_x -= jump
else:
return
potential_pos = [potential_x, potential_y]
collides = False
for other_id in positions:
if other_id != ShapeID:
if check_collision(ShapeID, other_id, pos1=potential_pos):
collides = True
break
if not collides:
positions[ShapeID] = potential_pos
glutPostRedisplay()

def init():
glClearColor(0.1, 0.1, 0.1, 1.0)
gluOrtho2D(-1.5, 1.5, -1.125, 1.125)
init_shapes()

def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(800, 600)
glutCreateWindow(b"Tangram 2D")
init()
glutDisplayFunc(DrawScene)
glutKeyboardFunc(handle_key)
glutSpecialFunc(handle_special_key)
glutMainLoop()

if __name__ == "__main__":
main()

You might also like