def test_project_point_line(point, point_line, vector_line, point_expected, dist_expected): line = Line(point_line, vector_line) point_projected = line.project_point(point) distance = line.distance_point(point) assert point_projected.is_close(point_expected) assert math.isclose(distance, dist_expected)
def test_from_points(objs): point_a, vector = objs point_b = point_a + vector line = Line(point_a, vector) line_from_points = Line.from_points(point_a, point_b) assert line.is_close(line_from_points, abs_tol=ATOL) # The line of best fit should be the same # as the line from two points. line_fit = Line.best_fit([point_a, point_b]) assert line_fit.is_close(line_from_points, abs_tol=ATOL)
def project_on_vector(L, R, M): '''gets left and closest Right and measured points, returns projection on the vector btw. R&L of M''' line = Line(point = L[0:2], direction=R[0:2]) point = Point(M[0:2]) line_const = line2pts(L, R) point_projected = line.project_point(point) line_projection = Line.from_points(point, point_projected) result = {"Point" : point_projected, "Line" : line_projection, "Distance": distance_pt2line(line_const["m"], line_const["b"], M[0:2])} return result
def get_next_line(self, point): self.past_points.append(point) if len(self.past_points) > self.MAX_POINT: self.past_points.popleft() self.last_time = time.time() if len(self.past_points) == self.MAX_POINT: max_movement = 0 for pt2, pt1 in zip(list(self.past_points)[1:], list(self.past_points)[:-1]): movement = np.linalg.norm(pt2 - pt1) if movement > max_movement: max_movement = movement if (max_movement / (time.time() - self.last_time)) < 0.1: return None points = Points(list(self.past_points)) line_fit = Line.best_fit(points) direction = np.array(line_fit.direction) # I defined this side will be the positive direction. if direction[0] < 0: direction *= -1 direction = direction / np.linalg.norm(direction) return direction else: return None
def fit_line_direction(points): direction = list() for frame in range(0, len(points)): points_ = Points(np.reshape(np.array(points[frame, :]), (-1, 3))) line_fit = Line.best_fit(points_) direction.append(np.array(line_fit.direction)) return np.array(direction)
def test_are_collinear(arrays): array_a, array_b, array_c = arrays assert Points([array_a, array_a, array_a]).are_collinear(tol=ATOL) assert Points([array_a, array_a, array_b]).are_collinear(tol=ATOL) all_different = not (Point(array_a).is_close(array_b, abs_tol=ATOL) or Point(array_b).is_close(array_c, abs_tol=ATOL)) if Points([array_a, array_b, array_c]).are_collinear() and all_different: line_ab = Line.from_points(array_a, array_b) line_bc = Line.from_points(array_b, array_c) assert line_ab.contains_point(array_c, abs_tol=ATOL) assert line_bc.contains_point(array_a, abs_tol=ATOL) assert line_ab.is_coplanar(line_bc)
def Reorient_Planes(plane_list,npoints): #using plane with most orient the rest i= np.where(npoints == np.max(npoints))[0][0] signs = np.sign(plane_list[i].normal) orient_line = Line(plane_list[i].normal,plane_list[i].point) newplane = [] for i in range(len(plane_list)): normalvector = np.abs(np.array(plane_list[i].normal))*signs points = np.array(plane_list[i].intersect_line(orient_line)) newplane.append(Plane(points,normalvector)) return newplane
def get_distance(plane_list,index): dappend = [] for j in range(1,len(plane_list)): i = index[j] im1 = index[j-1] normalline = Line(plane_list[im1].point,direction = plane_list[0].normal) # print(plane_list[i-1].point) p0 = np.array(plane_list[im1].point) intersection_point = np.array(plane_list[i].intersect_line(normalline)) distance = np.sqrt(np.sum((intersection_point-p0)**2)) dappend.append(distance) return dappend
def regression(centers=[]): points = Points(centers) #convert data line_fit = Line.best_fit(points) #take line of best fit p = line_fit.point v = line_fit.direction p0 = p - p[2] * v / v[2] #initial center v0 = v / v[2] #initial direction new_centers = [] #linearized centers i = z1 #start with first full slice while i <= end: #end with last full slice pn = p0 + i * v0 #next center new_centers.append(pn) i += 1 return new_centers
def test_best_fit_line(data): n_points = data.draw(st.integers(min_value=2, max_value=5)) dim = data.draw(st.integers(min_value=2, max_value=4)) points = Points([data.draw(arrays_fixed(dim)) for _ in range(n_points)]) assume(not points.are_concurrent(tol=ATOL)) line = data.draw(lines(dim)) line_fit = Line.best_fit(points) error_line = line.sum_squares(points) error_fit = line_fit.sum_squares(points) assert error_fit <= error_line + ATOL
import math import numpy as np import pytest from skspatial.objects import Line, Plane, Circle, Sphere @pytest.mark.parametrize( "line_a, line_b, array_expected", [ (Line([0, 0], [1, 0]), Line([0, 0], [1, 1]), [0, 0]), (Line([0, 0], [1, 0]), Line([5, 5], [1, 1]), [0, 0]), (Line([0, 0], [1, 0]), Line([9, 0], [1, 1]), [9, 0]), (Line([0, 0], [1, 1]), Line([4, 0], [1, -1]), [2, 2]), (Line([0, 0, 0], [1, 1, 1]), Line([4, 4, 0], [-1, -1, 1]), [2, 2, 2]), ], ) def test_intersect_lines(line_a, line_b, array_expected): point_intersection = line_a.intersect_line(line_b) assert point_intersection.is_close(array_expected) @pytest.mark.parametrize( "line_a, line_b", [ (Line([0, 0], [1, 0]), Line([0, 0], [1, 0])), (Line([0, 0], [1, 0]), Line([5, 5], [1, 0])), (Line([0, 0], [0, 1]), Line([0, 0], [0, 5])), (Line([0, 0], [1, 0]), Line([0, 0], [-1, 0])),
""" 3D Vector-Line Projection ========================= Project a vector onto a line. """ from skspatial.objects import Vector, Line from skspatial.plotting import plot_3d line = Line([0, 0, 0], [1, 1, 2]) vector = Vector([1, 1, 0.1]) vector_projected = line.project_vector(vector) plot_3d( line.plotter(t_1=-1, c='k', linestyle='--'), vector.plotter(point=line.point, color='k'), vector_projected.plotter(point=line.point, color='r', linewidth=2, zorder=3), )
def test_best_fit_line(points, line_expected): line_fit = Line.best_fit(np.array(points)) assert line_fit.is_close(line_expected) assert line_fit.point.is_close(line_expected.point)
def test_best_fit_line_failure(points): with pytest.raises(Exception): Line.best_fit(points)
[ ([[1, 0], [-1, 0], [0, 1], [0, 0]], "The points must be 3D."), ([[2, 0, 0], [-2, 0, 0], [0, 2, 0]], "There must be at least 4 points."), ([[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0]], "The points must not be in a plane."), ], ) def test_best_fit_failure(points, message_expected): with pytest.raises(ValueError, match=message_expected): Sphere.best_fit(points) @pytest.mark.parametrize( ("sphere", "line", "point_a_expected", "point_b_expected"), [ (Sphere([0, 0, 0], 1), Line([0, 0, 0], [1, 0, 0]), [-1, 0, 0], [1, 0, 0]), ( Sphere([0, 0, 0], 1), Line([0, 0, 0], [1, 1, 0]), -sqrt(2) / 2 * np.array([1, 1, 0]), sqrt(2) / 2 * np.array([1, 1, 0]), ), ( Sphere([0, 0, 0], 1), Line([0, 0, 0], [1, 1, 1]), -sqrt(3) / 3 * np.ones(3), sqrt(3) / 3 * np.ones(3), ), (Sphere([1, 0, 0], 1), Line([0, 0, 0], [1, 0, 0]), [0, 0, 0], [2, 0, 0]), (Sphere([0, 0, 0], 1), Line([1, 0, 0], [0, 0, 1]), [1, 0, 0], [1, 0, 0]), ],
(Plane([0, 0, 0], [0, 0, 1]), [7, -5, 20], [7, -5, 0]), (Plane([0, 0, 0], [0, 0, -10]), [7, -5, 20], [7, -5, 0]), ], ) def test_project_vector(plane, vector, vector_expected): vector_projected = plane.project_vector(vector) assert vector_projected.is_close(vector_expected) @pytest.mark.parametrize( ("plane", "line", "line_expected"), [ ( Plane([0, 0, 0], [0, 0, 1]), Line([0, 0, 0], [1, 0, 0]), Line([0, 0, 0], [1, 0, 0]), ), ( Plane([0, 0, 0], [0, 0, 1]), Line([0, 0, 5], [1, 0, 0]), Line([0, 0, 0], [1, 0, 0]), ), ( Plane([0, 0, 0], [0, 0, 1]), Line([2, 3, -5], [1, 0, 0]), Line([2, 3, 0], [1, 0, 0]), ), ( Plane([0, 0, 0], [1, 0, 0]), Line([1, 0, 0], [0, 1, 0]),
[ ([[1, 0, 0], [-1, 0, 0], [0, 1, 0]], "The points must be 2D."), ([[2, 0], [-2, 0]], "There must be at least 3 points."), ([[0, 0], [1, 1], [2, 2]], "The points must not be collinear."), ], ) def test_best_fit_failure(points, message_expected): with pytest.raises(ValueError, match=message_expected): Circle.best_fit(points) @pytest.mark.parametrize( ("circle", "line", "point_a_expected", "point_b_expected"), [ (Circle([0, 0], 1), Line([0, 0], [1, 0]), [-1, 0], [1, 0]), (Circle([0, 0], 1), Line([0, 0], [0, 1]), [0, -1], [0, 1]), (Circle([0, 0], 1), Line([0, 1], [1, 0]), [0, 1], [0, 1]), ( Circle([0, 0], 1), Line([0, 0.5], [1, 0]), [-math.sqrt(3) / 2, 0.5], [math.sqrt(3) / 2, 0.5], ), (Circle([1, 0], 1), Line([0, 0], [1, 0]), [0, 0], [2, 0]), (Circle([1.5, 0], 1), Line([0, 0], [1, 0]), [0.5, 0], [2.5, 0]), ], ) def test_intersect_line(circle, line, point_a_expected, point_b_expected): point_a, point_b = circle.intersect_line(line)
[sqrt(2) / 2, sqrt(2) / 2, 0], True, ), ], ) def test_cylinder_is_point_within(cylinder, point, bool_expected): assert cylinder.is_point_within(point) == bool_expected @pytest.mark.parametrize( ("cylinder", "line", "array_expected_a", "array_expected_b"), [ ( Cylinder([0, 0, 0], [0, 0, 1], 1), Line([0, 0, 0], [1, 0, 0]), [-1, 0, 0], [1, 0, 0], ), ( Cylinder([0, 0, 0], [0, 0, 1], 1), Line([0, 0, 0.5], [1, 0, 0]), [-1, 0, 0.5], [1, 0, 0.5], ), ( Cylinder([0, 0, 0], [0, 0, 1], 2), Line([0, 0, 0], [1, 0, 0]), [-2, 0, 0], [2, 0, 0], ),
""" 2D Point-Line Projection ======================== Project a point onto a line. """ from skspatial.objects import Point, Line from skspatial.plotting import plot_2d line = Line(point=[0, 0], direction=[1, 1]) point = Point([1, 4]) point_projected = line.project_point(point) line_projection = Line.from_points(point, point_projected) _, ax = plot_2d( line.plotter(t_2=5, c='k'), line_projection.plotter(c='k', linestyle='--'), point.plotter(s=75, c='k'), point_projected.plotter(c='r', s=75, zorder=3), ) ax.axis('equal')
""" Circle-Line Intersection ======================== """ from skspatial.objects import Circle, Line from skspatial.plotting import plot_2d circle = Circle([0, 0], 5) line = Line([0, 0], [1, 1]) point_a, point_b = circle.intersect_line(line) _, ax = plot_2d( circle.plotter(fill=False), line.plotter(t_1=-5, t_2=5, c='k'), point_a.plotter(c='r', s=100, edgecolor='k', zorder=3), point_b.plotter(c='r', s=100, edgecolor='k', zorder=3), ) ax.axis('equal')
""" 2D Line-Line Intersection ========================= """ from skspatial.objects import Line from skspatial.plotting import plot_2d line_a = Line(point=[0, 0], direction=[1, 1.5]) line_b = Line(point=[5, 0], direction=[-1, 1]) point_intersection = line_a.intersect_line(line_b) plot_2d( line_a.plotter(t_1=3), line_b.plotter(t_1=4), point_intersection.plotter(c='k', s=75, zorder=3), )
is_right: bool list_test_cases = [ TriangleTester( points=[[0, 0], [1, 0], [0, 1]], area=0.5, perimeter=2 + sqrt(2), lengths=(sqrt(2), 1, 1), angles=(90, 45, 45), centroid=[1 / 3, 1 / 3], orthocenter=[0, 0], normal=[0, 0, 1], classification='isosceles', is_right=True, altitudes=(Line([0, 0], [0.5, 0.5]), Line([1, 0], [-1, 0]), Line([0, 1], [0, -1])), ), TriangleTester( points=[[0, 0], [1, 1], [2, 0]], area=1, perimeter=2 + 2 * sqrt(2), lengths=(sqrt(2), 2, sqrt(2)), angles=(45, 90, 45), centroid=[1, 1 / 3], orthocenter=[1, 1], normal=[0, 0, -2], classification='isosceles', is_right=True, altitudes=(Line([0, 0], [1, 1]), Line([1, 1], [0, -1]), Line([2, 0], [-1, 1])),
""" 3D Line-Line Intersection ========================= """ from skspatial.objects import Line from skspatial.plotting import plot_3d line_a = Line(point=[0, 0, 0], direction=[1, 1, 1]) line_b = Line(point=[1, 1, 0], direction=[-1, -1, 1]) point_intersection = line_a.intersect_line(line_b) plot_3d( line_a.plotter(), line_b.plotter(), point_intersection.plotter(c='k', s=75), )
from skspatial.objects import Vector @pytest.mark.parametrize( ("obj_spatial", "repr_expected"), [ (Point([0]), "Point([0])"), (Point([0, 0]), "Point([0, 0])"), (Point([0.5, 0]), "Point([0.5, 0. ])"), (Point([-11, 0]), "Point([-11, 0])"), (Vector([-11, 0]), "Vector([-11, 0])"), (Vector([-11.0, 0.0]), "Vector([-11., 0.])"), (Vector([0, 0]), "Vector([0, 0])"), (Vector([0.5, 0]), "Vector([0.5, 0. ])"), (Points([[1.5, 2], [5, 3]]), "Points([[1.5, 2. ],\n [5. , 3. ]])"), (Line([0, 0], [1, 0]), "Line(point=Point([0, 0]), direction=Vector([1, 0]))"), (Line([-1, 2, 3], [5, 4, 2]), "Line(point=Point([-1, 2, 3]), direction=Vector([5, 4, 2]))"), (Line(np.zeros(2), [1, 0]), "Line(point=Point([0., 0.]), direction=Vector([1, 0]))"), (Plane([0, 0], [1, 0]), "Plane(point=Point([0, 0]), normal=Vector([1, 0]))"), (Plane([-1, 2, 3], [5, 4, 2]), "Plane(point=Point([-1, 2, 3]), normal=Vector([5, 4, 2]))"), (Circle([0, 0], 1), "Circle(point=Point([0, 0]), radius=1)"), (Circle([0, 0], 2.5), "Circle(point=Point([0, 0]), radius=2.5)"), (Sphere([0, 0, 0], 1), "Sphere(point=Point([0, 0, 0]), radius=1)"), ( Triangle([0, 0], [0, 1], [1, 0]), "Triangle(point_a=Point([0, 0]), point_b=Point([0, 1]), point_c=Point([1, 0]))", ), (Cylinder([0, 0, 0], [0, 0, 1], 1), "Cylinder(point=Point([0, 0, 0]), vector=Vector([0, 0, 1]), radius=1)"), ], ) def test_repr(obj_spatial, repr_expected):
""" Sphere-Line Intersection ======================== """ from skspatial.objects import Sphere, Line from skspatial.plotting import plot_3d sphere = Sphere([0, 0, 0], 1) line = Line([0, 0, 0], [1, 1, 1]) point_a, point_b = sphere.intersect_line(line) plot_3d( line.plotter(t_1=-1, c='k'), sphere.plotter(alpha=0.2), point_a.plotter(c='r', s=100), point_b.plotter(c='r', s=100), )
""" Plane-Line Intersection ======================= """ from skspatial.objects import Line, Plane from skspatial.plotting import plot_3d plane = Plane(point=[0, 0, 0], normal=[1, 1, 1]) line = Line(point=[-1, -1, 0], direction=[0, 0, 1]) point_intersection = plane.intersect_line(line) plot_3d( plane.plotter(lims_x=[-2, 2], lims_y=[-2, 2], alpha=0.2), line.plotter(t_2=5), point_intersection.plotter(c='k', s=75), )
# The projection of the zero vector onto v is the zero vector. ([0, 0], [0, 1], [0, 0]), ], ) def test_project_vector(vector_u, vector_v, vector_expected): """Test projecting vector u onto vector v.""" vector_u_projected = Vector(vector_v).project_vector(vector_u) assert vector_u_projected.is_close(vector_expected) @pytest.mark.parametrize( "line, vector, vector_expected", [ (Line([0, 0], [1, 0]), [1, 1], [1, 0]), (Line([-56, 72], [1, 0]), [1, 1], [1, 0]), (Line([-56, 72], [200, 0]), [5, 9], [5, 0]), (Line([-56, 72], [200, 0]), [-5, 9], [-5, 0]), ], ) def test_project_vector_line(line, vector, vector_expected): vector_projected = line.project_vector(vector) assert vector_projected.is_close(vector_expected) @pytest.mark.parametrize( "plane, vector, vector_expected", [ (Plane([0, 0, 0], [0, 0, 1]), [1, 1, 0], [1, 1, 0]),
import math import numpy as np import pytest from skspatial.objects import Line, Plane, Points @pytest.mark.parametrize( "line, points, error_expected", [ (Line([0, 0], [1, 0]), [[0, 0], [10, 0]], 0), (Line([0, 0], [5, 0]), [[0, 0], [0, 1]], 1), (Line([0, 0], [1, 0]), [[0, 1], [0, -1]], 2), (Line([0, 0], [1, 0]), [[0, 5]], 25), (Line([0, 0], [1, 0]), [[0, 3], [0, -2]], 13), (Line([0, 0], [-20, 0]), [[1, 3], [2, -2], [3, -5]], 38), ], ) def test_sum_squares_line(line, points, error_expected): error = line.sum_squares(points) assert math.isclose(error, error_expected) @pytest.mark.parametrize( "plane, points, error_expected", [ (Plane([0, 0, 0], [0, 0, 1]), [[25, 3, 0], [-6, 5, 0]], 0), (Plane([25, 9, 0], [0, 0, 1]), [[25, 3, 0], [-6, 5, 0]], 0), (Plane([25, 9, -2], [0, 0, 1]), [[25, 3, 0], [-6, 5, 0]], 8),
""" 3D Line of Best Fit =================== Fit a line to multiple 3D points. """ from skspatial.objects import Line from skspatial.objects import Points from skspatial.plotting import plot_3d points = Points([ [0, 0, 0], [1, 1, 0], [2, 3, 2], [3, 2, 3], [4, 5, 4], [6, 5, 5], [6, 6, 5], [7, 6, 7], ], ) line_fit = Line.best_fit(points) plot_3d( line_fit.plotter(t_1=-7, t_2=7, c='k'), points.plotter(c='b', depthshade=False), )
], ) def test_side_vector(array_a, array_b, value_expected): if value_expected is None: with pytest.raises(ValueError): Vector(array_a).side_vector(array_b) else: assert Vector(array_a).side_vector(array_b) == value_expected @pytest.mark.parametrize( "line, point, value_expected", [ (Line([0, 0], [0, 1]), [0, 0], 0), (Line([0, 0], [0, 1]), [1, 0], 1), (Line([0, 0], [0, 1]), [1, 1], 1), (Line([0, 0], [0, 1]), [1, 10], 1), (Line([0, 0], [0, 1]), [1, -10], 1), (Line([0, 0], [0, 1]), [-1, 0], -1), (Line([0, 0], [0, 1]), [-1, 1], -1), (Line([0, 0], [0, 1]), [-1, -25], -1), ], ) def test_side_point_line(line, point, value_expected): assert line.side_point(point) == value_expected @pytest.mark.parametrize(