2

i got the rotating of the triangle down with this functions

def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = (dx * scale / len, dy * scale / len) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts

but then i use another function to get the middle of the triangle with the formula (Ax + Bx + Cx)/3

def getCenter(self):
        # formula: (Ax + Bx + Cx)/3
        x = (self.x1 + self.x2 + self.x3)/3
        y = (self.y1 + self.y2 + self.y3)/3
        return (x, y)

here is where the two functions get called

def update(self):
        # point to mouse
        mouseP = pygame.mouse.get_pos()
        center = self.getCenter(mouseP)
        points = self._rotate(center, 12, mouseP)
        self.x1 = points[0][0]
        self.x2 = points[1][0]
        self.x3 = points[2][0]
        self.y1 = points[0][1]
        self.y2 = points[1][1]
        self.y3 = points[2][1]

and the move function

def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x1 -= self.vel
            self.x2 -= self.vel
            self.x3 -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x1 += self.vel
            self.x2 += self.vel
            self.x3 += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y1 -= self.vel
            self.y2 -= self.vel
            self.y3 -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y1 += self.vel
            self.y2 += self.vel
            self.y3 += self.vel

with all of that this happens https://streamable.com/1mfibu im using pygame

blorbee
  • 23
  • 2

2 Answers2

0

So you calculate the center using position values. Then rotate the points using that center and assign the result back to position values. This makes the values increase over time. You need to save those rotated points in a different variable to the one that stores original position values. Here is a working example. It directly returns the rotated points and draws them.

import pygame, math

class Tri:
    def __init__(self):
        self.x1 = self.x2 = self.x3 = 300
        self.y1 = self.y2 = self.y3 = 300
        self.vel = 0.05
    
    def getCenter(self):
        # formula: (Ax + Bx + Cx)/3
        x = (self.x1 + self.x2 + self.x3)/3
        y = (self.y1 + self.y2 + self.y3)/3
        return (x, y)

    def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x1 -= self.vel
            self.x2 -= self.vel
            self.x3 -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x1 += self.vel
            self.x2 += self.vel
            self.x3 += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y1 -= self.vel
            self.y2 -= self.vel
            self.y3 -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y1 += self.vel
            self.y2 += self.vel
            self.y3 += self.vel

    def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = ((dx / len) * scale, (dy / len) * scale) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts

    def update(self):
        # point to mouse
        mouseP = pygame.mouse.get_pos()
        center = self.getCenter()
        points = self._rotate(center, 12, mouseP)
        return points
        
    def getpoints(self):
        return self.update()

window = pygame.display.set_mode((600, 600))
tri = Tri()

while True:
    pygame.event.pump()
    
    tri.move()

    window.fill((255, 255, 255))
    pygame.draw.polygon(window, (0, 0, 0), tri.getpoints())
    pygame.display.flip()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
0

The problem is, that (0, 0) is not the center of the triangle with the points:

[(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]

(0, 0) is the center of the equilateral triangle:

a = math.sqrt(3)/2 # ~ 0.866 
[(-0.5, -a), (-0.5, a), (1.0, 0.0)]

or the center of the trianlge

[(-0.525, -0.866), (-0.525, 0.866), (1.05, 0.0)]

Since you calculate the center of the triangle in each frame, the triangle is shifted by the distance from (0, 0) to the center of the triangle with the points [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)] in every frame.


There is no need to move the 3 corner points of the triangle and to coumpute the center of the triangle. Save and move only the center of the triangle. (self.x, self.y). The 3 corner points can be calculated form the center point and the direction of the triangle:

import pygame
import math

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

class Triangle:
    def __init__(self, x, y):
        self.x, self.y = x, y 
        self.vel = 5
        self.points = []

    def _rotate(self, center, scale, mouse_pos):
        dx = mouse_pos[0] - center[0]
        dy = mouse_pos[1] - center[1]
        len = math.sqrt(dx * dx + dy * dy)
        dx, dy = (dx * scale / len, dy * scale / len) if len > 0 else (1, 0)

        pts = [(-0.5, -0.866), (-0.5, 0.866), (1.1, 0.0)]
        pts = [(center[0] + p[0] * dx + p[1] * dy, center[1] + p[0] * dy - p[1] * dx) for p in pts]
        return pts
    
    def update(self):
        mouseP = pygame.mouse.get_pos()
        self.points = self._rotate((self.x, self.y), 12, mouseP)

    def move(self):
        keys = pygame.key.get_pressed()

        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            self.x -= self.vel
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            self.x += self.vel
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.y -= self.vel
        if keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.y += self.vel
    def draw(self, surf):
        pygame.draw.polygon(surf, (255, 255, 255), self.points)

triangle = Triangle(200, 200)

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False      
    
    triangle.update()
    triangle.move()

    window.fill(0)
    triangle.draw(window)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
exit()

How to rotate a triangle to a certain angle in PyGame?
player turns in wrong direction if angle is negative

Rabbid76
  • 202,892
  • 27
  • 131
  • 174