geometry: Points and coordinate systems

place: Coordinate systems

A coordinate system is represented by a Place object which defines an origin and three axes specified relative to another coordinate system. A Place can specify the position and orientation of a model in a scene, defining the local coordinate system of the model relative to the global coordinate system of the scene. A Place can also represent the position and orientation of a camera within a scene. A Place can also be thought of as a coordinate transformation mapping Place coordinates to the other coordinate system. The transform consists of a linear part (often a rotation, but more generally a 3 by 3 matrix) followed by a shift along the 3 axes. Place objects use 64-bit coordinates for axes and origin.

A point or vector is a one-dimensional numpy array of 3 floating point values. Multiple points or vectors are represented as two-dimensional numpy arrays of size N by 3. Points and vectors can have 32-bit or 64-bit floating point coordinates.

class Place(matrix=None, axes=None, origin=None)

Bases: object

The Place class gives the origin and axes vectors for a model in the global coordinate system. A Place is often thought of as a coordinate transformation from local to global coordinates.

The axes can be specified as a sequence of three axis vectors. The origin can be specified as a point. Or both axes and origin can be specified as a 3 by 4 array where the first 3 columns are the axes and the last column is the origin.

The axes do not need to be orthogonal, for instance a crystallographic density map may use skewed axes, and the axis vectors need not be of unit length. The axes and origin are represented as 64-bit floating point values.

apply_without_translation(v)

Transform a vector. This applies the linear part of the transform without the shift. If the linear part is a rotation, then tangent and normal vectors are rotated.

axes()

Return the coordinate system axes.

axis_center_angle_shift()

Parameterize the transform as a rotation about a point around an axis and shift along that axis. Return the rotation axis, a point on the axis, rotation angle (in degrees), and shift distance parallel to the axis. This assumes the transformation linear part is a rotation.

description()

Return a text description of the transformation including the 3 by 4 matrix, and the decomposition as a rotation about a point through an axis and shift along that axis.

determinant()

Return the determinant of the linear part of the transformation.

interpolate(tf, center, frac)

Interpolate from this transform to the specified one by a specified fraction. A fraction of 0 gives this transform while a fraction 1 gives transform tf. The interpolation is done by finding the transform mapping to tf, treating it as a rotation about the specified center point followed by a shift, then perform the specified fraction of the full rotation, and specified fraction of the shift. When the interpolated places are thought of as coordinate systems positions, the center point is in local coordinates.

inverse()

Return the inverse transform.

is_identity(tolerance=1e-06)

Is the transform the identity transformation? Tests if each of the 3 by 4 matrix elements is within the specified tolerance of the identity transform.

matrix = None

3 by 4 numpy array, first 3 columns are axes, last column is origin.

move(xyz)

Apply transform to an array of points, modifying the points in place.

moved(xyz)

Returned transformed array of points. Makes a copy of points if place is not identity.

opengl_matrix()

Return a numpy 4x4 array which is the transformation matrix in OpenGL order (columns major).

origin()

Return the transformation shift vector, or equivalently the coordinate system origin.

rotation_angle()

Return the rotation angle of the transform, or equivalently the rotation of the coordinate axes from the global axes. The return values is in radians from 0 to pi. The rotation is about the unique axis that takes the local to global coordinates. This assumes the transform is a rotation, or equivalently that the coordinate axes are orthonormal and right handed.

rotation_axis_and_angle()

Return the rotation axis and angle (degrees) of the transform.

same(p, angle_tolerance=0, shift_tolerance=0)

Is this transform the same as the given one to within a rotation angle tolerance (degrees), and shift tolerance (distance)

scale_translation(s)

Return a copy of the transform with scaled shift.

shift_and_angle(center)

Return the shift distance and rotation angle for the transform. The rotation angle is in radians the same as returned by rotation_angle(), and the shift is the distance the given center point is moved by the transformation.

translation()

Return the transformation shift vector, or equivalently the coordinate system origin.

transpose()

Return a copy of the transform with the linear part transposed.

z_axis()

Return the coordinate system z axis.

zero_translation()

Return a copy of the transform with zero shift.

class Places(places=None, place_array=None, shift_and_scale=None, opengl_array=None)

Bases: object

The Places class represents a list of 0 or more Place objects. The advantage of Places over using a list of Place objects is that it doesn’t need to create a separate Python Place object for each position, instead it is able to represent for example 10,000 atom positions as a numpy array of positioning matrices. So this class is primarily to allow efficient handling of large numbers of positions.

opengl_matrices()

Return array of 4x4 matrices with column-major order.

transform_coordinates(csys)

csys maps new coordinates to old coordinates.

cross_product(u)

