In this article, we will be discussing how to rotate and scale a vector in Python. Vectors allow us to perform advanced mathematical calculations such as dot and cross product in linear algebra. Let’s see how Python implements vectors.
What is a Vector?
A vector is nothing but a one-dimensional array structure. In Python, however, a vector is a one-dimensional array of lists with similar properties to Python lists. In physics, a vector’s values represent direction and magnitude. It denotes the position of one point in space relative to other points.
In Python, we can perform the following operations with the help of vectors.
- Addition
- Subtraction
- Multiplication
- Division
- Dot Product
- Scalar Product
These operations allow us to work with data in Neural Networks and 3D Rendering.
How to Implement a Vector in Python?
Using the NumPy module, we can create vectors. Vectors are of 2 types:
- Horizontal
- Vertical
With the help of the .array() function, we are able to create vectors from lists.
Horizontal Vector
Horizontal vectors can be created using single square brackets.
import numpy as np
sampleList = [2, 4, 6, 8, 10]
myVector = np.array(sampleList)
print(myVector)
Output
[ 2 4 6 8 10]
Vertical Vector
Using double square brackets, we can create vertical vectors
import numpy as np
sampleList = [[7],
[3],
[25],
[12]]
myVector = np.array(sampleList)
print(myVector)
Output
[[ 7] [ 3] [25] [12]]
How to Rotate a Vector About Its axis In Python
Let a
be a unit vector along an axis axis
. Then a = axis/norm(axis)
. Let A
= I x a
, the cross product of a
with an identity matrix I
. Then exp(theta,A)
is the rotation matrix. Finally, dotting the rotation matrix with the vector will rotate the vector.
With the help of the scipy module, we are able to achieve this. Specifically the scipy.spatial.transform.Rotation.from_rotvec(rotvec)
function. Where rotvec is the rotation axis times the rotation radians. We can apply the rotation to the vector by calling rotation.apply(vectorName)
. Let’s look at the following program
sampleVector = [1,1,1]
rotation_degrees = 90
rotation_radians = np.radians(rotation_degrees)
rotation_axis = np.array([0, 0, 1])
rotation_vector = rotation_radians * rotation_axis
rotation = R.from_rotvec(rotation_vector)
rotated_vector = rotation.apply(sampleVector)
print(rotated_vector)
Output
[-1. 1. 1.]
How To Rotate a Vector using a Quaternion
What are quaternions? Let’s refer to the following equation.
w + xi + yj + zk
A quaternion is the addition of a scalar value(w) to a 3D vector(xi + yj + zk). The space of 3D rotations is represented in full by the space of unit quaternions. Therefore, you should make sure the quaternions are normalized. Refer to this function that does exactly that.
def normalize(vector, tolerance=0.00001):
mag2 = sum(n * n for n in vector)
if abs(mag2 - 1.0) > tolerance:
mag = sqrt(mag2)
vector = tuple(n / mag for n in vector)
return vector
Each rotation is represented by a unit quaternion, and concatenations of rotations correspond to multiplications of unit quaternions. Let’s take a look at the formula represented as a function.
def quaternionMult(quaternionOne, quaternionTwo):
w1, x1, y1, z1 = quaternionOne
w2, x2, y2, z2 = quaternionTwo
w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2
x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2
y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2
z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2
return w, x, y, z
In order to rotate the vector by a quaternion, we will need its conjugate.
def quaternionConjugate(quaternion):
w, x, y, z = quaternion
return (w, -x, -y, -z)
Quaternion-vector multiplication involves converting the vector into a quaternion and then multiplying quaternion * vector * quaternionConjugate(quaternion)
def quaternionvectorProduct(quaternion, vector):
quaternion2 = (0.0,) + vector
return quaternionMult(quaternionMult(quaternion, quaternion2), quaternionConjugate(quaternion))[1:]
Finally, it’s necessary that we convert axis-angle rotations to quaternions and vice-versa. Using our previous normalize()
, the vector is normalized.
def angletoQuaternion(vector, theta):
vector = normalize(vector)
x, y, z = vector
theta /= 2
w = cos(theta/2.)
x = x * sin(theta/2.)
y = y * sin(theta/2.)
z = z * sin(theta/2.)
return w, x, y, z
Now, vice-versa.
def quaterniontoAngle(quaternion):
w, vector = quaternion[0], quaternion[1:]
theta = acos(w) * 2.0
return normalize(vector), theta
Let’s put our implementation to use. For this example, we will perform a sequence of 90-degree rotations about the x,y, and z axes. This will return a vector on the y axis to its initial position.
x_axis_unit = (1, 0, 0)
y_axis_unit = (0, 1, 0)
z_axis_unit = (0, 0, 1)
rotationOne = angletoQuaternion(x_axis_unit, numpy.pi / 2)
rotationTwo = angletoQuaternion(y_axis_unit, numpy.pi / 2)
rotationThree = angletoQuaternion(z_axis_unit, numpy.pi / 2)
vector = quaternionvectorProduct(rotationOne, y_axis_unit)
vector = quaternionvectorProduct(r2, vector)
vector = quaternionvectorProduct(r3, vector)
print(vector)
Sample Output
4.930380657631324e-32, 2.220446049250313e-16, -1.0
How To Scale Vectors Using a Sequence of Numbers in Python
Let’s say we need to scale a vector v=[1,3,5]
multiple times with a sequence of number s=[3,6,9,12]
. With the help of the NumPy library, this is achieved. Specifically, np.multiply.outer()
function.
import numpy as np
v =[1,3,5]
s=[2,4,6,8,10]
np.multiply.outer(v, s).T
Output
array([[ 2, 6, 10], [ 4, 12, 20], [ 6, 18, 30], [ 8, 24, 40], [10, 30, 50]])
FAQs
Using the rot90()
function from NumPy, we can rotate an array 90 degrees from its axes.
With the help of the rotate()
function in the PIL module, you can rotate an image. It takes two arguments:
– Angle (int)
– Expand (bool)
Conclusion
In this article, we have discussed how to rotate and scale a vector in Python. A scientific explanation for a vector has been provided. We have discussed what quaternions are and how to rotate vectors using them. Finally, we discussed vector scaling.