alexanderd5398
alexanderd5398

Reputation: 327

Why is this way of finding the angle between two points so inaccurate?

I'm trying to get one sprite to intersect with another using angles. This is the function I've used, found online:

def findAngle(x,y,x2,y2):
    deltaX = x2 - x
    deltaY = y2 - y

    return math.atan2(deltaY,deltaX)

However, this is horribly inaccurate. When the two sprites are at around the same X, they are still usually 100-200 pixels away from eachother.

Here is my entire program for you to run yourself.

import pygame
import math

screen_size = screen_width,screen_height = 700,500
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()

BLACK   = (   0,   0,   0)
WHITE   = ( 255, 255, 255)
RED     = ( 255,   0,   0)
GREEN   = (   0, 255,   0)
BLUE    = (   0,   0, 255)

class Sprite(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)


class Particle(Sprite):
    def __init__(self,x,y,size):
        self.image = pygame.Surface((size,size))
        self.rect = pygame.Rect(x,y,size,size)

        self.angle = 0
        self.speed = 0

    def draw(self):

        self.rect.x -= math.cos(self.angle) * self.speed
        self.rect.y -= math.sin(self.angle) * self.speed
        pygame.draw.circle(screen, BLACK, (self.rect.x,self.rect.y), self.rect.width)

def findAngle(x,y,x2,y2):
    deltaX = x2 - x
    deltaY = y2 - y

    return math.atan2(deltaY,deltaX)

class main:

    p1 = Particle(100,100,16)
    p2 = Particle(600,400,5)

    p2.angle = findAngle(100,100,600,400)
    p2.speed = 2

    done = False
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    done = True

                if event.key == pygame.K_r:
                        pass

        pygame.display.init()
        screen.fill(WHITE)

        p1.draw()
        p2.draw()

        pygame.display.flip()
        clock.tick(60)
    pygame.display.quit()
    pygame.quit()

Upvotes: 0

Views: 514

Answers (2)

Foon
Foon

Reputation: 6433

P1 is at 100,100 and stationary P2 is at 600,400 and moving at an angle of ~30 degrees (or more accurately, -120 degrees since you're doing -= instead of +=.
If you swap cos and sin, Every frame, p2 moves -1.715 units in the X direction and -1.02 units in the Y direction. After it has moved 300 units in the Y (which would finish it), it should have moved 500 units in the X, which is what you're looking for.

Simplifying things to take pygame stuff:

import math

def findAngle(x,y,x2,y2):
    return math.atan2(y2-y,x2-x)

x = 600
y = 400
angle = findAngle(100,100,x,y)
dx = 2 * math.cos(angle)
dy = 2 * math.sin(angle)
while x > 100:
    x -= dx
    y -= dy
print "At end, we were at %f,%f"%(x,y)

This prints out: At end, we were at 99.224131,99.534479

Upvotes: 0

Justin
Justin

Reputation: 6711

You should use cos for the x-coordinate and sin for the y-coordinate. You have it backward in the draw function.

Upvotes: 1

Related Questions