Return the transform representing vector crossproduct with vector u (on the left) and zero shift.

identity()

Return the identity transform.

interpolate_rotation(place1, place2, fraction)

Interpolate the rotation parts of place1 and place2. The rotation axis taking one coordinate frame to the other is linearly interpolated. The translations are ignored and the returned Place has translation set to zero.

look_at(from_pt, to_pt, up)

Return a Place object that represents looking from ‘from_pt’ to ‘to_pt’ with ‘up’ pointing up.

orthonormal_frame(zaxis, ydir=None, xdir=None, origin=None)

Return a Place object with the specified z axis. Any rotation about that z axis is allowed, unless a vector ydir is given in which case the y axis will be in the plane define by the z axis and ydir.

product(plist)

Product of a sequence of Place transforms.

rotation(axis, angle, center=(0, 0, 0))

Return a transform which is a rotation about the specified center and axis by the given angle (degrees).

scale(s)

Return a transform which is a scale by factor s.

skew_axes(cell_angles)

Return a Place object representing the skewing with cell angles alpha, beta and gamma (degrees). The first axis is (1, 0, 0), the second axis makes angle gamma with the first and is in the xy plane, and the third axis makes angle beta with the first and angle alpha with the second axes. The axes are unit length and form a right handed coordinate system. The angles alpha, beta and gamma are the angles between yz, xz, and xy axes.

transform_planes(coord_sys, planes)

Planes are given by 4 vectors v defining plane v0*x + v1*y + v2*z + v3 = 0. Returns planes in new coordinate system.

translation(v)

Return a transform which is a shift by vector v.

vector_rotation(u, v)

Return a rotation transform taking vector u to vector v by rotation about an axis perpendicular to u and v. The vectors can have any length and the transform maps the direction of u to the direction of v.

z_align(pt1, pt2)

Return a Place object that puts the pt1->pt2 vector on the Z axis

vector: Point and vector operations

These are convenience functions that act on points and vectors which are one-dimensional numpy arrays of 3 elements, or for multiple points and vectors two-dimensional numpy arrays of size N by 3. Vectors of any dimensions are allowed, not just 3-dimensional, except where noted. Coordinate values can be 32 or 64-bit floating point numbers.

distance(p, q)

Return the distance between two points.

norm(u)

Return the length of a vector.

normalize_vector(v)

Return a unit vector in the same direction as v.

normalize_vectors(v)

Modify an array of vectors, making each have unit length.

vector_sum(weights, vectors)

Return a vector which is a linear combination of vectors with specified weights.

cross_product(u, v)

Return the cross-product of two vectors. Vectors must be 3-dimensonal.

inner_product(u, v)

Return the inner product of two vectors.

inner_product_64(u, v) → float64

Return the inner-product of two vectors accumulated as a 64-bit floating point value even if the vector components are 32-bit values. Input arrays are 1-dimensional with any value type.

bounds: Bounding boxes

Compute bounding boxes for objects in scene. The bounds of no object is represented as None rather than a Bounds object.

class Bounds(xyz_min, xyz_max)

Bases: object

Bounding box specified by minimum and maximum x,y,z coordinates.

center()

Center of bounding box.

radius()

Radius of sphere containing bounding box.

size()

Size of box along x,y,z axes.

width()

Maximum of size of box x,y,z axes.

xyz_max = None

Maximum x,y,z bounds as numpy float32 array.

xyz_min = None

Minimum x,y,z bounds as numpy float32 array.

clip_bounds(b, planes)

Clip a bounding box using planes each given as a plane point and normal.

copies_bounding_box(bounds, positions)

Return Bounds that covers a specified bounding box replicated at Places.

copy_tree_bounds(bounds, positions_list)

Return Bounds that covers a specified bounding box replicated at a hierarchy of Places.

point_bounds(xyz, placements=[])

Return Bounds for a set of points, optionally multiple positions given by a Place list.

sphere_bounds(centers, radii)

Return Bounds containing a set of spheres.

union_bounds(blist)

Return Bounds that is the union of a list of Bounds. The list can contain None elements which are ignored. If the list contains no Bounds then None is returned.

Miscellaneous Routines

align_points(xyz, ref_xyz)

Computes rotation and translation to align one set of points with another. The sum of the squares of the distances between corresponding positions is minimized.

Parameters:

xyz : numpy float n by 3 array

ref_xyz : numpy float n by 3 array

Returns:

place : Place

transformation taking xyz onto ref_xyz.

rms : float

root mean square (RMS) value calculated from distances between aligned points.

closest_cylinder_intercept(base1, base2, radii, xyz1, xyz2) → f, cnum

Find first cylinder intercept along line segment from xyz1 to xyz2. Cylinder endcaps are not considered. Implemented in C++.

