How to detect that two bodies (in my case, balls) have touched while they are moving?

Asked

Viewed 75 times

0

I’m doing a program in python that simulates a small game of billiards (pool) and I’m having trouble finding a simple way to identify when the two balls touch, so I can change their direction. My code can be found at: https://py3.codeskulptor.org/#user304_IhC0l87Ss8kkIU2.py My code is like this:

import simplegui

# inicializa as variáveis globais
LARGURA = 600
ALTURA = 400
RAIO_BOLA = 20

#posições das bolas
ball_pos = [LARGURA / 3, ALTURA / 2]
ball_pos2 = [LARGURA - (RAIO_BOLA * 2) + 5, ALTURA / 2]

#velocidade das bolas
vel = [2, 2]
vel2 = [2, 2]

# define os event handlers
def draw(canvas):

    global ball_pos, vel,  ball_pos2, vel2

    # Atualiza a pisição da bola1
    ball_pos[0] = ball_pos[0] + vel[0]
    ball_pos[1] = ball_pos[1] + vel[1]

    # Atualiza a pisição da bola2
    ball_pos2[0] = ball_pos2[0] + vel2[0]
    ball_pos2[1] = ball_pos2[1] + vel2[1]

    reflexaoBola1() 
    reflexaoBola2()

    # Desenha as bolas
    canvas.draw_circle(ball_pos, RAIO_BOLA, 2, "white", "White")
    canvas.draw_circle(ball_pos2, RAIO_BOLA, 2, "blue", "blue")


def reflexaoBola1():
    global ball_pos, vel, ball_pos2, vel2

    # Reflexão com a parede a direita
    if ball_pos[0] > LARGURA - RAIO_BOLA:
        vel[0] = -1 * vel[0]

    # Reflexão com a parede a esquerda
    if ball_pos[0] < RAIO_BOLA:
        vel[0] = -1 * vel[0]

    # Reflexão com a parede em cima
    if ball_pos[1] > ALTURA - RAIO_BOLA:
        vel[1] = -1 * vel[1]

    # Reflexão com a parede em baixo
    if ball_pos[1] < RAIO_BOLA:
        vel[1] = -1 * vel[1]


def reflexaoBola2():
    global ball_pos, vel, ball_pos2, vel2

    # Reflexão com a parede a direita
    if ball_pos2[0] > LARGURA - RAIO_BOLA:
        vel2[0] = -1 * vel2[0]

    # Reflexão com a parede a esquerda
    if ball_pos2[0] < RAIO_BOLA:
        vel2[0] = -1 * vel2[0]

    # Reflexão com a parede em cima
    if ball_pos2[1] > ALTURA - RAIO_BOLA:
        vel2[1] = -1 * vel2[1]

    # Reflexão com a parede em baixo
    if ball_pos2[1] < RAIO_BOLA:
        vel2[1] = -1 * vel2[1]


# cria o frame
frame = simplegui.create_frame("Motion", LARGURA, ALTURA)

# registra os event handlers
frame.set_draw_handler(draw)

# inicia frame
frame.start()

If you rotate my code, you will see that the balls only collide with the walls instead of colliding with each other, I would like to solve that part

  • There’s no simple way, you have to use the mathematical formula yourself

  • 1

    Basically the distance between the centers of the circles (easy to calculate) has to be greater than the sum of the rays, if it is equal or smaller they are colliding

1 answer

0

Hello viva uses so although this solution only reflect the change of direction on the X axis, you can change how you want it to be, however with this function that I share will stop colliding as you wanted.

Flames this function in DRAW

def reflexaoEntreBolas():
    if (ball_pos2[0] - (RAIO_BOLA * 2)) <= ball_pos[0] <= (ball_pos2[0] + (RAIO_BOLA * 2)) and (ball_pos2[1] - (RAIO_BOLA * 2)) <= ball_pos[1] <= (ball_pos2[1] + (RAIO_BOLA * 2)):
        vel[0] = -1 * vel[0]
        vel2[0] = -1 * vel2[0]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.