Skip to main content

Overview

The vec2d class is a powerful 2D vector implementation that supports vector and scalar operations, along with high-level geometric functions. It’s used throughout Serenity Valley for positioning, movement, and mathematical calculations.

Creating Vectors

You can create a vec2d in two ways:
from vec2d import vec2d

# Create with x and y coordinates
position = vec2d(100, 200)
velocity = vec2d(5.0, -3.0)

Real Examples from Source

widgets.py:318
# Creating a moving rectangle with position, size, and speed vectors
def __init__(self, surface, pos=vec2d(0,0), size=vec2d(20,20), 
             color=(255,0,0), speed=vec2d(1,0), gravity=0):
    self.pos = pos
    self.size = size
    self.speed = speed
game.py:104
# Positioning UI elements
self.floater = movingRect(self.screen,
                    pos=vec2d(self.SCREEN_WIDTH/2, 0),
                    speed=vec2d(0,5))

Arithmetic Operations

Vectors can be added to other vectors, tuples, lists, or scalars.
v1 = vec2d(10, 20)
v2 = vec2d(5, 3)

# Vector addition
result = v1 + v2  # vec2d(15, 23)

# Add tuple/list
result = v1 + [5, 3]  # vec2d(15, 23)

# Add scalar (adds to both components)
result = v1 + 5  # vec2d(15, 25)

# In-place addition
v1 += v2
Addition is commutative: v + 5 and 5 + v produce the same result.

Vector Operations

Calculate and manipulate vector length.
v = vec2d(3, 4)

# Get length (magnitude)
length = v.get_length()  # Returns 5.0
length = v.length  # Property access

# Get squared length (faster, no sqrt)
length_sqrd = v.get_length_sqrd()  # Returns 25

# Set length (scales the vector)
v.length = 10  # Now vec2d(6, 8)

# Normalize and get original length
original_length = v.normalize_return_length()
# v is now unit vector, returns original length
Use get_length_sqrd() when comparing distances to avoid expensive square root calculations.

Comparison & Indexing

Comparison

v1 = vec2d(3, 4)
v2 = vec2d(3, 4)
v3 = vec2d(5, 6)

# Equality
v1 == v2  # True
v1 == (3, 4)  # True (works with tuples)
v1 == [3, 4]  # True (works with lists)

# Inequality
v1 != v3  # True

Indexing

Access components by index:
v = vec2d(10, 20)

# Access by index
x = v[0]  # 10
y = v[1]  # 20

# Modify by index
v[0] = 5
v[1] = 15

# Get length
len(v)  # Returns 2

Unary Operations

v = vec2d(3, -4)

# Negation
neg = -v  # vec2d(-3, 4)

# Absolute value
abs_v = abs(v)  # vec2d(3, 4)

# Inversion
inv = ~v  # vec2d(-3, 4)

Common Patterns

Velocity and Movement

widgets.py:334
# Update position based on velocity
self.pos.x += self.speed.x
self.pos.y += self.speed.y

# Bounce off walls (reverse velocity)
if self.pos.x + self.size.x > self.surfaceSize.x or self.pos.x < 0:
    self.speed.x *= -1
if self.pos.y + self.size.y > self.surfaceSize.y or self.pos.y < 0:
    self.speed.y *= -1

Direction Calculation

# Get direction from point A to point B
point_a = vec2d(100, 100)
point_b = vec2d(200, 150)

direction = (point_b - point_a).normalized()
speed = 5
velocity = direction * speed

Distance Checks

# Check if two objects are close
player_pos = vec2d(100, 100)
enemy_pos = vec2d(150, 150)

# Use squared distance to avoid sqrt
if player_pos.get_dist_sqrd(enemy_pos) < 50**2:
    print("Enemy is within range!")

API Reference

x
float
The x-component of the vector
y
float
The y-component of the vector
length
float
Property to get or set the magnitude of the vector
angle
float
Property to get or set the angle of the vector in degrees

Methods

get_length()
float
Returns the magnitude of the vector
get_length_sqrd()
float
Returns the squared magnitude (faster than get_length)
rotate(angle_degrees)
None
Rotates the vector in-place by the specified angle
rotated(angle_degrees)
vec2d
Returns a rotated copy of the vector
normalized()
vec2d
Returns a unit vector in the same direction
dot(other)
float
Returns the dot product with another vector
cross(other)
float
Returns the 2D cross product (scalar)
get_distance(other)
float
Returns the distance to another point
get_angle_between(other)
float
Returns the angle in degrees between this vector and another

Build docs developers (and LLMs) love