Welcome to polliwog’s documentation!¶
polliwog package¶
Subpackages¶
polliwog.box package¶
Submodules¶
polliwog.box.box module¶

class
polliwog.box.box.
Box
(origin, size)[source]¶ Bases:
object
An axisaligned cuboid or rectangular prism. It’s defined by an origin point, which is its minimum point in each dimension, and nonnegative size (length, width, and depth).
Parameters:  origin (np.arraylike) – The x, y, and z coordinate of the origin, the minimum point in each dimension.
 size (np.arraylike) – An array containing the width (dx), height (dy), and depth (dz), which must be nonnegative.

center_point
¶ The box’s geometric center.

depth
¶ The box’s depth. Same as max_z  min_z.

floor_point
¶ The center of the side of the box having the minimum y coordinate. This is center_point projected to the the level of min_y.

classmethod
from_points
(points)[source]¶ The smallest box which spans the given points.
Parameters: points (np.arraylike) – A kx3 array of points. Returns: The smallest box which spans the given points. Return type: Box

height
¶ The box’s height. Same as max_y  min_y.

max_x
¶ The box’s maximum x coordinate.

max_y
¶ The box’s maximum y coordinate.

max_z
¶ The box’s maximum z coordinate.

mid_x
¶ The x coordinate of the box’s center.

mid_y
¶ The y coordinate of the box’s center.

mid_z
¶ The z coordinate of the box’s center.

min_x
¶ The box’s minimum x coordinate.

min_y
¶ The box’s minimum y coordinate.

min_z
¶ The box’s minimum z coordinate.

ranges
¶ Ranges for each coordinate axis as a 3x2 np.ndarray.

surface_area
¶ The box’s surface area.

volume
¶ The box’s volume.

width
¶ The box’s width. Same as max_x  min_x.
polliwog.line package¶
Submodules¶
polliwog.line.functions module¶
polliwog.line.line module¶
polliwog.line.line_intersect module¶

polliwog.line.line_intersect.
line_intersect2
(p0, q0, p1, q1)[source]¶ Intersect two lines: (p0, q0) and (p1, q1). Each should be a 2D point.
Adapted from http://stackoverflow.com/a/26416320/893113

polliwog.line.line_intersect.
line_intersect3
(p0, q0, p1, q1)[source]¶ Intersect two lines in 3d: (p0, q0) and (p1, q1). Each should be a 3D point. See this for a diagram: http://math.stackexchange.com/questions/270767/findintersectionoftwo3dlines
polliwog.plane package¶
Submodules¶
polliwog.plane.coordinate_planes module¶
polliwog.plane.functions module¶

polliwog.plane.functions.
normal_and_offset_from_plane_equations
(plane_equations)[source]¶ Given A, B, C, D of the plane equation Ax + By + Cz + D = 0, return the plane normal vector which is [A, B, C] and the offset D.

polliwog.plane.functions.
plane_equation_from_points
(points)[source]¶ Given many sets of three points, return a stack of plane equations [A, B, C, D] which satisfy Ax + By + Cz + D = 0. Also works on three points to return a single plane equation.
These coefficients can be decomposed into the plane normal vector which is [A, B, C] and the offset D, either by the caller or by using normal_and_offset_from_plane_equations().

polliwog.plane.functions.
plane_normal_from_points
(points, normalize=True)[source]¶ Given a set of three points, compute the normal of the plane which passes through them. Also works on stacked inputs (i.e. many sets of three points).
This is the same as polliwog.tri.functions.surface_normals, to which this delegates.
polliwog.plane.intersections module¶
polliwog.plane.plane module¶

class
polliwog.plane.plane.
Plane
(point_on_plane, unit_normal)[source]¶ Bases:
object
A 2D plane in 3space (not a hyperplane).
 Params:
 point_on_plane, plane_normal:
 1 x 3 np.arrays

canonical_point
¶ A canonical point on the plane, the one at which the normal would intersect the plane if drawn from the origin (0, 0, 0).
This is computed by projecting the reference point onto the normal.
This is useful for partitioning the space between two planes, as we do when searching for planar cross sections.

equation
¶ Returns parameters A, B, C, D as a 1 x 4 np.array, where
Ax + By + Cz + D = 0defines the plane.
 params:
 normalized:
 Boolean, indicates whether or not the norm of the vector [A, B, C] is 1. Useful when computing the distance from a point to the plane.

