Получить обновленные координаты вращающегося кинетического тела пиманка

Ниже показано вращающееся кинетическое тело пимунка с массой внутри. Есть ли способ получить среднюю точку верхней горизонтальной части body_type после начала воспроизведения анимации. Изначально интересующая меня точка на кинетическом теле имеет координаты (400 500). Как распечатать обновленные координаты рассматриваемой точки после начала вращения

import pymunk
import pymunk.pygame_util
import pygame

GRAY = (220, 220, 220)

width_mass=50
height_mass=50

pygame.init()
size = 800,600
screen = pygame.display.set_mode(size)
draw_options = pymunk.pygame_util.DrawOptions(screen)

space = pymunk.Space()
space.gravity = (0,-50)

pts = [(-27, -238.5), (27,-238.5), (27,238.5), (-27,238.5)]
body_type=pymunk.Body(body_type=pymunk.Body.KINEMATIC)  
body_type.position = (400, 263.5)  
space.add(body_type)
for i in range(4):
    segment = pymunk.Segment(body_type, pts[i], pts[(i+1)%4], 2)
    segment.elasticity = 0
    segment.friction=0
    space.add(segment)

body_type.angular_velocity=1

body = pymunk.Body(mass=1, moment=100)
body.position = 400,400

mass = pymunk.Poly.create_box(body, (width_mass, height_mass))
mass.elasticity = 0
space.add(body, mass)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            #pygame.image.save(screen, 'intro1.png')

    screen.fill(GRAY)
    space.debug_draw(draw_options)
    pygame.display.update()
    space.step(0.01)

person Ken Morison    schedule 25.10.2020    source источник


Ответы (1)


Текущая позиция Body хранится в атрибуте position. (например, space.bodies[0].position).
PyGame использует систему координат, в которой верхний левый угол равен (0, 0). Система координат PyGame, ось Y направлена ​​вниз.

running = True
while running:
    # [...]

    # draw a dot in at the center of the bodies
    for body in space.bodies:
        pos = body.position
        pygame.draw.circle(screen, (255,0,0), (pos[0], screen.get_height()-pos[1]), 7)

    pygame.display.update()
    space.step(0.01)

Текущий угол Body хранится в атрибуте angle. (например, body_type.angle).
Текущее положение точки можно вычислить, добавив повернутое относительное положение к абсолютному положению. Повернутое положение можно вычислить с помощью простой тригонометрии:

pos = abs_pos[0] + rel_dist * math.cos(angle), abs_pos[1] + rel_dist * math.sin(angle)

Сначала вам нужно вычислить относительные полярные координаты из относительных Декартовы координаты:

rel_pos = (0, 238.5)
rel_dist, rel_angle = math.hypot(*rel_pos), math.atan2(rel_pos[1], rel_pos[0])

Добавьте текущий угол к углу в полярных координатах:

angle = rel_angle + body_type.angle

Например:

running = True
while running:
    # [...]

    abs_pos = body_type.position
    rel_pos = (0, 238.5)
    rel_dist, rel_angle = math.hypot(*rel_pos), math.atan2(rel_pos[1], rel_pos[0])
    
    angle = rel_angle + body_type.angle
    pos = abs_pos[0] + rel_dist * math.cos(angle), abs_pos[1] + rel_dist * math.sin(angle)
    pygame.draw.circle(screen, (255, 255, 0), (pos[0], screen.get_height() - pos[1]), 7)

    pygame.display.update()
    space.step(0.01)

Минимальный пример:

import pymunk
import pymunk.pygame_util
import pygame
import math

GRAY = (220, 220, 220)
width_mass=50
height_mass=50
pygame.init()

size = 800,600
screen = pygame.display.set_mode(size)
draw_options = pymunk.pygame_util.DrawOptions(screen)

space = pymunk.Space()
space.gravity = (0,-50)

pts = [(-27, -238.5), (27,-238.5), (27,238.5), (-27,238.5)]
body_type=pymunk.Body(body_type=pymunk.Body.KINEMATIC)  
body_type.position = (400, 263.5)  
space.add(body_type)
for i in range(4):
    segment = pymunk.Segment(body_type, pts[i], pts[(i+1)%4], 2)
    segment.elasticity = 0
    segment.friction=0
    space.add(segment)

body_type.angular_velocity=0.5

body = pymunk.Body(mass=1, moment=100)
body.position = 400,400

mass = pymunk.Poly.create_box(body, (width_mass, height_mass))
mass.elasticity = 0
space.add(body, mass)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            #pygame.image.save(screen, 'intro1.png')

    screen.fill(GRAY)
    space.debug_draw(draw_options)

    for body in space.bodies:
        pos = body.position
        pygame.draw.circle(screen, (255, 0, 0), (pos[0], screen.get_height() - pos[1]), 7)

    abs_pos = body_type.position
    rel_pos = (0, 238.5)
    rel_dist, rel_angle = math.hypot(*rel_pos), math.atan2(rel_pos[1], rel_pos[0])
    angle = rel_angle + body_type.angle
    print( body_type.position.angle)
    pos = abs_pos[0] + rel_dist * math.cos(angle), abs_pos[1] + rel_dist * math.sin(angle)
    pygame.draw.circle(screen, (255, 255, 0), (pos[0], screen.get_height() - pos[1]), 7)

    pygame.display.update()
    space.step(0.01)
person Rabbid76    schedule 25.10.2020