Skip to content

Linear Algebra

Darxeal edited this page Jul 28, 2020 · 8 revisions

The linear_algebra module provides the tools for doing basic matrix and vector arithmetic in 2 and 3 dimensions.

Vector classes vec2 & vec3

In Rocket League botmaking, vectors are usually used to represent a position (coordinates) or some kind of displacement (velocities, offsets). Values like ball.position, ball.velocity, car.position, etc. are all vectors. Rocket League is a 3D game so usually you want to use vec3, but sometimes you don't care about the height part, so it's useful to have a vec2.

Instantiate vectors like this:

>>> from rlutilities.linear_algebra import vec2, vec3
>>> a = vec2(1, 2)
>>> b = vec3(3, 4, 5)

Getting and setting elements is like accessing lists/arrays:

>>> a[0]
1.0
>>> a[1]
2.0
>>> b[2] = 6

To make a new copy of an existing vector, use the copy constructor:

>>> b = vec3(a)

To convert a vec2 to vec3 or vice versa:

>>> a = vec3(1, 2, 3)
>>> b = vec2(a)
>>> c = vec3(b)
>>> print(c[0], c[1], c[2])
1.0 2.0 0.0

Notice that when converting a vec2 to vec3, the added third element defaults to 0

Arithmetic operations

Supported operations for vec3 and likewise for vec2

vec3 - vec3
vec3 + vec3
vec3 -= vec3
vec3 += vec3
float * vec3
vec3 * float
vec3 / float
vec3 *= float
vec3 /= float

Example:

>>> a = vec3(0, 1, 2)
>>> b = vec3(3, 1, -1)
>>> c = a + 2.5 * b
>>> print(c[0], c[1], c[2]) 
7.5 3.5 -0.5

Note: Operations on different vector types (for example adding vec2 and vec3) isn't supported in python. You need to explicitly convert first.

Norm / size / length / magnitude of a vector

norm returns the Euclidean length of a vector.

>>> from rlutilities.linear_algebra import vec3, norm
>>> norm(vec3(3, 0, 4))
5.0

Example: Get the distance between a car and a ball:

distance = norm(car.position - ball.position)

Normalized vector

normalize returns the unit vector (with a magnitude of 1) in the same direction as its argument.

>>> from rlutilities.linear_algebra import vec3, norm, normalize
>>> v = vec3(5, 12, 0)
>>> w = normalize(v)
>>> print(w[0], w[1], w[2])
0.384615 0.923077 0.0
>>> norm(w)
1.0

Angle between vectors

angle_between returns the absolute angle between two vectors, in radians.

>>> from rlutilities.linear_algebra import vec3, norm, angle_between
>>> angle_between(vec3(1, 0, 0), vec3(0, 0, 1))
1.5707963705062866
>>> angle_between(vec3(1, 0, 0), vec3(1, 0, 0)) 
0.0

Matrix classes mat2 & mat3 and orientation

In RLUtilities, matrices are usually used to represent a car's orientation. You can simply get an existing car's orientation by car.orientation.

Creating an orientation matrix

You might need to create a custom orientation matrix, for example as a target for Reorient. Here's a few ways how to do that:

  • Using look_at

    look_at takes two vectors, the first is the direction in which you want your car to face, the second is the direction to orient the car's roof in.

    Example: Let's say you want your car to face towards the ball while being upside down:

    >>> to_ball = ball.position - car.position
    >>> down = vec3(0, 0, -1)
    >>> orientation = look_at(to_ball, down)

    Note: make sure that the two vector arguments passed to look_at do not have exactly the same direction. In this case it's unclear what the resulting orientation should be.

  • Using axis_to_rotation

    axis_to_rotation takes a vector, its direction is the axis around which it rotates, and its length is the angle, in radians. This is useful for modifying existing orientation matrices using the dot product.

    Example: Let's say you want to roll the car 90 degrees clockwise.

    >>> angle = math.pi / 2
    >>> clockwise_roll = axis_to_rotation(car.forward() * angle)
    >>> orientation = dot(clockwise_roll, car.orientation)
  • From euler angles (pitch, yaw, roll)

    >>> orientation = euler_to_rotation(vec3(pitch, yaw, roll))

More on matrices

Creating specific matrices, getting and setting elements:

>>> from rlutilities.linear_algebra import mat2, mat3
>>> a = mat2(1, 2,
...          3, 4)
>>> b = mat3(1, 0, 0,
...          0, 1, 0,
...          0, 0, 1)
>>> a[0, 1]
2.0
>>> b[2, 2] = 9

Matrices are commonly used to represent linear transformations. An orientation matrix is just one of many uses. You can "apply" those transformations onto vectors using the dot product. Let's look at an example usage:

Local and world coordinates

Using the orientation matrix to find the world coordinates of a location given in terms of how it is in front, to the left, and above:

offset_local = vec3(
    150.0, # how far in front of the car
    60.0,  # how far to the left of the car
    300.0  # how far above the car
)

world_pos = car.position + dot(car.orientation, offset_local)

Using the orientation matrix to find the local coordinates of a world location

offset_local = dot(world_pos - car_pos, orientation)

# world_pos is offset_local[0] units in front of the car
# world_pos is offset_local[1] units to the left of the car
# world_pos is offset_local[2] units above of the car;