Search code examples
pythonpython-3.xpygamerotationradius

Python pygame - center axis rotation segment line


import sys, pygame
from math import sin, cos, radians, pi
from pygame.locals import QUIT, MOUSEBUTTONDOWN

pygame.init()
SURFACE = pygame.display.set_mode((780,920))
FPSCLOCK = pygame.time.Clock()

def Line():
    speed = 0

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        if pygame.mouse.get_pressed() [0]:
            speed += 26
            if speed > 60:
                speed = 60

        else:
            speed -= 15
            if speed < 0:
                speed = 0

        SURFACE.fill((255,0,0))

        radius = speed * 0.8
        
        pygame.draw.line(SURFACE,(5,80,255),(295,127),(sin(200-radius),cos(300-radius)),8)
        pygame.display.update()
        FPSCLOCK.tick(6)

if __name__ == '__main__' :
    Line()

I am trying to code a line segment that rotates counterclockwise about a central axis. It is difficult to understand. The end-pos part is difficult for me.


Solution

  • I recommend to use the pygame.math.Vector2.

    Define the center point, the radius, a direction vector of the line and an angle

    center_x, center_y = SURFACE.get_rect().center
    radius = 100
    line_vector = pygame.math.Vector2(1, 0)
    angle = 0
    

    Since you want to rotate counter clockwise, you need to decrement the angle when the mouse button is pressed:

    if pygame.mouse.get_pressed()[0]:
        angle -= 1
    

    Use pygame.math.Vector2.rotate() to rotate the direction vector and compute the rotated start and end point of the line

    rot_vector = line_vector.rotate(angle) * radius
    start = round(center_x + rot_vector.x), round(center_y + rot_vector.y)
    end = round(center_x - rot_vector.x), round(center_y - rot_vector.y)
    

    Use the start and end to draw the line:

    pygame.draw.line(SURFACE, (5,80,255), start, end, 8)
    

    Minimal Example: repl.it/@Rabbid76/PyGame-VectorRotateLine

    Complete example:

    import sys, pygame
    from math import sin, cos, radians, pi
    from pygame.locals import QUIT, MOUSEBUTTONDOWN
    pygame.init()
    SURFACE = pygame.display.set_mode((780,920))
    FPSCLOCK = pygame.time.Clock()
    
    def Line():
        center_x, center_y = SURFACE.get_rect().center
        radius = 100
        line_vector = pygame.math.Vector2(1, 0)
        angle = 0
        while True:
            for event in pygame.event.get():
                if event.type == QUIT:
                    pygame.quit()
                    sys.exit()
    
            if pygame.mouse.get_pressed()[0]:
                angle -= 1
                print(angle)
            
            rot_vector = line_vector.rotate(angle) * radius
            start = round(center_x + rot_vector.x), round(center_y + rot_vector.y)
            end = round(center_x - rot_vector.x), round(center_y - rot_vector.y)
           
            SURFACE.fill((255,0,0))
            pygame.draw.line(SURFACE, (5,80,255), start, end, 8)
            pygame.display.update()
            FPSCLOCK.tick(60)
    
    if __name__ == '__main__' :
        Line()
    

    If you want to rotate around the start point of a line, then you don't need the center point. Define the start of the line:

    start_x, start_y = SURFACE.get_rect().center
    length = 200
    

    Compute the rotated end point:

    rot_vector = line_vector.rotate(angle) * length
    start = start_x, start_y
    end = round(start_x + rot_vector.x), round(start_y + rot_vector.y)