def test_to_points(cylinder, n_along_axis, n_angles, points_expected): array_rounded = cylinder.to_points(n_along_axis=n_along_axis, n_angles=n_angles).round(3) points_unique = Points(array_rounded).unique() assert points_unique.is_close(points_expected)
def test_dimension_failure(array, dimension): message_expected = "The desired dimension cannot be less than the current dimension." points = Points(array) with pytest.raises(ValueError, match=message_expected): points.set_dimension(dimension)
def test_mean_center(array_points, array_centered_expected, centroid_expected): points = Points(array_points) points_centered, centroid = points.mean_center(return_centroid=True) assert isinstance(points_centered, Points) assert isinstance(centroid, Point) assert_array_almost_equal(points_centered, array_centered_expected) assert_array_almost_equal(centroid, centroid_expected)
def fit_plane_scipy(P=None): from skspatial.objects import Points, Plane from skspatial.plotting import plot_3d points = Points([[0, 0, 0], [1, 3, 5], [-5, 6, 3], [3, 6, 7], [-2, 6, 7] ]) if P is None else Points(P) plane = Plane.best_fit(points) plot_3d( points.plotter(c='k', s=0.1, depthshade=False), plane.plotter(alpha=0.8, lims_x=(-5, 5), lims_y=(-5, 5)), ) plt.show()
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
def test_best_fit(points, sphere_expected): points = Points(points) sphere_fit = Sphere.best_fit(points) assert sphere_fit.point.is_close(sphere_expected.point, abs_tol=1e-9) assert math.isclose(sphere_fit.radius, sphere_expected.radius)
def test_best_fit_plane(points, plane_expected): points = Points(points).set_dimension(3) plane_fit = Plane.best_fit(points) assert plane_fit.is_close(plane_expected) assert plane_fit.point.is_close(plane_expected.point)
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 multi_points(draw, dim): """ Return a strategy which generates Points objects. Parameters ---------- dim : int Dimension of the object. Returns ------- LazyStrategy Hypothesis strategy. Examples -------- >>> from hypothesis import find >>> from tests.property.strategies import multi_points >>> find(multi_points(2), lambda x: len(x) == 3) Points([[0., 0.], [0., 0.], [0., 0.]]) """ n_points = draw(st.integers(min_value=1, max_value=50)) array_like_2d = [draw(arrays_fixed(dim)) for _ in range(n_points)] return Points(array_like_2d)
def test_best_fit(points, circle_expected): points = Points(points) circle_fit = Circle.best_fit(points) assert circle_fit.point.is_close(circle_expected.point, abs_tol=1e-9) assert math.isclose(circle_fit.radius, circle_expected.radius)
def triangles(draw, dim): """ Return a strategy which generates Triangle objects. Parameters ---------- dim : int Dimension of the object. Returns ------- LazyStrategy Hypothesis strategy. Examples -------- >>> from hypothesis import find >>> from tests.property.strategies import triangles >>> find(triangles(dim=2), lambda x: True) Triangle(point_a=Point([0., 0.]), point_b=Point([0. , 0.001]), point_c=Point([0.001, 0. ])) """ point_a = draw(arrays_fixed(dim)) point_b = draw(arrays_fixed(dim)) point_c = draw(arrays_fixed(dim)) assume(not Points([point_a, point_b, point_c]).are_collinear(tol=1)) return Triangle(point_a, point_b, point_c)
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 area_signed(points: array_like) -> float: """ Return the signed area of a simple polygon given the 2D coordinates of its veritces. The signed area is computed using the shoelace algorithm. A positive area is returned for a polygon whose vertices are given by a counter-clockwise sequence of points. Parameters ---------- points : array_like Input 2D points. Returns ------- area_signed : float The signed area of the polygon. Raises ------ ValueError If the points are not 2D. If there are fewer than three points. References ---------- https://en.wikipedia.org/wiki/Shoelace_formula https://alexkritchevsky.com/2018/08/06/oriented-area.html https://rosettacode.org/wiki/Shoelace_formula_for_polygonal_area#Python Examples -------- >>> from skspatial.measurement import area_signed >>> area_signed([[0, 0], [1, 0], [0, 1]]) 0.5 >>> area_signed([[0, 0], [0, 1], [1, 0]]) -0.5 >>> area_signed([[0, 0], [0, 1], [1, 2], [2, 1], [2, 0]]) -3.0 """ points = Points(points) n_points = points.shape[0] if points.dimension != 2: raise ValueError("The points must be 2D.") if n_points < 3: raise ValueError("There must be at least 3 points.") X = points[:, 0] Y = points[:, 1] indices = np.arange(n_points) indices_offset = indices - 1 return 0.5 * np.sum(X[indices_offset] * Y[indices] - X[indices] * Y[indices_offset])
def test_from_points(arrays): points = Points(arrays) assume(not points.are_collinear(tol=1)) # The plane must contain each point. plane = Plane.from_points(*points) points = points.set_dimension(plane.dimension) for point in points: assert plane.contains_point(point, abs_tol=ATOL) # The plane of best fit should be the same # as the plane from three points. plane_fit = Plane.best_fit(points) assert plane_fit.is_close(plane, abs_tol=ATOL)
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 test_best_fit_plane(data): n_points = data.draw(st.integers(min_value=3, max_value=5)) points = Points([data.draw(arrays_fixed(3)) for _ in range(n_points)]) assume(not points.are_collinear(tol=ATOL)) plane_fit = Plane.best_fit(points) # The best fit plane could have a higher dimension than the points # (e.g., 2D points have a 3D plane of best fit). # So, we convert the points dimension to that of the best fit plane. dim_fit = plane_fit.dimension points = points.set_dimension(dim_fit) plane = data.draw(planes(dim_fit)) error_plane = plane.sum_squares(points) error_fit = plane_fit.sum_squares(points) assert error_fit <= error_plane + ATOL
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 compute(self): if len(self.points) < 3 or self.origin is None or self.vector is None: return points = Points(self.points) self.plane = Plane.best_fit(points) self.vector = np.array(self.plane.project_point(self.vector)) self.origin = np.array(self.plane.project_point(self.origin)) self.xAxis = self.normalizeVector(self.vector - self.origin) self.normal = np.array(self.plane.normal) a = np.argmax(np.abs(self.normal)) if self.normal[a] < 0: self.normal *= -1 self.zAxis = self.normalizeVector(self.normal) self.yAxis = -np.cross(self.xAxis, self.zAxis) self.vectorBasis = [self.xAxis, self.yAxis, self.zAxis] self.quaternion = self.get_quaternion( [[1, 0, 0], [0, 1, 0], [0, 0, 1]], self.vectorBasis)
[0, 1], [0, 1, 2], ], ) def test_failure(array): message_expected = "The array must be 2D." with pytest.raises(ValueError, match=message_expected): Points(array) @pytest.mark.parametrize( ("points", "dim_expected"), [ (Points([[0, 0], [1, 1]]), 2), (Points([[0, 0], [0, 0], [0, 0]]), 2), (Points([[0, 0, 1], [1, 2, 1]]), 3), (Points([[4, 3, 9, 1], [3, 7, 8, 1]]), 4), ], ) def test_dimension(points, dim_expected): assert points.dimension == dim_expected @pytest.mark.parametrize( ("points", "dim", "points_expected"), [ (Points([[0, 0], [1, 1]]), 3, Points([[0, 0, 0], [1, 1, 0]])), (Points([[0, 0], [1, 1]]), 4, Points([[0, 0, 0, 0], [1, 1, 0, 0]])),
def test_are_collinear(points, bool_expected): """Test checking if multiple points are collinear.""" assert Points(points).are_collinear() == bool_expected
""" 3D Plane of Best Fit ==================== Fit a plane to multiple 3D points. """ from skspatial.objects import Plane from skspatial.objects import Points from skspatial.plotting import plot_3d points = Points([[0, 0, 0], [1, 3, 5], [-5, 6, 3], [3, 6, 7], [-2, 6, 7]]) plane = Plane.best_fit(points) plot_3d( points.plotter(c='k', s=50, depthshade=False), plane.plotter(alpha=0.2, lims_x=(-5, 5), lims_y=(-5, 5)), )
pts_rec = np.array(pts_rec) new_world=np.array(new_world) new_corners_rec=np.array(new_corners_rec) # Montrer les cibles # Sur la carte de profondeur plt.figure() plt.imshow(depth_map) plt.plot(new_corners_rec[:,0,0], new_corners_rec[:,0,1], 'r.') plt.show() # -------------------------------------------------------------------------- # 3. Évaluer la planéité --------------------------------------------------- # 3.1 Trouver l'équation du plan points = Points(pts_rec) plane = Plane.best_fit(points) a,b,c,d = plane.cartesian() x = pts_rec[:,0] y = pts_rec[:,1] z = pts_rec[:,2] X = np.linspace(x.min()*0.8, x.max()*1.3) Y = np.linspace(y.min()*0.8, y.max()*1.3) X, Y = np.meshgrid(X, Y) Z = -(d + a*X + b*Y)/c # Montrer le plan fig = plt.figure() ax = fig.add_subplot(111, projection='3d')
def test_volume_tetrahedron(arrays): volume = volume_tetrahedron(*arrays) if math.isclose(volume, 0): assert Points(arrays).are_coplanar(tol=ATOL)
def test_area_triangle(arrays): area = area_triangle(*arrays) if math.isclose(area, 0): assert Points(arrays).are_collinear(tol=ATOL)
def test_failure(array): message_expected = "The array must be 2D." with pytest.raises(ValueError, match=message_expected): Points(array)
from skspatial.objects import Points, Plane from skspatial.plotting import plot_3d import matplotlib.pyplot as plt import numpy as np from PIL import Image from mpl_toolkits.mplot3d import Axes3D all_data = np.loadtxt('111.txt') print(all_data) print(all_data.shape) cordi = all_data[:, 0:3] color = all_data[:, 3::] # print(color) points = Points(cordi) plane = Plane.best_fit(points) print(type(plane.point), plane.point) print(list(plane.point), list(plane.normal), 'dddddd') list_normal = np.array(list(plane.normal)) lens_ = list_normal / np.sqrt(np.sum(list_normal**2, axis=0)) print(lens_, "模长") point_projected = plane.project_point(cordi[0]) print(cordi[0]) print(len(cordi)) cordi_after = np.zeros_like(cordi)
def test_normalize_distance(array_points, array_points_expected): points_normalized = Points(array_points).normalize_distance() assert_array_almost_equal(points_normalized, array_points_expected)
def test_area_signed(points, area_expected): points = Points(points) area = area_signed(points) assert area == area_expected
""" 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), )
from skspatial.objects import Triangle 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)"), ], )