classmethod
fit_from_points
(points)[source]¶ Fits a plane whose normal is orthgonal to the first two principal axes of variation in the data and centered on the points’ centroid.

classmethod
from_points
(p1, p2, p3)[source]¶ If the points are oriented in a counterclockwise direction, the plane’s normal extends towards you.

classmethod
from_points_and_vector
(p1, p2, vector)[source]¶ Compute a plane which contains two given points and the given vector. Its reference point will be p1.
For example, to find the vertical plane that passes through two landmarks:
from_points_and_normal(p1, p2, vector)Another way to think about this: identify the plane to which your result plane should be perpendicular, and specify vector as its normal vector.

normal
¶ Return the plane’s normal vector.

points_in_front
(points, inverted=False, ret_indices=False)[source]¶ Given an array of points, return the points which lie either on the plane or in the halfspace in front of it (i.e. in the direction of the plane normal).
Parameters:  points (np.arraylikw) – An array of points.
 inverted (bool) – When True, invert the logic. Return the points that lie behind the plane instead.
 ret_indices (bool) – When True, return the indices instead of the points themselves.

reference_point
¶ The point used to create this plane.
polliwog.polyline package¶
Submodules¶
polliwog.polyline.cut_by_plane module¶
polliwog.polyline.inflection_points module¶

polliwog.polyline.inflection_points.
inflection_points
(points, axis, span)[source]¶ Find the list of vertices that preceed inflection points in a curve. The curve is differentiated with respect to the coordinate system defined by axis and span.
Interestingly, lambda x: 2*x + 1 should have no inflection points, but almost every point on the line is detected. It’s because a zero or zero crossing in the second derivative is necessary but not sufficient to detect an inflection point. You also need a higher derivative of odd order that’s nonzero. But that gets ugly to detect reliably using sparse finite differences. Just know that if you’ve got a straight line this method will go a bit haywire.
axis: A vector representing the vertical axis of the coordinate system. span: A vector representing the the horiztonal axis of the coordinate system.
returns: a list of points in space corresponding to the vertices that immediately preceed inflection points in the curve
polliwog.polyline.polyline module¶

class
polliwog.polyline.polyline.
Polyline
(v, is_closed=False)[source]¶ Bases:
object
Represent the geometry of a polygonal chain in 3space. The chain may be open or closed, and there are no constraints on the geometry. For example, the chain may be simple or selfintersecting, and the points need not be unique.
Mutable by setting polyline.v or polyline.closed or calling a method like polyline.partition_by_length().
Note this class is distinct from lace.lines.Lines, which allows arbitrary edges and enables visualization. To convert to a Lines object, use the as_lines() method.

apex
(axis)[source]¶ Find the most extreme point in the direction of the axis provided.
axis: A vector, which is an 3x1 np.array.

bisect_edges
(edges)[source]¶ Cutting the given edges in half.
Return an arrray that gives the new indices of the original vertices.

bounding_box
¶ The bounding box which encompasses the entire polyline.

cut_by_plane
(plane)[source]¶ Return a new Polyline which keeps only the part that is in front of the given plane.
For open polylines, the plane must intersect the polyline exactly once.
For closed polylines, the plane must intersect the polylint exactly twice, leaving a single contiguous segment in front.

e
¶ Return a np.array of edges. Derived automatically from self.v and self.is_closed whenever those values are set.

intersect_plane
(plane, ret_edge_indices=False)[source]¶ Returns the points of intersection between the plane and any of the edges of polyline, which should be an instance of Polyline.
TODO: This doesn’t correctly handle vertices which lie on the plane.

is_closed
¶

classmethod
join
(*polylines)[source]¶ Join together a stack of open polylines endtoend into one contiguous polyline. The last vertex of the first polyline is connected to the first vertex of the second polyline, and so on.

nearest
(points, ret_segment_indices=False)[source]¶ For the given query point or points, return the nearest point on the polyline. With ret_segment_indices=True, also return the segment indices of those points.

num_e
¶ Return the number of segments in the polyline.

num_v
¶ Return the number of vertices in the polyline.

oriented_along
(along, reverse=False)[source]¶ Flip the polyline, if necessary, so that it points (approximately) along the second vector rather than (approximately) opposite it.

partition_by_length
(max_length, ret_indices=False)[source]¶ Subdivide each line segment longer than max_length with equallength segments, such that none of the new segments are longer than max_length.
 ret_indices: If True, return the indices of the original vertices.
 Otherwise return self for chaining.

