Goulib.geom3d module

3D geometry

class Goulib.geom3d.Vector3(*args)[source]

Bases: object

Mutable 3D Vector. See `Vector2`documentation

Constructor. :param *args: x,y,z values

__init__(*args)[source]

Constructor. :param *args: x,y,z values

xyz
Returns:tuple (x,y,z)
__repr__()[source]
__eq__(other)[source]
__ne__(other)[source]
__bool__()[source]
__nonzero__()
__len__()[source]
__iter__()[source]
__add__(other)[source]
__radd__(other)
__iadd__(other)[source]
__sub__(other)[source]
__rsub__(other)[source]
__mul__(other)[source]
__rmul__(other)
__imul__(other)[source]
__div__(other)[source]
__rdiv__(other)[source]
__floordiv__(other)[source]
__rfloordiv__(other)[source]
__truediv__(other)[source]
__rtruediv__(other)[source]
__neg__()[source]
__pos__()[source]
__abs__()[source]
mag()
mag2()[source]
normalize()[source]
normalized()[source]
dot(other)[source]
cross(other)[source]
reflect(normal)[source]
rotate_around(axis, theta)[source]

Return the vector rotated around axis through angle theta. Right hand rule applies

angle(other)[source]

angle between two vectors. :param other: Vector3 :return: float angle in radians to the other vector, or self direction if other=None

project(other)[source]

Return one vector projected on the vector other

__hash__ = None
class Goulib.geom3d.Point3(*args)[source]

Bases: Goulib.geom3d.Vector3, Goulib.geom.Geometry

A point on a 3D plane. Construct in the obvious way:

>>> p = Point3(1.0, 2.0, 3.0)
>>> p
Point3(1.00, 2.00, 3.00)

Point3 subclasses Vector3, so all of Vector3 operators and methods apply. In particular, subtracting two points gives a vector:

>>> Point3(1.0, 2.0, 3.0) - Point3(1.0, 0.0, -2.0)
Vector3(0.00, 2.00, 5.00)

The following methods are also defined:

intersect(other)
If other is a Sphere, returns True iff the point lies within the sphere.
connect(other)
Returns a LineSegment3 which is the minimum length line segment that can connect the two shapes. other may be a Point3, Line3, Ray3, LineSegment3, Sphere or Plane.
distance(other)
Returns the absolute minimum distance to other. Internally this simply returns the length of the result of connect.

Constructor. :param *args: x,y,z values

intersect(other)[source]

Point3/object intersection :return: self Point3 if on other object, None if not

connect(other)[source]
__abstractmethods__ = frozenset()
class Goulib.geom3d.Line3(*args)[source]

Bases: Goulib.geom.Geometry

A Line3 is a line on a 3D plane extending to infinity in both directions; a Ray3 has a finite end-point and extends to infinity in a single direction; a LineSegment3 joins two points.

All three classes support the same constructors, operators and methods, but may behave differently when calculating intersections etc.

You may construct a line, ray or line segment using any of:

  • another line, ray or line segment
  • two points
  • a point and a vector
  • a point, a vector and a length

For example:

>>> Line3(Point3(1.0, 1.0, 1.0), Point3(1.0, 2.0, 3.0))
Line3(<1.00, 1.00, 1.00> + u<0.00, 1.00, 2.00>)
>>> Line3(Point3(0.0, 1.0, 1.0), Vector3(1.0, 1.0, 2.0))
Line3(<0.00, 1.00, 1.00> + u<1.00, 1.00, 2.00>)
>>> Ray3(Point3(1.0, 1.0, 1.0), Vector3(1.0, 1.0, 2.0), 1.0)
Ray3(<1.00, 1.00, 1.00> + u<0.41, 0.41, 0.82>)

Internally, lines, rays and line segments store a Point3 p and a Vector3 v. You can also access (but not set) the two endpoints p1 and p2. These may or may not be meaningful for all types of lines.

The following methods are supported by all three classes:

intersect(other)

If other is a Sphere, returns a LineSegment3 which is the intersection of the sphere and line, or None if there is no intersection.

If other is a Plane, returns a Point3 of intersection, or None.

connect(other)
Returns a LineSegment3 which is the minimum length line segment that can connect the two shapes. For two parallel lines, this line segment may be in an arbitrary position. other may be a Point3, Line3, Ray3, LineSegment3, Sphere or Plane.
distance(other)
Returns the absolute minimum distance to other. Internally this simply returns the length of the result of connect.

LineSegment3 also has a length property which is read-only.

__init__(*args)[source]
__repr__()[source]
p1
p2
point(u)[source]
Returns:Point3 at parameter u
intersect(other)[source]
connect(other)[source]
__abstractmethods__ = frozenset()
class Goulib.geom3d.Ray3(*args)[source]

Bases: Goulib.geom3d.Line3

__abstractmethods__ = frozenset()
class Goulib.geom3d.Segment3(*args)[source]

Bases: Goulib.geom3d.Line3

