def test_euclidean_distance_mixed(): v1s = np.array([[1, 1, 0], [-1, 0, 0], [0, 0, 5]]) v2 = np.array([2, -1, 5]) expected = np.array([ math.sqrt(1**2 + 2**2 + 5**2), math.sqrt(3**2 + 1**2 + 5**2), math.sqrt(2**2 + 1**2), ]) np.testing.assert_array_almost_equal(vg.euclidean_distance(v1s, v2), expected) np.testing.assert_array_almost_equal(vg.euclidean_distance(v2, v1s), expected)
def extent(points, ret_indices=False): """ Find the distance between the two farthest-most points. Args: points (np.arraylike): A `kx3` stack of points. ret_indices (bool): When `True`, return the indices along with the distance. Returns: object: With `ret_indices=False`, the distance; with `ret_indices=True` a tuple `(distance, first_index, second_index)`. Note: This is implemented using a brute-force method. """ k = vg.shape.check(locals(), "points", (-1, 3)) if k < 2: raise ValueError("At least two points are required") farthest_i = -1 farthest_j = -1 farthest_distance = -1 for i, probe in enumerate(points): distances = vg.euclidean_distance(points, probe) this_farthest_j = np.argmax(distances) if distances[this_farthest_j] > farthest_distance: farthest_i = i farthest_j = this_farthest_j farthest_distance = distances[this_farthest_j] if ret_indices: return farthest_distance, farthest_i, farthest_j else: return farthest_distance
def test_euclidean_distance(): v1 = np.array([1, 1, 0]) v2 = np.array([2, -1, 5]) expected = math.sqrt(1**2 + 2**2 + 5**2) result = vg.euclidean_distance(v1, v2) np.testing.assert_almost_equal(result, expected) assert isinstance(result, float)
def segment_lengths(self): """ The length of each of the segments. """ if self.e is None: return np.zeros(0) else: segments = self.segments return vg.euclidean_distance(segments[:, 0], segments[:, 1])
def test_euclidean_distance_stacked(): v1s = np.array([[1, 1, 0], [-1, 0, 0], [0, 0, 5]]) v2s = np.array([[2, -1, 5], [3, 4, 0], [-1, 0, 6]]) expected = np.array([ math.sqrt(1**2 + 2**2 + 5**2), math.sqrt(4**2 + 4**2), math.sqrt(1**2 + 1**2), ]) np.testing.assert_array_almost_equal(vg.euclidean_distance(v1s, v2s), expected)
def segment_lengths(self): """ The length of each of the segments. """ if self.e is None: return np.zeros(0) else: v1s = self.v[self.e[:, 0]] v2s = self.v[self.e[:, 1]] return vg.euclidean_distance(v1s, v2s)
def nearest(self, points, ret_segment_indices=False): """ 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. """ from .._common.shape import columnize from ..segment import closest_point_of_line_segment points, _, transform_result = columnize(points, name="points") num_points = len(points) stacked_points = np.repeat(points, self.num_e, axis=0) closest_points_of_segments = closest_point_of_line_segment( points=stacked_points, start_points=np.tile(self.segments[:, 0], (num_points, 1)), segment_vectors=np.tile(self.segment_vectors, (num_points, 1)), ) distance_to_closest_points_of_segments = vg.euclidean_distance( stacked_points, closest_points_of_segments) closest_points_of_segments = closest_points_of_segments.reshape( num_points, self.num_e, 3) distance_to_closest_points_of_segments = distance_to_closest_points_of_segments.reshape( num_points, self.num_e) indices_of_nearest_segments = np.argmin( distance_to_closest_points_of_segments, axis=1) closest_points_of_polyline = np.take_along_axis( closest_points_of_segments, indices_of_nearest_segments.reshape(num_points, 1, 1), axis=1, ).reshape(num_points, 3) if ret_segment_indices: return ( transform_result(closest_points_of_polyline), transform_result(indices_of_nearest_segments), ) else: return transform_result(closest_points_of_polyline)