def test_project_point_plane(point, point_plane, normal_plane, point_expected, dist_expected): plane = Plane(point_plane, normal_plane) point_projected = plane.project_point(point) distance_signed = plane.distance_point_signed(point) assert point_projected.is_close(point_expected) assert math.isclose(distance_signed, dist_expected)
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
(Line([0, 0], [0, 1]), Line([0, 0], [0, 5])), (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, 1, 1]), Line([0, 1, 0], [-1, 0, 0])), ], ) def test_intersect_lines_failure(line_a, line_b): with pytest.raises(Exception): line_a.intersect_line(line_b) @pytest.mark.parametrize( "line, plane, array_expected", [ (Line([0, 0, 0], [1, 0, 0]), Plane([0, 0, 0], [1, 0, 0]), [0, 0, 0]), (Line([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [0, 0, 1]), [0, 0, 0]), (Line([5, -3, 0], [0, 0, 1]), Plane([0, 0, 0], [0, 0, 1]), [5, -3, 0]), ], ) def test_intersect_line_plane(line, plane, array_expected): point_intersection = plane.intersect_line(line) assert point_intersection.is_close(array_expected) @pytest.mark.parametrize( "line, plane", [ (Line([0, 0, 0], [1, 0, 0]), Plane([0, 0, 0], [0, 0, 1])), (Line([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [1, 0, 0])),
""" Vector-Plane Projection ======================= Project a vector onto a plane. """ from skspatial.objects import Plane from skspatial.objects import Vector from skspatial.plotting import plot_3d plane = Plane([0, 0, 0], [0, 0, 1]) vector = Vector([1, 1, 1]) vector_projected = plane.project_vector(vector) _, ax = plot_3d( plane.plotter(lims_x=(-5, 5), lims_y=(-5, 5), alpha=0.3), vector.plotter(point=plane.point, color='k'), vector_projected.plotter(point=plane.point, color='r', linewidth=2, zorder=3), ) ax.set_zlim([-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), (Plane([0, 0, 0], [0, 0, 1]), [[25, 3, 2], [-6, 5, 0]], 4), (Plane([0, 0, 0], [0, 0, 5]), [[25, 3, 2], [-6, 5, 0]], 4), (Plane([0, 0, 0], [0, 0, -5]), [[25, 3, 2], [-6, 5, 0]], 4), ], ) def test_sum_squares_plane(plane, points, error_expected): error = plane.sum_squares(points) assert math.isclose(error, error_expected) @pytest.mark.parametrize( "points, line_expected",
""" 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), )
@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): assert repr(obj_spatial) == repr_expected
import pytest from skspatial._functions import _allclose from skspatial.objects import Plane @pytest.mark.parametrize( "point_a, point_b, point_c, plane_expected", [ ([0, 0], [1, 0], [0, 1], Plane([0, 0, 0], [0, 0, 1])), # The spacing between the points is irrelevant. ([0, 0], [9, 0], [0, 9], Plane([0, 0, 0], [0, 0, 1])), # The first point is used as the plane point. ([0, 0.1], [1, 0], [0, 1], Plane([0, 0.1, 0], [0, 0, 1])), # The order of points is relevant. ([0, 0], [0, 1], [1, 0], Plane([0, 0, 0], [0, 0, -1])), ], ) def test_from_points(point_a, point_b, point_c, plane_expected): plane = Plane.from_points(point_a, point_b, point_c) assert plane.point.is_close(plane_expected.point) assert plane.is_close(plane_expected) @pytest.mark.parametrize( "point_a, point_b, point_c", [ # The points cannot be collinear. ([0, 0], [0, 0], [0, 0]),
def fit_mt_main_fault(well_dict, section='all', function='thin_plate_spline'): fault_depths = { 'D1': (14.34, 19.63), 'D2': (11.04, 16.39), 'D3': (17.98, 20.58), 'D4': (27.05, 28.44), 'D5': (19.74, 22.66), 'D6': (28.5, 31.4), 'D7': (22.46, 25.54), 'B2': (41.25, 45.65), 'B1': (34.8, 42.25), 'B9': (None, 55.7), 'B10': (17.75, 21.7), '1': (38.15, 45.15), '2': (44.23, 49.62), '3': (38.62, 43.39) } if section == 'FS': fault_depths = {k: fault_depths[k] for k in ('1', '2', '3')} elif section == 'FSB': fault_depths = { k: fault_depths[k] for k in fault_depths.keys() if k[0] == 'B' } elif section == 'CSD': fault_depths = { k: fault_depths[k] for k in fault_depths.keys() if k[0] == 'D' } elif section == 'west': fault_depths = { k: fault_depths[k] for k in fault_depths.keys() if k[0] == 'D' or k in ('B2') } elif section == 'east': fault_depths = { k: fault_depths[k] for k in fault_depths.keys() if k[0] == 'B' or k in ('1', '2', '3') } elif section == 'all': pass else: print('Section {} is invalid'.format(section)) return print('Section: {}'.format(section)) # Do best fit plane tops = [ depth_to_xyz(well_dict, well, d[0]) for well, d in fault_depths.items() if d[0] and well in fault_depths ] bottoms = [ depth_to_xyz(well_dict, well, d[1]) for well, d in fault_depths.items() if well in fault_depths ] A_top = np.array(tops).T A_bot = np.array(bottoms).T c_top = A_top.sum(axis=1) / A_top.shape[1] c_bot = A_top.sum(axis=1) / A_top.shape[1] # Top first u, s, v = np.linalg.svd(A_top - c_top[:, np.newaxis]) # Lsqr quadratic fit X, Y = np.meshgrid(np.arange(np.min(A_top[0, :]), np.max(A_top[0, :]), 2), np.arange(np.min(A_top[1, :]), np.max(A_top[1, :]), 2)) tops_array = np.array(tops) spline = Rbf(tops_array[:, 0], tops_array[:, 1], tops_array[:, 2], function=function, smooth=0) Z = spline(X, Y) u1, u2, u3 = u[:, -1] if u3 < 0: easting = u2 else: easting = -u2 if u3 > 0: northing = u1 else: northing = -u1 dip = np.rad2deg(np.arctan(np.sqrt(easting**2 + northing**2) / u3)) if easting >= 0: partA_strike = easting**2 + northing**2 strike = np.rad2deg(np.arccos(northing / np.sqrt(partA_strike))) else: partA_strike = northing / np.sqrt(easting**2 + northing**2) strike = np.rad2deg(2 * np.pi - np.arccos(partA_strike)) print('SVD strike Top: {}'.format(strike)) print('SVD dip Top: {}'.format(dip)) # Now bottom u, s, v = np.linalg.svd(A_bot - c_bot[:, np.newaxis]) u1, u2, u3 = u[:, -1] if u3 < 0: easting = u2 else: easting = -u2 if u3 > 0: northing = u1 else: northing = -u1 dip = np.rad2deg(np.arctan(np.sqrt(easting**2 + northing**2) / u3)) if easting >= 0: partA_strike = easting**2 + northing**2 strike = np.rad2deg(np.arccos(northing / np.sqrt(partA_strike))) else: partA_strike = northing / np.sqrt(easting**2 + northing**2) strike = np.rad2deg(2 * np.pi - np.arccos(partA_strike)) print('SVD strike Bottom: {}'.format(strike)) print('SVD dip Bottom: {}'.format(dip)) # Now compute fit for all possible planes dips = np.arange(90) strikes = np.arange(360) dip_rads = np.deg2rad(dips) strike_rads = np.deg2rad(strikes) S, D = np.meshgrid(strike_rads, dip_rads) # Normal to plane a = np.sin(D.flatten()) * np.cos(S.flatten()) # East b = -np.sin(D.flatten()) * np.sin(S.flatten()) # North c = np.cos(D.flatten()) c_top = c_top.squeeze() planes = [ Plane(point=c_top.squeeze(), normal=np.array([a[i], b[i], c[i]])) for i in range(a.shape[0]) ] rmss = np.array([ np.sqrt(np.mean([p.distance_point_signed(t)**2 for t in tops])) for p in planes ]) rmss = rmss.reshape(S.shape) print('Gridsearch Strike: {}'.format( np.rad2deg(S.flatten()[np.argmin(rmss)]))) print('Grid search Dip: {}'.format(np.rad2deg( D.flatten()[np.argmin(rmss)]))) print('Grid search RMS: {}'.format(np.min(rmss))) fig = plt.figure() ax = fig.add_subplot(projection='3d') ax.plot_surface(np.rad2deg(S), np.rad2deg(D), rmss, cmap='viridis') ax.set_xlabel('Strike [deg]') ax.set_ylabel('Dip [deg]') ax.set_zlabel('RMS for plane [meters]') plt.show() return X, Y, Z
import pytest from skspatial.objects import Plane, Sphere, Points @pytest.mark.parametrize( "plane, points_expected", [ (Plane([0, 0, 0], [0, 0, 1]), [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0]]), (Plane([1, 0, 0], [0, 0, 1]), [[0, -1, 0], [2, -1, 0], [0, 1, 0], [2, 1, 0]]), (Plane([0, 0, 0], [0, 0, -1]), [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0]]), (Plane([0, 0, 0], [0, 0, 5]), [[-1, -1, 0], [1, -1, 0], [-1, 1, 0], [1, 1, 0]]), (Plane([0, 0, 0], [0, 1, 0]), [[-1, 0, -1], [1, 0, -1], [-1, 0, 1], [1, 0, 1]]), (Plane([0, 0, 0], [1, 0, 0]), [[0, -1, -1], [0, 1, -1], [0, -1, 1], [0, 1, 1]]), (Plane([0, 0, 0], [1, 1, 0]), [[-1, 1, -1], [1, -1, -1], [-1, 1, 1], [1, -1, 1]]), ], ) def test_plane_points(plane, points_expected): points = plane.to_points() assert points.is_close(points_expected)
(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( "plane, point, value_expected", [ (Plane([0, 0], [1, 1]), [2, 2], 1), (Plane([0, 0], [1, 1]), [0, 0], 0), (Plane([0, 1], [1, 1]), [0, 0], -1), (Plane([0, 0, 0], [1, 0, 0]), [0, 0, 0], 0), (Plane([0, 0, 0], [1, 0, 0]), [1, 0, 0], 1), (Plane([0, 0, 0], [1, 0, 0]), [-1, 0, 0], -1), (Plane([0, 0, 0], [1, 0, 0]), [25, 53, -105], 1), (Plane([0, 0, 0], [1, 0, 0]), [-2, 53, -105], -1), (Plane([0, 0, 0], [1, 0, 0]), [0, 38, 19], 0), (Plane([0, 0, 0], [1, 0, 0]), [0, 101, -45], 0), (Plane([0, 0, 0], [-1, 0, 0]), [1, 0, 0], -1), (Plane([5, 0, 0], [1, 0, 0]), [1, 0, 0], -1), ], ) def test_side_point_plane(plane, point, value_expected):
""" Plane-Plane Intersection ======================== """ from skspatial.objects import Plane from skspatial.plotting import plot_3d plane_a = Plane([0, 0, 0], [1, 0, 0]) plane_b = Plane([0, 0, 0], [1, 0, 1]) line_intersection = plane_a.intersect_plane(plane_b) plot_3d( plane_a.plotter(alpha=0.2), plane_b.plotter(alpha=0.2), line_intersection.plotter(t_1=-1, c='k'), )
import math import pytest from skspatial._functions import _allclose from skspatial.objects import Line from skspatial.objects import Plane from skspatial.objects import Points @pytest.mark.parametrize( ("array_point", "array_a", "array_b", "plane_expected"), [ ([0, 0], [1, 0], [0, 1], Plane([0, 0, 0], [0, 0, 1])), ([1, 2], [1, 0], [0, 1], Plane([1, 2, 0], [0, 0, 1])), ([0, 0], [0, 1], [1, 0], Plane([0, 0, 0], [0, 0, -1])), ([0, 0], [2, 0], [0, 1], Plane([0, 0, 0], [0, 0, 2])), ([0, 0], [2, 0], [0, 2], Plane([0, 0, 0], [0, 0, 4])), ([1, 2, 3], [2, 0], [0, 2], Plane([1, 2, 3], [0, 0, 4])), ([-3, 2, 6], [1, 4, 6], [-1, 5, 8], Plane([-3, 2, 6], [2, -14, 9])), ], ) def test_from_vectors(array_point, array_a, array_b, plane_expected): plane = Plane.from_vectors(array_point, array_a, array_b) assert plane.is_close(plane_expected) # Also ensure that the vector is exactly as expected. assert plane.vector.is_close(plane_expected.vector)
with pytest.raises( ValueError, match="The point and vector must have the same dimension."): class_spatial(point, vector) @pytest.mark.parametrize( "obj_1, obj_2, bool_expected", [ (Line([0, 0], [1, 0]), Line([0, 0], [1, 0]), True), (Line([0, 0], [1, 0]), Line([1, 0], [1, 0]), True), (Line([0, 0], [1, 0]), Line([-5, 0], [1, 0]), True), (Line([0, 0], [1, 0]), Line([-5, 0], [7, 0]), True), (Line([0, 0], [1, 0]), Line([-5, 0], [-20, 0]), True), (Line([0, 0], [1, 0]), Line([-5, 1], [1, 0]), False), (Plane([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [0, 0, 1]), True), (Plane([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [0, 0, 2]), True), (Plane([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [0, 0, -10]), True), (Plane([0, 0, 0], [0, 0, 1]), Plane([0, 0, 0], [1, 0, -10]), False), (Line([0, 0], [1, 0]), Plane([0, 0], [1, 0]), None), (Plane([0, 0], [1, 0]), Line([0, 0], [1, 0]), None), ], ) def test_is_close(obj_1, obj_2, bool_expected): if bool_expected is None: with pytest.raises( TypeError, match="The input must have the same type as the object."): obj_1.is_close(obj_2)
(Line([-6, 7], [5, 90]), Line([1, 4], [-4, 5]), True), (Line([0, 0, 1], [1, 1, 0]), Line([0, 0, 0], [0, 1, 0]), False), (Line([0, 0, 1], [1, 1, 0]), Line([0, 0, 1], [0, 1, 0]), True), (Line([0, 0, 1], [1, 0, 1]), Line([0, 0, 1], [2, 0, 2]), True), ], ) def test_is_coplanar(line_a, line_b, bool_expected): assert line_a.is_coplanar(line_b) == bool_expected @pytest.mark.parametrize( ("line_a", "line_b"), [ (Line([0, 0], [1, 1]), Point([0, 0])), (Line([0, 0, 0], [1, 1, 0]), Plane([0, 0, 0], [0, 0, 1])), ], ) def test_is_coplanar_failure(line_a, line_b): message_expected = "The input must also be a line." with pytest.raises(TypeError, match=message_expected): line_a.is_coplanar(line_b) @pytest.mark.parametrize( ("point", "point_line", "vector_line", "point_expected", "dist_expected"), [ ([0, 5], [0, 0], [0, 1], [0, 5], 0), ([0, 5], [0, 0], [0, 100], [0, 5], 0),
(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]), (Plane([0, 0, 0], [0, 0, 1]), [1, 1, 1], [1, 1, 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(plane, vector, vector_expected): vector_projected = plane.project_vector(vector) assert vector_projected.is_close(vector_expected) @pytest.mark.parametrize( "circle, point, point_expected", [ (Circle([0, 0], 1), [1, 0], [1, 0]),
""" Point-Plane Projection ====================== Project a point onto a plane. """ from skspatial.objects import Plane from skspatial.objects import Point from skspatial.objects import Vector from skspatial.plotting import plot_3d plane = Plane(point=[0, 0, 2], normal=[1, 0, 2]) point = Point([5, 9, 3]) point_projected = plane.project_point(point) vector_projection = Vector.from_points(point, point_projected) plot_3d( plane.plotter(lims_x=(0, 10), lims_y=(0, 15), alpha=0.3), point.plotter(s=75, c='k'), point_projected.plotter(c='r', s=75, zorder=3), vector_projection.plotter(point=point, c='k', linestyle='--'), )
[ ([0, 0], Line([0, 0], [1, 0]), 0), ([8, 7], Line([0, 0], [1, 0]), 7), ([20, -3], Line([0, 0], [1, 0]), 3), ([20, -3, 1], Line([0, 0, 0], [1, 0, 0]), math.sqrt(10)), ], ) def test_distance_point_line(array_point, line, dist_expected): assert math.isclose(line.distance_point(array_point), dist_expected) @pytest.mark.parametrize( "point, plane, dist_signed_expected", [ ([0, 0, 0], Plane([0, 0, 0], [0, 0, 1]), 0), ([50, -67, 0], Plane([0, 0, 0], [0, 0, 1]), 0), ([50, -67, 0], Plane([0, 0, 1], [0, 0, 1]), -1), ([5, 3, 8], Plane([0, 0, 0], [0, 0, 1]), 8), ([5, 3, 7], Plane([0, 0, 0], [0, 0, -50]), -7), ([5, 3, -8], Plane([0, 0, 0], [0, 0, 1]), -8), ], ) def test_distance_point_plane(point, plane, dist_signed_expected): assert math.isclose(plane.distance_point_signed(point), dist_signed_expected) assert math.isclose(plane.distance_point(point), abs(dist_signed_expected)) @pytest.mark.parametrize(