rolled
(index, ret_edge_mapping=False)[source]¶ Return a new Polyline which reindexes the callee polyline, which much be closed, so the vertex with the given index becomes vertex 0.
 ret_edge_mapping: if True, return an array that maps from old edge
 indices to new.

segment_lengths
¶ The length of each of the segments.

segment_vectors
¶ Vectors spanning each segment.

segments
¶ Coordinate pairs for each segment.

total_length
¶ The total length of all the segments.

v
¶

polliwog.segment package¶
Submodules¶
polliwog.segment.segment module¶

polliwog.segment.segment.
closest_point_of_line_segment
(points, start_points, segment_vectors)[source]¶

polliwog.segment.segment.
partition
(v, partition_size=5)[source]¶  params:
 v:
 V x N np.array of points in Nspace
 partition_size:
 how many partitions intervals for each segment?
Fill in the line segments determined by v with equally spaced points  the space for each segment is determined by the length of the segment and the supplied partition size.

polliwog.segment.segment.
partition_segment
(p1, p2, n_samples, endpoint=True)[source]¶ For two points in nspace, return an np.ndarray of equidistant partition points along the segment determined by p1 & p2.
The total number of points returned will be n_samples. When n_samples is 2, returns the original points.
When endpoint is True, p2 is the last point. When false, p2 is excluded.
Partition order is oriented from p1 to p2.
Parameters:  p2 (p1,) – 1 x N vectors
 partition_size – size of partition. should be >= 2.

polliwog.segment.segment.
partition_segment_old
(p1, p2, partition_size=5)[source]¶ Deprecated. Please use partition_segment.
For two points in nspace, return an np.ndarray of partition points at equal widths determined by ‘partition_size’ on the interior of the segment determined by p1 & p2.
Accomplished by partitioning the segment into ‘partition_size’ subintervals.
Partition order is oriented from p1 to p2.
Parameters:  p2 (p1,) – 1 x N vectors
 partition_size – size of partition. should be > 1.
polliwog.transform package¶
Submodules¶
polliwog.transform.affine_transform module¶
polliwog.transform.composite module¶

class
polliwog.transform.composite.
CompositeTransform
[source]¶ Bases:
object
Composite transform using homogeneous coordinates.
Example
>>> transform = CompositeTransform() >>> transform.scale(10) >>> transform.reorient(up=[0, 1, 0], look=[1, 0, 0]) >>> transform.translate([0, 2.5, 0]) >>> transformed_scan = transform(scan_v) >>> # ... register the scan here ... >>> untransformed_alignment = transform(alignment_v, reverse=True)
See also
 Computer Graphics: Principles and Practice, Hughes, van Dam, McGuire, Sklar, Foley
 http://gamedev.stackexchange.com/questions/72044/whydoweuse4x4matricestotransformthingsin3d

__call__
(points, from_range=None, reverse=False)[source]¶ Parameters:  points (np.arraylike) – Points to transform, as a 3xn array.
 from_range (tuple) – The indices of the subset of the transformations to apply. e.g. (0, 2), (2, 4). When None, which is the default, apply them all.
 reverse (bool) – When True applies the selected transformations in reverse. This has no effect on how range is interpreted, only whether the selected transformations apply in the forward or reverse mode.

append_transform3
(forward, reverse=None)[source]¶ Append an arbitrary transformation, defined by 3x3 forward and reverse matrices.
The new transformation is added to the end. Return its index.

append_transform4
(forward, reverse=None)[source]¶ Append an arbitrary transformation, defined by 4x4 forward and reverse matrices.
The new transformation is added to the end. Return its index.

convert_units
(from_units, to_units)[source]¶ Convert the mesh from one set of units to another.
These calls are equivalent:
>>> composite.convert_units(from_units='cm', to_units='m') >>> composite.scale(.01)
Supports the length units from Ounce: https://github.com/lace/ounce/blob/master/ounce/core.py#L26

scale
(factor)[source]¶ Scale by the given factor.
Forward: [[ s_0, 0, 0, 0 ], [ 0, s_1, 0, 0 ], [ 0, 0, s_2, 0 ], [ 0, 0, 0, 1 ]]
Reverse: [[ 1/s_0, 0, 0, 0 ], [ 0, 1/s_1, 0, 0 ], [ 0, 0, 1/s_2, 0 ], [ 0, 0, 0, 1 ]]
Parameters: factor (float) – The scale factor.

