# 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]

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]

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]
`__abstractmethods__` = frozenset()
class `Goulib.geom3d.``Segment3`(*args)[source]
`__repr__`()[source]
`__abs__`()[source]
`mag2`()[source]
`swap`()[source]
`length`
`__abstractmethods__` = frozenset()
`Goulib.geom3d.``Spherical`(r, theta, phi)[source]
class `Goulib.geom3d.``Sphere`(*args)[source]

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
`__init__`(*args)[source]
Parameters: args – can be
• Sphere
• center, point on sphere
`__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 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]

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]