A collection of plotter-friendly utilities.
The dependencies of this package depend on each module. The basic requirements for all modules are NumPy, SciPy and Matplotlib.
polyhonsoup.svgdepends on svgpathtools- It is suggested to install the latest version with
pip install git+https://github.com/mathandy/svgpathtools.git
- It is suggested to install the latest version with
polygonsoup.clipperdepends on the PyClipper package.- It can be installed with
conda install -c conda-forge pyclipperif using conda- or
pip install pyclipperif using pip.
- It can be installed with
polygonsoup.limbdepends on the KinPy package, which in turn depends on VTK. The latest version of KinPy can be installed with pip through:pip install git+https://github.com/neka-nat/kinpy.git- If using Anaconda, it is suggested to first install VTK with
conda install -c conda-forge vtk
- The
polygonsoup.vtk_utilsmodule and the relevant examples depend on VTK. - The
polygonsoup.plotters.AxiPlotterclass depends on the axi Python package. Follow the instructions at the link to install. - The
polygonsoup.imagingmodule depends on OpenCV.
To install locally use
pip install -e .
From the py directory in the repository. This will create a symbolic link to the location of the py/polygonsoup directory, allowing a user to modify the source code if necessary.
Plotters basically can just trace 2D lines, so the main objects in this package
are a polylines. Points, vectors, and matrices are represented as NumPy arrays.
Polylines are represented as a list of points, or optionally as a N*D
ndarray, where N is the number of points and D is the number of
coordinates (2 or 3 for a 3D polyline). A compound polyline is a list of polylines.
The geom module contains utilities to process polylines (compound or not), as
well as basic homogeneous transformation matrices. Points, polylines and
compound polylines can be transformed with the same geom.affine_transform
function. Creating a point or a vector can be done with the geom.vec function,
which is simply a shorthand for creating a numpy array with its arguments. For
example vec(0, 3) is equivalent to np.array([0, 3]). These are examples of 2d points, polylines and compound polylines:
from polygonsoup.geom import vec # a 2d point p = vec(0,0) # A polyline (a closed square) P = [p, vec(10, 0), vec(10, 10), vec(0, 10), p] # or P = np.array([p, vec(10, 0), vec(10, 10), vec(0, 10), p]) # A compound polyline (the square and one diagonal) S = [P, [p, vec(10,10)]]
Polylines can be specified as either lists of points or numpy arrays. While lists can be handy to concatenate points, the preferred format is numpy arrays with points as rows (e.g. a 10x2 array for 10 points) and many functions in this module will return this format.
This module also contains a basic line-based 3d graphics
pipeline, which is implemented in the geom.view_3d function. The function
transforms 3d polylines into 2d ones, given a view and a projection matrix. The
projection can be either a perspective projection (geom.perspective) or
parallel projection (geom.parallel).
The plut module enables visualisation and plotting of polylines with the same interface.
Visualisation is done through matplotlib, while plotting is done with different interfaces exposed in the plotters module. Polylines and compound polylines can be plotted with the plot.stroke function. A barebones visualisation example of a polyline is the following:
import polygonsoup.plot as plut
import numpy as np
plut.figure('A5') # Create a figure with A5 size
plut.stroke(np.random.uniform(-5, 5, (2, 10)))
plut.show()
This displays a random 2D polyline with 10 points. The code between figure and show can contain common matplotlib calls. These will be displayed in the resulting image, but not on the drawing made by the plotter.
The same module provides a plut.show_drawing function. This takes an axi.Drawing as an input and allows to plot and visualise outputs generated with the axi package. As an example of the use of this function refer to examples/axi_lsystem.py. A similar approach can be used to easily convert (and plot) the other nice examples in axi.
This module exposes interfaces that allow plotting with AxiDraw. These can be passed with the plotter argument to the plot.figure function, which will also send the polylines following the call to the plotter. The AxiPlotter class requires an AxiDraw to be connected to the computer, and uses the axi package for communicating with the plotter. The AxiDrawClient connects to a running instance of the axidraw_server script. The NoPlotter class is the default, which is used to display graphics only. This can be useful when testing the output of a script.
As an example, plotting the minimal example above when connected to an AxiDraw can be done with:
import polygonsoup.plot as plot
import polygonsoup.plotters as plotters
import numpy as np
plot.figure('A5', plotter=plotters.AxiPlotter()) # Create a figure with A5 size, send to AxiPlotter
plot.stroke(np.random.uniform(-5, 5, (2, 10)))
plot.show()
This module provides utilities to clip or to perform boolean operations with polylines. It simply wraps the Clipper library and requires the PyClipper package to be installed. See examples/boolean_ops.py for a usage example.
This module contains utilities to generate Bezier curves.
This module provides utilities to load SVG files. To load a file as a compound polyline:
import polygonsoup.svg as svg
S = svg.load_svg('filename.svg')
See examples/svg_example.py for a usage example.
This module implements hatching, which can be used to “fill” a shape with lines. The input to the method is assumed to be closed, and filling of compound shapes follows the “Even-odd” rule. See examples/cubes_hatch.py for a usage example.
This module exposes some of the functionalities of the Visualization Toolkit (VTK), a powerful library for 3d geometry processing. See examples/vtk_contour_lines.py and examples/vtk_silhouette.py for usage examples.
The limb module provides utilities to perform forward and inverse kinematics on
a kinematic chain. The chain can be loaded from a URDF or SDF file with the
limb.Limb class. The module wraps relies on the KinPy package for loading,
forward kinematics and Jacobian computation, while the Limb class provides two
functions to compute inverse kinematics (ik and ik_soft).
See examples/forward_kinematics.py and examples/inverse_kinematics.py for usage examples.