Parameters:

base1, base2 : n by 3 float arrays

x,y,z cylinder end center coordinates.

radii : float array

cylinder radii.

xyz1, xyz2 : float 3-tuples

x,y,z coordinates of line segment endpoints.

Returns:

f : float

fraction of distance from xyz1 to xyz2. None if no intercept.

cnum : int

cylinder number, or None if no intercept.

closest_sphere_intercept(centers, radii, xyz1, xyz2) → f, snum

Find first sphere intercept along line segment from xyz1 to xyz2. Implemented in C++.

Parameters:

centers : n by 3 float array

x,y,z sphere center coordinates.

radii : length n float array

sphere radii.

xyz1, xyz2 : float 3-tuples

x,y,z coordinates of line segment endpoints.

Returns:

f : float

fraction of distance from xyz1 to xyz2. None if no intercept.

snum : int

sphere number, or None if no intercept.

closest_triangle_intercept(vertices, tarray, xyz1, xyz2) → f, tnum

Find first triangle intercept along line segment from xyz1 to xyz2. Implemented in C++.

Parameters:

vertices : n by 3 float array

triangle vertex x,y,z coordinates.

triangles : m by 3 int array

vertex indices specifying 3 vertices for each triangle.

xyz1, xyz2 : float 3-tuples

x,y,z coordinates of line segment endpoints.

Returns:

f : float

fraction of distance from xyz1 to xyz2. None if no intercept.

tnum : int

triangle number, or None if no intercept.

find_close_points(xyz1, xyz2, max_distance) → i1, i2

Find close points between two sets of points, returning indices for each point that is close to some point in the other set. It does not report all pairs of close points, only which points have some close neighbor in the other set. The calculation is optimized for specified maximum distance small compared to the extent of the point sets, so that only positions close to a point need to be considered. Implemented in C++.

Parameters:

xyz1 : n by 3 float array

xyz2 : m by 3 float array

max_distance : float

consider only points less than this distance away.

Returns:

i1, i2 : numpy int32 arrays

Two arrays of indices into the xyz1 and xyz2 arrays. The index arrays are generally not of the same length.

find_closest_points(xyz1, xyz2, max_distance[, scale2]) → i1, i2, near1

Find close points between two sets of points, returning indices for each point that is close to some point in the other set, and also return the closest point in set 2 for each point in set 1. The calculation is optimized for specified maximum distance small compared to the extent of the point sets, so that only positions close to a point need to be considered. Implemented in C++.

Parameters:

xyz1 : n by 3 float array

xyz2 : m by 3 float array

max_distance : float

consider only points less than this distance away.

scale2 : length m float array

Optional argument giving a distance scale factor for each point in set 2. The scale factor is only used for determining the closest point, and causes the closest scaled distance to be used. This is an obscure feature.

Returns:

i1, i2 : numpy int32 array

Two arrays of indices into the xyz1 and xyz2 arrays for points that are within the maximum distance of some other point in the other set.

near1 : numpy int32 array

A third array is returned that gives the index in set 2 of the closest for each point in set 1. This array has length equal to the number of points in set 1. If a set 1 point has no point from set 2 within the distance range then index returned is -1.

find_close_points_sets(tp1, tp2, max_distance) → i1, i2

Find close points between two sets of points, returning indices for each point that is close to some point in the other set. Each set of points is defined by a list of pairs, each pair being an array of points and an affine transform to apply to those points. The calculation is optimized for specified maximum distance small compared to the extent of the point sets, so that only positions close to a point need to be considered. Implemented in C++.

Parameters:

tp1, tp2 : list of (n by 3 float array, 3 by 4 float array)

The first array of each pair are x,y,z point coordinates, and the second array is an affine transformation with the first 3 columns being a 3 by 3 matrix to applied (left multiplied) to each point and the last column being a translation (added to the point) applied after the matrix multiplication.

max_distance : float

consider only points less than this distance away.

Returns:

i1, i2 : tuples of numpy int32 arrays

Two tuples of arrays of indices with lengths matching the lengths of the tp1 and tp2 arguments. Each index array list indices into the corresponding transformed point array for points that have some nearby point in the other set.

natural_cubic_spline(path, segment_subdivisions) → spath, tangents

Compute a natural cubic spline through path points in 3 dimensions, producing a finer set of points and tangent vectors at those points. Implemented in C++.

Parameters:

path : n by 3 float array

points that spline will pass through.

segment_subdivisions : int

place this number of additional points between every two consecutive path points.

Returns:

spath : m by 3 float array

points on cubic spline including original points and subdivision points.

tangents : m by 3 float array

tangent vector at point of returned path.