transform_matrix_for
(from_range=None, reverse=False)[source]¶ Return a 4x4 transformation matrix representation.
 range: The min and max indices of the subset of the transformations to
 apply. e.g. (0, 2), (2, 4). Inclusive of the min value, exclusive of the max value. The default is to apply them all.
 reverse: When True returns a matrix for the inverse transform.
 This has no effect on how range is interpreted, only whether the forward or reverse matrices are used.
polliwog.transform.coordinate_manager module¶

class
polliwog.transform.coordinate_manager.
CoordinateManager
[source]¶ Bases:
object
Here’s the idea:
coordinate_manager = CoordinateManager() coordinate_manager.tag_as(‘source’) coordinate_manager.translate(cube.floor_point) coordinate_manager.scale(2) coordinate_manager.tag_as(‘floored_and_scaled’) coordinate_manager.translate(np.array([0., 4., 0.])) coordinate_manager.tag_as(‘centered_at_origin’)
coordinate_manager.source = cube centered_mesh = coordinate_manager.centered_at_origin
polliwog.transform.rigid_transform module¶

polliwog.transform.rigid_transform.
find_rigid_transform
(a, b, visualize=False)[source]¶ Parameters:  a – a 3xN array of vertex locations
 b – a 3xN array of vertex locations
Returns: (R,T) such that R.dot(a)+T ~= b Based on Arun et al, “Leastsquares fitting of two 3D point sets,” 1987. See also Eggert et al, “Estimating 3D rigid body transformations: a comparison of four major algorithms,” 1997.
polliwog.transform.rodrigues module¶
polliwog.transform.rotation module¶

polliwog.transform.rotation.
rotation_from_up_and_look
(up, look)[source]¶ Rotation matrix to rotate a mesh into a canonical reference frame. The result is a rotation matrix that will make up along +y and look along +z (i.e. facing towards a default opengl camera).
up: The direction you want to become +y. look: The direction you want to become +z.
polliwog.tri package¶
Submodules¶
polliwog.tri.functions module¶

polliwog.tri.functions.
barycentric_coordinates_of_points
(vertices_of_tris, points)[source]¶ Compute barycentric coordinates for the projection of a set of points to a given set of triangles specfied by their vertices.
These barycentric coordinates can refer to points outside the triangle. This happens when one of the coordinates is negative. However they can’t specify points outside the triangle’s plane. (That requires tetrahedral coordinates.)
The returned coordinates supply a linear combination which, applied to the vertices, returns the projection of the original point the plane of the triangle.
Parameters:  vertices_of_tris (np.arraylike) – A set of triangle vertices as kx3x3.
 points (np.arraylike) – Coordinates of points as kx3.
Returns: Barycentric coordinates as kx3
Return type: np.ndarray
See also
 https://en.wikipedia.org/wiki/Barycentric_coordinate_system
 Heidrich, “Computing the Barycentric Coordinates of a Projected Point,” JGT 05 (http://www.cs.ubc.ca/~heidrich/Papers/JGT.05.pdf)
polliwog.tri.quad_faces module¶

polliwog.tri.quad_faces.
quads_to_tris
(quads, ret_mapping=False)[source]¶ Convert quad faces to triangular faces.
quads: An nx4 array. ret_mapping: A bool.
When ret_mapping is True, return a 2nx3 array of new triangles and a 2nx3 array mapping old quad indices to new trangle indices.
When ret_mapping is False, return the 2nx3 array of triangles.
polliwog.tri.shapes module¶

polliwog.tri.shapes.
create_cube
(origin, size, ret_unique_vertices_and_faces=False)[source]¶ Return vertices (or unique verties and faces) with an axisaligned cube. One vertex is origin; the diametrically opposite vertex is size units along +x, +y, and +z.
size: int or float.

polliwog.tri.shapes.
create_horizontal_plane
(ret_unique_vertices_and_faces=False)[source]¶ Creates a horizontal plane.

polliwog.tri.shapes.
create_rectangular_prism
(origin, size, ret_unique_vertices_and_faces=False)[source]¶ Return vertices (or unique verties and faces) of an axisaligned rectangular prism. One vertex is origin; the diametrically opposite vertex is origin + size.
size: 3x1 array.

polliwog.tri.shapes.
create_triangular_prism
(p1, p2, p3, height, ret_unique_vertices_and_faces=False)[source]¶ Return vertices (or unique verties and faces) of a triangular prism whose base is the triangle p1, p2, p3. If the vertices are oriented in a counterclockwise direction, the prism extends from behind them.
Imported from lace.