PyGameExamplesAndAnswers

StackOverflow            reply.it reply.it

“I’m a programmer. I like programming. And the best way I’ve found to have a positive impact on code is to write it.”
Robert C. Martin, Clean Architecture


Math and Vector

Euclidean distance an length

Related Stack Overflow questions:

Normalize

Related Stack Overflow questions:

The normalize() method computes a Unit vector. Therefore, the components of the vector are divided by the Euclidean length of the vector. If the length of the vector is 0, this causes division by 0.
normalize does not change the vector itself, but returns a new vector with the same direction but length 1. In compare normalize_ip normalizes the vector in place so that its length is 1.

if v.x != 0 or v.y != 0:
    new_vector.normalize_ip()

Angle between vectors and angle of arc

Related Stack Overflow questions:

In general, the angle of a vector (x, y) can be calculated by math.atan2(y, x). The vector can be defined by 2 points (x1, y1) and (x2, y2) on a line. Therefore the angle of the line is math.atan2(y2-y1, x2-x1). Be aware that the y-axis needs to be reversed (-y respectively y1-y2) because the y-axis is generally pointing up but in the PyGame coordinate system the y-axis is pointing down. The unit of the angle in the Python math module is Radian, but the unit of the angle in PyGame functions like pygame.transform.rotate() is Degree. Hence the angle has to be converted from Radians to Degrees by math.degrees:

import math

def angle_of_vector(x, y):
    return math.degrees(math.atan2(-y, x))

def angle_of_line(x1, y1, x2, y2):
    return math.degrees(math.atan2(-(y1-y2), x2-x1))

This can be simplified by using the angle_to method of the pygame.math.Vector2 object. This method computes the angle between 2 vectors in the PyGame coordinate system in degrees. Therefore it is not necessary to reverse the y-axis and convert from radians to degrees. Just calculate the angle between the vector and (1, 0):

def angle_of_vector(x, y):
    return pygame.math.Vector2(x, y).angle_to((1, 0))

def angle_of_line(x1, y1, x2, y2):
    return angle_of_vector(x2-x1, y2-y1)

📁 Minimal example - Calculate angle of vector animation

How to know the angle between two vectors?

angle_to can be used to calculate the angle between 2 vectors or lines:

def angle_between_vectors(x1, y1, x2, y2):
    return pygame.math.Vector2(x1, y1).angle_to((x2, y2))

📁 Minimal example - Calculate angle between vector animation

How to know the angle between two vectors?

Dot product

Related Stack Overflow questions:

I recommend to use pygame.math.Vector2 and the function .distance_to() to calculate the Euclidean distance distance between 2 points.

def chase(self):
    pos = pygame.math.Vector2(self.x, self.y)
    enemy = min([e for e in enemies], key=lambda e: pos.distance_to(pygame.math.Vector2(e.x, e.y)))

Explanation:

lambda e: pos.distance_to(pygame.math.Vector2(e.x, e.y)) calcaultes the distance of the argument e to the pygame.math.Vector2 object pos.
min finds the minimum element in an iterable. The “minimum” value is given by the function which is set to the key argument.

pos is initialized by the position of the Missile. For each element of enemies the distance to pos is calculated and the enemy which is closest to pos is returned by min.

Of course this can be further simplified by manually calculating the squared euclidean distance:

def chase(self):
    enemy = min([e for e in enemies], key=lambda e: pow(e.x-self.x, 2) + pow(e.y-self.y, 2))

The Dot product of 2 vectors is equal the cosine of the angle between the 2 vectors multiplied by the magnitude (length) of both vectors.

dot(A, B) == | A | * | B | * cos(angle_A_B)

This follows, that the dot product of 2 unit vectors is equal the cosine of the angle between the 2 vectors, because the length of a unit vector is 1.

uA = normalize(A)
uB = normalize(B)
cos(angle_A_B) == dot(uA, uB)

A dot B

If 2 normalized vectors point in the same direction, then the dot product is 1, if the point in the opposite direction, the dot product is -1 and if the vectors are perpendicular then the dot product is 0.

In pygame the dot product can be computed by math.Vector2.dot(). If A and B are pygame.math.Vector2 objects:

uA = A.normalize()
uB = B.normalize()
AdotB = uA.dot(uB)

Reflection

Related Stack Overflow questions:

Calculate the reflection vector to the incident vector on the circular surface.
In the following formula N is the normal vector of the circle, I is the incident vector (the current direction vector of the bouncing ball) and R is the reflection vector (outgoing direction vector of the bouncing ball):

R = I - 2.0 * dot(N, I) * N.

Use the pygame.math.Vector2.

To calculate the normal vector, you’ ve to know the “hit” point (dvx, dvy) and the center point of the circle (cptx, cpty):

circN = (pygame.math.Vector2(cptx - px, cpty - py)).normalize()

Calculate the reflection:

vecR = vecI - 2 * circN.dot(vecI) * circN

The new angle can be calculated by math.atan2(y, x):

self.angle  = math.atan2(vecR[1], vecR[0])

Rotate

Related Stack Overflow questions:

Curve

Trigonometry

Related Stack Overflow questions:

Lissajous curve

Related Stack Overflow questions:

Sort

Related Stack Overflow questions: