The geometry module consists of several classes and functions for working with geometries. Some of the core classes are the Point, the Vector and the Quat representing respectively a point or position in 3D, a vector in 3D and a quaternion which can be used for e.g. rotations.
In [1]:
import numpy as np
from geometry import Point, Vector, Quat, Plane, Polygon
Let's have a look first at the Point class.
A Point has x, y and z attributes.
In [ ]:
x = Point(2.0, 3.0, 0.0)
print(x.x, x.y, x.z)
Subtracting two points results in a Vector.
In [ ]:
y = Point(5.0, 2.0, 0.0)
y - x
and similarly, adding a Vector to a Point results in another Point.
In [ ]:
v = Vector(10, 2, 4)
x + v
Determining the distance between points can be done by subtracting one point from another, and then determining the norm of the resulting Vector.
In [ ]:
(y - x).norm()
This, however, can be done directly using the distance_to method.
In [ ]:
x.distance_to(y)
Now let's look at the Vector class. Like a Point a Vector has x, y and z attributes.
In [ ]:
v = Vector(3,4,5)
print(v.x, v.y, v.z)
As shown before the Vector class is closely related to the Point class. Adding a Point to a Vector results in another Point.
In [ ]:
v + Point(1,2,3)
Adding two vectors however results in another vector
In [ ]:
v + v
and adding a scalar adds the scalar value to each component of the vector.
In [ ]:
v + 3
Multiplying a vector with a scalar changes the norm of the vector and each of its components.
In [ ]:
v * 3.0
while multiplying a vector with another vector calculates the dot product
In [ ]:
v * Vector(5,2,1)
which can also be calculated explicitly using the dot method
In [ ]:
v.dot(Vector(5,2,1))
The cross product can also be calculated using the cross method
In [ ]:
v.cross(Vector(5,2,1))
Besides the normal arithmetic operators Vector also supports in-place operators.
In [ ]:
v *= 5.0
print(v)
The norm of a Vector can be obtained by using the abs function or norm method
In [ ]:
print(abs(v))
print(v.norm())
A normalized copy of a Vector can be obtained by
In [ ]:
v.normalized()
It's also possible to normalize a Vector in-place.
In [ ]:
v.normalize()
Determining whether a Vector is a unit vector is simple, using the unit method
In [ ]:
print(v.unit())
print(Vector(0,1,0).unit())
print(Vector(0,2,0).unit())
Finally, a Vector can be rotated using a Quat or quaternion.
In [ ]:
quat = Quat.from_angle_and_axis(np.deg2rad(45.0), Vector(0,1,1)) # Create rotation quaternion given an angle and an axis
v = Vector(5, 0, 0) # Vector to be rotated
v.rotate(quat)
As was shown in the previous section a quaternion represented by Quat can be used to rotate a Vector.
A quaternion consists of 4 numbers. The first number is the scalar part and the other 3 numbers form to be a Vector.
In [ ]:
a = Quat(5., 6., 7., 8.)
b = Quat(8., 7., 6., 5.)
Quaternions can be added to each other
In [ ]:
a + b
or subtracted
In [ ]:
a - b
Multiplication of quaternions is non-commutative
In [ ]:
print(a*b)
print(b*a)
while quaternion-scalar (or scalar-quaternion) multiplication is
In [ ]:
print(3.0*a)
print(a*3.0)
Quaternions can be used to represent rotations. In such a case the quaternion has to be a unit quaternion, or versor. Let's consider a rotation along the z-axis of +90 degrees.
In [ ]:
axis = Vector(0.0, 0.0, 1.0)
angle = np.deg2rad(90.0)
quat = Quat.from_angle_and_axis(angle, axis)
print(quat)
We can now apply such rotation to a vector
In [ ]:
vector = Vector(5.0, 0.0, 0.0)
vector.rotate(quat)
A polygon consists of a set of points
In [ ]:
a = Point(0.0, 0.0, 0.0)
b = Point(0.0, 1.0, 0.0)
c = Point(1.0, 1.0, 0.0)
d = Point(1.0, 0.0, 0.0)
center = Point(0.5, 0.5, 0.0)
p = Polygon([a,b,c,d], center)
Currently the center of a polygon has to be specified manually. However, this shouldn't be necessary anymore in the near future.
The area of the polygon can be obtained using the area method
In [ ]:
p.area()
A polygon is a set of points in a plane. We can get the plane using the plane method
In [ ]:
pl = p.plane()
and the normal of the polygon via the plane
In [ ]:
p.plane().normal()
If we have a plane and a line specified by two points, we can determine whether the plane and line intersect. The method distinguishes between two types of intersections, point and line. In this case, we have a point intersection.
In [ ]:
pl.intersects(Point(0.5, 0.5, 0.5), Point(0.5, 0.5, -0.5))
The point of intersection can be obtained with the intersection method
In [ ]:
pl.intersection(Point(0.5, 0.5, 0.5), Point(0.5, 0.5, -0.5))
Besides the default constructor which requires the reduced normal form, it is possible to construct a plane using several alternative constructors.