__repr__()[source]
__abs__()[source]
mag2()[source]
swap()[source]
length
__abstractmethods__ = frozenset()
Goulib.geom3d.Spherical(r, theta, phi)[source]
class Goulib.geom3d.Sphere(*args)[source]

Bases: Goulib.geom.Geometry

Spheres are constructed with a center Point3 and a radius:

>>> s = Sphere(Point3(1.0, 1.0, 1.0), 0.5)
>>> s

Sphere(<1.00, 1.00, 1.00>, radius=0.50)

Internally there are two attributes: c, giving the center point and r, giving the radius.

The following methods are supported:

intersect(other):

If other is a Point3, returns True iff the point lies within the sphere.

If other is a Line3, Ray3 or LineSegment3, returns a LineSegment3 giving the intersection, or None if the line does not intersect the sphere.

distance(other)
Returns the absolute minimum distance to other. Internally this simply returns the length of the result of connect.
Parameters:args – can be
  • Sphere
  • center, point on sphere
  • center, radius
__init__(*args)[source]
Parameters:args – can be
  • Sphere
  • center, point on sphere
  • center, radius
__repr__()[source]
__contains__(pt)[source]
Returns:True if pt is ON or IN the sphere
point(u, v)[source]
Parameters:
  • u – float angle from “north pole” (=radians(90-lat) in radians
  • v – float angle from 0 meridian
Returns:

Point3 on sphere at specified coordinates

intersect(other)[source]
connect(other)[source]

minimal joining segment between Sphere and other 3D Object :param other: Point3, Line3, Sphere, Plane :return: LineSegment3 of minimal length

distance_on_sphere(phi1, theta1, phi2, theta2)[source]
Parameters:
  • phi1 – float angle from “north pole” (=radians(90-lat) in radians
  • theta1 – float angle from 0 meridian
  • phi2 – float angle from “north pole” (=radians(90-lat) in radians
  • theta2 – float angle from 0 meridian
__abstractmethods__ = frozenset()
class Goulib.geom3d.Plane(*args)[source]

Bases: Goulib.geom.Geometry

Planes can be constructed with any of:

  • three Point3’s lying on the plane
  • a Point3 on the plane and the Vector3 normal
  • a Vector3 normal and k, described below.

Internally, planes are stored with the normal n and constant k such that n.p = k for any point on the plane p.

The following methods are supported:

intersect(other)

If other is a Line3, Ray3 or LineSegment3, returns a Point3 of intersection, or None if there is no intersection.

If other is a Plane, returns the Line3 of intersection.

connect(other)
Returns a LineSegment3 which is the minimum length line segment that can connect the two shapes. other may be a Point3, Line3, Ray3, LineSegment3, Sphere or Plane.
distance(other)
Returns the absolute minimum distance to other. Internally this simply returns the length of the result of connect.
__init__(*args)[source]
__repr__()[source]
intersect(other)[source]
connect(other)[source]
__abstractmethods__ = frozenset()
class Goulib.geom3d.Matrix4(*args)[source]

Bases: object

__init__(*args)[source]
__repr__()[source]
__iter__()[source]
__getitem__(key)[source]
__setitem__(key, value)[source]
__mul__(other)[source]
__call__(other)[source]
__imul__(other)[source]
transform(other)[source]
identity()[source]
scale(x, y, z)[source]
translate(x, y, z)[source]
rotatex(angle)[source]
rotatey(angle)[source]
rotatez(angle)[source]
rotate_axis(angle, axis)[source]
rotate_euler(heading, attitude, bank)[source]
rotate_triple_axis(x, y, z)[source]
transpose()[source]
transposed()[source]
classmethod new(*values)[source]
classmethod new_identity()[source]
classmethod new_scale(x, y, z)[source]
classmethod new_translate(x, y, z)[source]
classmethod new_rotatex(angle)[source]
classmethod new_rotatey(angle)[source]
classmethod new_rotatez(angle)[source]
classmethod new_rotate_axis(angle, axis)[source]
classmethod new_rotate_euler(heading, attitude, bank)[source]
classmethod new_rotate_triple_axis(x, y, z)[source]
classmethod new_look_at(eye, at, up)[source]
classmethod new_perspective(fov_y, aspect, near, far)[source]
determinant()[source]
inverse()[source]
class Goulib.geom3d.Quaternion(w=1, x=0, y=0, z=0)[source]

Bases: object

A quaternion represents a three-dimensional rotation or reflection transformation. They are the preferred way to store and manipulate rotations in 3D applications, as they do not suffer the same numerical degradation that matrices do.

The quaternion constructor initializes to the identity transform:

>>> q = Quaternion()
>>> q
Quaternion(real=1.00, imag=<0.00, 0.00, 0.00>)

Element access

Internally, the quaternion is stored as four attributes: x, y and z forming the imaginary vector, and w the real component.

Constructors

Rotations can be formed using the constructors:

new_identity()
Equivalent to the default constructor.
new_rotate_axis(angle, axis)

Equivalent to the Matrix4 constructor of the same name. angle is specified in radians, axis is an instance of Vector3. It is not necessary to normalize the axis. Example:

>>> q = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q
Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>)
new_rotate_euler(heading, attitude, bank)

Equivalent to the Matrix4 constructor of the same name. heading is a rotation around the Y axis, attitude around the X axis and bank around the Z axis. All angles are given in radians. Example:

>>> q = Quaternion.new_rotate_euler(math.pi / 2, math.pi / 2, 0)
>>> q
Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)
new_interpolate(q1, q2, t)

Create a quaternion which gives a (SLERP) interpolated rotation between q1 and q2. q1 and q2 are instances of Quaternion, and t is a value between 0.0 and 1.0. For example:

>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q2 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0))
>>> for i in range(11):
...     print Quaternion.new_interpolate(q1, q2, i / 10.0)
...
Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>)
Quaternion(real=0.75, imag=<0.66, 0.09, 0.00>)
Quaternion(real=0.78, imag=<0.61, 0.17, 0.00>)
Quaternion(real=0.80, imag=<0.55, 0.25, 0.00>)
Quaternion(real=0.81, imag=<0.48, 0.33, 0.00>)
Quaternion(real=0.82, imag=<0.41, 0.41, 0.00>)
Quaternion(real=0.81, imag=<0.33, 0.48, 0.00>)
Quaternion(real=0.80, imag=<0.25, 0.55, 0.00>)
Quaternion(real=0.78, imag=<0.17, 0.61, 0.00>)
Quaternion(real=0.75, imag=<0.09, 0.66, 0.00>)
Quaternion(real=0.71, imag=<0.00, 0.71, 0.00>)

