xslope 0.1.5__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xslope/_version.py +1 -1
- xslope/mesh.py +97 -21
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/METADATA +1 -1
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/RECORD +8 -8
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/LICENSE +0 -0
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/NOTICE +0 -0
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/WHEEL +0 -0
- {xslope-0.1.5.dist-info → xslope-0.1.6.dist-info}/top_level.txt +0 -0
xslope/_version.py
CHANGED
xslope/mesh.py
CHANGED
|
@@ -1235,14 +1235,8 @@ def build_polygons(slope_data, reinf_lines=None, debug=False):
|
|
|
1235
1235
|
if max_depth is None:
|
|
1236
1236
|
raise ValueError("When using only 1 profile line, max_depth must be specified")
|
|
1237
1237
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
# Sort profile lines from top to bottom by average y
|
|
1242
|
-
sorted_lines = sorted(profile_lines, key=get_avg_y, reverse=True)
|
|
1243
|
-
n = len(sorted_lines)
|
|
1244
|
-
# Deep copy so we can insert points
|
|
1245
|
-
lines = [list(line) for line in copy.deepcopy(sorted_lines)]
|
|
1238
|
+
n = len(profile_lines)
|
|
1239
|
+
lines = [list(line) for line in copy.deepcopy(profile_lines)]
|
|
1246
1240
|
tol = 1e-8
|
|
1247
1241
|
|
|
1248
1242
|
for i in range(n - 1):
|
|
@@ -1282,7 +1276,7 @@ def build_polygons(slope_data, reinf_lines=None, debug=False):
|
|
|
1282
1276
|
if not found:
|
|
1283
1277
|
insert_idx = np.searchsorted(xs_lower, x_top)
|
|
1284
1278
|
lower.insert(insert_idx, (round(x_top, 6), round(y_proj, 6)))
|
|
1285
|
-
|
|
1279
|
+
|
|
1286
1280
|
def clean_polygon(poly, tol=1e-8):
|
|
1287
1281
|
# Remove consecutive duplicate points (except for closing point)
|
|
1288
1282
|
if not poly:
|
|
@@ -1304,25 +1298,107 @@ def build_polygons(slope_data, reinf_lines=None, debug=False):
|
|
|
1304
1298
|
ys_top = np.array(ys_top)
|
|
1305
1299
|
left_x, left_y = xs_top[0], ys_top[0]
|
|
1306
1300
|
right_x, right_y = xs_top[-1], ys_top[-1]
|
|
1301
|
+
|
|
1302
|
+
# Initialize variables for debug output
|
|
1303
|
+
lower_left_x = None
|
|
1304
|
+
lower_right_x = None
|
|
1305
|
+
proj_left_x = None
|
|
1306
|
+
proj_right_x = None
|
|
1307
|
+
bottom_cleaned = []
|
|
1307
1308
|
|
|
1308
1309
|
if i < n - 1:
|
|
1310
|
+
# Use the immediate next line as the lower boundary
|
|
1309
1311
|
lower_line = lines[i + 1]
|
|
1310
1312
|
xs_bot, ys_bot = zip(*lower_line)
|
|
1311
1313
|
xs_bot = np.array(xs_bot)
|
|
1312
1314
|
ys_bot = np.array(ys_bot)
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
#
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1315
|
+
lower_left_x = xs_bot[0]
|
|
1316
|
+
lower_right_x = xs_bot[-1]
|
|
1317
|
+
|
|
1318
|
+
# Collect actual points from all lower lines within the top line's x-range
|
|
1319
|
+
# But only include a point if it's actually on the highest lower profile at that x
|
|
1320
|
+
bottom_points = [] # List of (x, y, line_idx) tuples
|
|
1321
|
+
|
|
1322
|
+
for j in range(i + 1, n):
|
|
1323
|
+
lower_candidate = lines[j]
|
|
1324
|
+
xs_cand = np.array([x for x, y in lower_candidate])
|
|
1325
|
+
ys_cand = np.array([y for x, y in lower_candidate])
|
|
1326
|
+
|
|
1327
|
+
# Only include points that are within the top line's x-range
|
|
1328
|
+
mask = (xs_cand >= left_x - tol) & (xs_cand <= right_x + tol)
|
|
1329
|
+
for x, y in zip(xs_cand[mask], ys_cand[mask]):
|
|
1330
|
+
# Check if this point is actually on the highest lower profile at this x
|
|
1331
|
+
# Compare with all other lower lines at this x-coordinate
|
|
1332
|
+
is_highest = True
|
|
1333
|
+
for k in range(i + 1, n):
|
|
1334
|
+
if k == j:
|
|
1335
|
+
continue
|
|
1336
|
+
other_line = lines[k]
|
|
1337
|
+
xs_other = np.array([x_o for x_o, y_o in other_line])
|
|
1338
|
+
ys_other = np.array([y_o for x_o, y_o in other_line])
|
|
1339
|
+
if xs_other[0] - tol <= x <= xs_other[-1] + tol:
|
|
1340
|
+
y_other = np.interp(x, xs_other, ys_other)
|
|
1341
|
+
if y_other > y + tol: # Other line is higher
|
|
1342
|
+
is_highest = False
|
|
1343
|
+
break
|
|
1344
|
+
|
|
1345
|
+
if is_highest:
|
|
1346
|
+
bottom_points.append((x, y, j))
|
|
1347
|
+
|
|
1348
|
+
# Group by x-coordinate (within tolerance) and keep only the highest y at each x
|
|
1349
|
+
# This handles cases where multiple lines have points at the same x
|
|
1350
|
+
bottom_dict = {} # x_key -> (y, line_idx, orig_x, orig_y)
|
|
1351
|
+
for x, y, line_idx in bottom_points:
|
|
1352
|
+
x_key = round(x / tol) * tol # Round to tolerance to group nearby points
|
|
1353
|
+
if x_key not in bottom_dict or y > bottom_dict[x_key][0]:
|
|
1354
|
+
bottom_dict[x_key] = (y, line_idx, x, y)
|
|
1355
|
+
|
|
1356
|
+
# Convert to sorted list
|
|
1357
|
+
bottom_cleaned = sorted([(orig_x, orig_y) for _, _, orig_x, orig_y in bottom_dict.values()])
|
|
1358
|
+
|
|
1359
|
+
# Project endpoints - find highest lower profile or use max_depth
|
|
1360
|
+
left_y_bot = -np.inf
|
|
1361
|
+
right_y_bot = -np.inf
|
|
1362
|
+
for j in range(i + 1, n):
|
|
1363
|
+
lower_candidate = lines[j]
|
|
1364
|
+
xs_cand = np.array([x for x, y in lower_candidate])
|
|
1365
|
+
ys_cand = np.array([y for x, y in lower_candidate])
|
|
1366
|
+
if xs_cand[0] - tol <= left_x <= xs_cand[-1] + tol:
|
|
1367
|
+
y_cand = np.interp(left_x, xs_cand, ys_cand)
|
|
1368
|
+
if y_cand > left_y_bot:
|
|
1369
|
+
left_y_bot = y_cand
|
|
1370
|
+
if xs_cand[0] - tol <= right_x <= xs_cand[-1] + tol:
|
|
1371
|
+
y_cand = np.interp(right_x, xs_cand, ys_cand)
|
|
1372
|
+
if y_cand > right_y_bot:
|
|
1373
|
+
right_y_bot = y_cand
|
|
1374
|
+
|
|
1375
|
+
# If no lower profile at endpoints, use max_depth
|
|
1376
|
+
if left_y_bot == -np.inf:
|
|
1377
|
+
left_y_bot = max_depth if max_depth is not None else -np.inf
|
|
1378
|
+
if right_y_bot == -np.inf:
|
|
1379
|
+
right_y_bot = max_depth if max_depth is not None else -np.inf
|
|
1380
|
+
|
|
1381
|
+
# Build bottom boundary: right projection, intermediate points (right to left), left projection
|
|
1382
|
+
# The bottom should go from right to left to close the polygon
|
|
1321
1383
|
bottom = []
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1384
|
+
|
|
1385
|
+
# Start with right endpoint
|
|
1386
|
+
if right_y_bot != -np.inf:
|
|
1387
|
+
bottom.append((right_x, right_y_bot))
|
|
1388
|
+
|
|
1389
|
+
# Add intermediate points in reverse order (right to left)
|
|
1390
|
+
# Filter out points too close to endpoints
|
|
1391
|
+
for x, y in reversed(bottom_cleaned):
|
|
1392
|
+
if abs(x - left_x) > tol and abs(x - right_x) > tol:
|
|
1393
|
+
bottom.append((x, y))
|
|
1394
|
+
|
|
1395
|
+
# End with left endpoint
|
|
1396
|
+
if left_y_bot != -np.inf:
|
|
1397
|
+
bottom.append((left_x, left_y_bot))
|
|
1398
|
+
|
|
1399
|
+
# Store for debug output
|
|
1400
|
+
proj_left_x = left_x
|
|
1401
|
+
proj_right_x = right_x
|
|
1326
1402
|
else:
|
|
1327
1403
|
# For the lowest polygon, bottom is at max_depth
|
|
1328
1404
|
# Only need endpoints - no intermediate points
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
xslope/__init__.py,sha256=ZygAIkX6Nbjag1czWdQa-yP-GM1mBE_9ss21Xh__JFc,34
|
|
2
|
-
xslope/_version.py,sha256=
|
|
2
|
+
xslope/_version.py,sha256=El5otyOm5tn7_NTNUcawnWQ_lZMwfYOTw_-GGhANHSI,50
|
|
3
3
|
xslope/advanced.py,sha256=35k_ekQJ-mQJ1wHnoIHMc5TVfYn-2EPCJyHz827Cpbc,18281
|
|
4
4
|
xslope/fem.py,sha256=K4_Pq06HFBpRkN3JwtXF2zw_AMnCkXvj0ggrlRFMQQw,115731
|
|
5
5
|
xslope/fileio.py,sha256=DnFUYmJedjKXOuVPZUfTRxGfTjiIz8KyHkRDK7ddQg0,28840
|
|
6
6
|
xslope/global_config.py,sha256=Cj8mbPidIuj5Ty-5cZM-c8H12kNvyHsk5_ofNGez-3M,2253
|
|
7
|
-
xslope/mesh.py,sha256=
|
|
7
|
+
xslope/mesh.py,sha256=OhaAMlunbO86Sx4iF5sRsk4eEN7-AG-_TYPUvYVTGA4,122513
|
|
8
8
|
xslope/plot.py,sha256=rr1D-6KzYyJtq51o4yLyaFkowBa1LtygIk9rtA3GxgQ,54592
|
|
9
9
|
xslope/plot_fem.py,sha256=al9zjqjxWKooLl4SAds77Zz-j9cjD4TJGygyU9QK5vo,71111
|
|
10
10
|
xslope/plot_seep.py,sha256=3wbKp85cmK_6EniFnK9x-FaZtYBZ3KZbRn9U1GsInmk,28775
|
|
@@ -12,9 +12,9 @@ xslope/search.py,sha256=dvgKn8JCobuvyD7fClF5lcbeHESCvV8gZ_U_lQnYRok,16867
|
|
|
12
12
|
xslope/seep.py,sha256=zVX8NJOp8e6VJ6y99YLkmOh_RPQFly9Z9UI3tka6yQQ,85765
|
|
13
13
|
xslope/slice.py,sha256=QHawTk7XPLziHoN_ZS0jrEPYKlhPT62caUc_q-_EGjs,45236
|
|
14
14
|
xslope/solve.py,sha256=j7N66QBjBpDAo-aizTiP8auwd5Ey1SiYAYeySaMVzkw,48554
|
|
15
|
-
xslope-0.1.
|
|
16
|
-
xslope-0.1.
|
|
17
|
-
xslope-0.1.
|
|
18
|
-
xslope-0.1.
|
|
19
|
-
xslope-0.1.
|
|
20
|
-
xslope-0.1.
|
|
15
|
+
xslope-0.1.6.dist-info/LICENSE,sha256=NU5J88FUai_4Ixu5DqOQukA-gcXAyX8pXLhIg8OB3AM,10969
|
|
16
|
+
xslope-0.1.6.dist-info/METADATA,sha256=8eM1VvzchbN-xSlSrTzbRMX86Vy2L3WDUVrdt3_BJq4,2027
|
|
17
|
+
xslope-0.1.6.dist-info/NOTICE,sha256=E-sbN0MWwvJC27Z-2_G4VUHIx4IsfvLDTmOstvY4-OQ,530
|
|
18
|
+
xslope-0.1.6.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
|
|
19
|
+
xslope-0.1.6.dist-info/top_level.txt,sha256=5qHbWJ1R2pdTNIainFyrVtFk8R1tRcwIn0kzTuwuV1Q,7
|
|
20
|
+
xslope-0.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|