-
Notifications
You must be signed in to change notification settings - Fork 18
Linear Algebra
The linear_algebra
module provides the tools for doing basic matrix and vector arithmetic in 2 and 3 dimensions.
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
tovec3
, the added third element defaults to0
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
andvec3
) isn't supported in python. You need to explicitly convert first.
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)
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
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
In RLUtilities, matrices are usually used to represent a car's orientation. You can simply get an existing car's orientation by car.orientation
.
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:
-
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 theball
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. -
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 thedot
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)
-
>>> orientation = euler_to_rotation(vec3(pitch, yaw, roll))
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:
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;