Package: scikit-spatial
IntroductionThis package provides spatial objects based on NumPy arrays, as well as computations using these objects. The package includes computations for 2D, 3D, and higher-dimensional space.The following spatial objects are provided:PointPointsVectorLineLineSegmentPlaneCircleSphereTriangleCylinderMost of the computations fall into the following categories:MeasurementComparisonProjectionIntersectionFittingTransformationAll spatial objects are equipped with plotting methods based onmatplotlib. Both 2D and 3D plotting are supported. Spatial computations can be easily visualized by plotting multiple objects at once.Why this instead ofscipy.spatialorsympy.geometry?This package has little to no overlap with the functionality ofscipy.spatial. It can be viewed as an object-oriented extension.While similar spatial objects and computations exist in thesympy.geometrymodule,scikit-spatialis based on NumPy rather than symbolic math. The primary objects ofscikit-spatial(Point,Points, andVector) are actually subclasses of the NumPyndarray. This gives them all the regular functionality of thendarray, plus additional methods from this package.>>> from skspatial.objects import Vector>>> vector = Vector([2, 0, 0])Behaviour inherited from NumPy:>>> vector.size
3
>>> vector.mean().round(3)
0.667Additional methods fromscikit-spatial:>>> vector.norm()
2.0
>>> vector.unit()
Vector([1., 0., 0.])PointandVectorare based on a 1D NumPy array, andPointsis based on a 2D NumPy array, where each row represents a point in space.  TheLineandPlaneobjects havePointandVectorobjects as attributes.Note that most methods inherited from NumPy return a regularndarray, instead of the spatial object class.>>> vector.sum()
array(2)This is to avoid getting a spatial object with a forbidden shape, like a zero dimensionVector. Trying to convert this back to aVectorcauses an exception.>>> Vector(vector.sum())
Traceback (most recent call last):
...
ValueError: The array must be 1D.Because the computations ofscikit-spatialare also based on NumPy, keyword arguments can be passed to NumPy functions. For example, a tolerance can be specified while testing for collinearity. Thetolkeyword is passed tonumpy.linalg.matrix_rank.>>> from skspatial.objects import Points>>> points = Points([[1, 2, 3], [4, 5, 6], [7, 8, 8]])>>> points.are_collinear()
False
>>> points.are_collinear(tol=1)
TrueInstallationThe package can be installed with pip.$pipinstallscikit-spatialIt can also be installed with conda.$condainstallscikit-spatial-cconda-forgeExample UsageMeasurementMeasure the cosine similarity between two vectors.>>> from skspatial.objects import Vector>>> Vector([1, 0]).cosine_similarity([1, 1]).round(3)
0.707ComparisonCheck if multiple points are collinear.>>> from skspatial.objects import Points>>> points = Points([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])>>> points.are_collinear()
TrueProjectionProject a point onto a line.>>> from skspatial.objects import Line>>> line = Line(point=[0, 0, 0], direction=[1, 1, 0])>>> line.project_point([5, 6, 7])
Point([5.5, 5.5, 0. ])IntersectionFind the intersection of two planes.>>> from skspatial.objects import Plane>>> plane_a = Plane(point=[0, 0, 0], normal=[0, 0, 1])
>>> plane_b = Plane(point=[5, 16, -94], normal=[1, 0, 0])>>> plane_a.intersect_plane(plane_b)
Line(point=Point([5., 0., 0.]), direction=Vector([0, 1, 0]))An error is raised if the computation is undefined.>>> plane_b = Plane(point=[0, 0, 1], normal=[0, 0, 1])>>> plane_a.intersect_plane(plane_b)
Traceback (most recent call last):
...
ValueError: The planes must not be parallel.FittingFind the plane of best fit for multiple points.>>> points = [[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]>>> Plane.best_fit(points)
Plane(point=Point([0.5, 0.5, 0. ]), normal=Vector([0., 0., 1.]))TransformationTransform multiple points to 1D coordinates along a line.>>> line = Line(point=[0, 0, 0], direction=[1, 2, 0])
>>> points = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]>>> line.transform_points(points).round(3)
array([ 2.236,  6.261, 10.286])AcknowledgmentThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.