Operators

Quaternions may be multiplied to compound rotations. For example, to rotate 90 degrees around the X axis and then 90 degrees around the Y axis:

>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q2 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0))
>>> q1 * q2
Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)

Multiplying a quaternion by a vector gives a vector, transformed appropriately:

>>> q = Quaternion.new_rotate_axis(math.pi / 2, Vector3(0, 1, 0))
>>> q * Vector3(1.0, 0, 0)
Vector3(0.00, 0.00, -1.00)

Similarly, any 3D object can be multiplied (e.g., Point3, Line3, Sphere, etc):

>>> q * Ray3(Point3(1., 1., 1.), Vector3(1., 1., 1.))
Ray3(<1.00, 1.00, -1.00> + u<1.00, 1.00, -1.00>)

As with the matrix classes, the constructors are also available as in-place operators. These are named identity, rotate_euler and rotate_axis. For example:

>>> q1 = Quaternion()
>>> q1.rotate_euler(math.pi / 2, math.pi / 2, 0)
Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)
>>> q1
Quaternion(real=0.50, imag=<0.50, 0.50, 0.50>)

Quaternions are usually unit length, but you may wish to use sized quaternions. In this case, you can find the magnitude using abs, magnitude and magnitude_squared, as with the vector classes. Example:

>>> q1 = Quaternion()
>>> abs(q1)
1.0
>>> q1.magnitude()
1.0

Similarly, the class implements normalize and normalized in the same way as the vectors.

The following methods do not alter the quaternion:

conjugated()

Returns a quaternion that is the conjugate of the instance. For example:

>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q1.conjugated()
Quaternion(real=0.71, imag=<-0.71, -0.00, -0.00>)
>>> q1
Quaternion(real=0.71, imag=<0.71, 0.00, 0.00>)
get_angle_axis()

Returns a tuple (angle, axis), giving the angle to rotate around an axis equivalent to the quaternion. For example:

>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q1.get_angle_axis()
(1.5707963267948966, Vector3(1.00, 0.00, 0.00))
get_matrix()

Returns a Matrix4 implementing the transformation of the quaternion. For example:

>>> q1 = Quaternion.new_rotate_axis(math.pi / 2, Vector3(1, 0, 0))
>>> q1.get_matrix()
Matrix4([    1.00     0.00     0.00     0.00
             0.00     0.00    -1.00     0.00
             0.00     1.00     0.00     0.00
             0.00     0.00     0.00     1.00])
__init__(w=1, x=0, y=0, z=0)[source]
__repr__()[source]
__mul__(other)[source]
__imul__(other)[source]
mag2()[source]
__abs__()[source]
mag()
identity()[source]
rotate_axis(angle, axis)[source]
rotate_euler(heading, attitude, bank)[source]
rotate_matrix(m)[source]
conjugated()[source]
normalize()[source]
normalized()[source]
get_angle_axis()[source]
get_euler()[source]
get_matrix()[source]
classmethod new_identity()[source]
classmethod new_rotate_axis(angle, axis)[source]
classmethod new_rotate_euler(heading, attitude, bank)[source]
classmethod new_rotate_matrix(m)[source]
classmethod new_interpolate(q1, q2, t)[source]