def test_project(): v = np.array([5.0, -3.0, 1.0]) onto = np.array([0, -1.0, 0]) expected_s = 3.0 expected_v = np.array([0, -3.0, 0]) np.testing.assert_array_almost_equal(vg.scalar_projection(v, onto=onto), expected_s) np.testing.assert_array_almost_equal(vg.project(v, onto=onto), expected_v) with pytest.raises( ValueError, match=r"onto must be an array with shape \(3,\); got \(2, 3\)"): vg.project(v, onto=np.array([vg.basis.x, vg.basis.x]))
def test_project_stacked_vs(): vs = np.array([[5.0, -3.0, 1.0], [1.0, 0, 1.0], [0.0, 1, 0.0], [0.0, 0, 0.0]]) onto = np.array([0, -1.0, 0]) expected_s = np.array([3.0, 0.0, -1.0, 0]) expected_v = np.array([[0.0, -3.0, 0.0], [0.0, 0, 0.0], [0.0, 1.0, 0.0], [0.0, 0, 0.0]]) np.testing.assert_array_almost_equal(vg.scalar_projection(vs, onto=onto), expected_s) np.testing.assert_array_almost_equal(vg.project(vs, onto=onto), expected_v)
def project_to_line(points, reference_points_of_lines, vectors_along_lines): k = check_shape_any(points, (3, ), (-1, 3), name="points") check_shape_any( reference_points_of_lines, (3, ), (-1 if k is None else k, 3), name="reference_points_of_lines", ) vg.shape.check(locals(), "vectors_along_lines", reference_points_of_lines.shape) return reference_points_of_lines + vg.project( points - reference_points_of_lines, onto=vectors_along_lines)
def project_point_to_line(points, reference_points_of_lines, vectors_along_lines): """ Project a point to a line, or pairwise project a stack of points to a stack of lines. """ k = check_shape_any(points, (3,), (-1, 3), name="points") check_shape_any( reference_points_of_lines, (3,), (-1 if k is None else k, 3), name="reference_points_of_lines", ) vg.shape.check(locals(), "vectors_along_lines", reference_points_of_lines.shape) return reference_points_of_lines + vg.project( points - reference_points_of_lines, onto=vectors_along_lines )
def oriented_along(self, along, reverse=False): """ Flip the polyline, if necessary, so that it points (approximately) along the second vector rather than (approximately) opposite it. """ if self.is_closed: raise ValueError("Can't reorient a closed polyline") vg.shape.check(locals(), "along", (3,)) if self.num_v < 2: return self extent = self.v[-1] - self.v[0] projected = vg.project(extent, onto=along) if vg.scale_factor(projected, along) * (-1 if reverse else 1) < 0: return self.copy().flip() else: return self
def aligned_with(self, vector): """ Flip the polyline if necessary, so it's aligned with the given vector rather than against it. Works on open polylines and considers only the two end vertices. """ if self.is_closed: raise ValueError("Can't align a closed polyline") vg.shape.check(locals(), "vector", (3, )) if self.num_v < 2: return self extent = self.v[-1] - self.v[0] projected = vg.project(extent, onto=vector) if vg.scale_factor(projected, vector) < 0: return self.flipped() else: return self
def test_project_error(): with pytest.raises(ValueError, match="Not sure what to do with 3 dimensions"): vg.project(np.array([[[5.0, -3.0, 1.0]]]), onto=np.array([0, -1.0, 0]))