upxo.geoEntities.sline3d module
3D straight line geometric entity module for UPXO.
Provides two 3-D straight-line classes — a lean variant for minimal memory footprint and a full-featured class for geometric operations.
Applications
Non-conformal to conformal geometry conversion.
Hierarchical grain structure feature generation.
General 3-D geometry operations.
Classes
- Sline3d_leanest
Minimal 3-D line stored as six scalar endpoint coordinates.
- Sline3d
Full-featured 3-D line with geometric properties and spatial operations.
Coordinate system
Y+
| Z-
| /
| /
| /
| /
X- | / X+
-----------------O------------------
/|
/ |
/ |
/ |
/ |
/ |
Z+ Y-
Usage
from upxo.geoEntities.sline3d import Sline3d as sl3d
from upxo.geoEntities.sline3d import Sline3d_leanest as sl3dl
@author: Dr. Sunil Anandatheertha
- class upxo.geoEntities.sline3d.Sline3d_leanest(x0=0, y0=0, z0=0, x1=1, y1=0, z1=0)[source]
Bases:
objectLean 3-D straight line storing only six scalar endpoint coordinates.
Provides a minimal footprint for high-frequency operations where only coordinate access, length, and iteration are required.
Usage
from upxo.geoEntities.sline3d import Sline3d_leanest as sl3dl
Examples
from upxo.geoEntities.sline3d import Sline3d_leanest as sl3dl e = sl3dl(-2, 3, 4, 5, 1, 2) for coord in e: print(coord) print(e[1])
- x0
- y0
- z0
- x1
- y1
- z1
- property length
Euclidean length of the line segment.
- class upxo.geoEntities.sline3d.Sline3d(x0=0, y0=0, z0=0, x1=1, y1=0, z1=0, pnta=None, pntb=None)[source]
Bases:
objectFull-featured 3-D straight line entity for UPXO geometric operations.
Stores a straight line segment by its two endpoint coordinates
(x0, y0, z0)and(x1, y1, z1), and exposes a rich API for geometric queries (length, midpoint, direction cosines, angles), distance calculations, splitting, and iterative extension.Usage
from upxo.geoEntities.sline3d import Sline3d as sl3d
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d a = sl3d(0, 0, 0, 1, 1, 1) print(a.length, a.mid)
- pnta
- pntb
- x0
- y0
- z0
- x1
- y1
- z1
- classmethod by_coord(start, end)[source]
Construct a
Sline3dfrom two[x, y, z]coordinate lists.- Parameters:
- Returns:
New line from
starttoend.- Return type:
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d A = sl3d.by_coord([-1, 2, 0], [3, 4, 1])
- classmethod by_p3d(start, end)[source]
Construct a
Sline3dfrom twoPoint3dendpoint objects.- Parameters:
- Returns:
New line from
starttoend.- Return type:
Examples
from upxo.geoEntities.point3d import Point3d from upxo.geoEntities.sline3d import Sline3d Sline3d.by_p3d(Point3d(-1, 2, 3), Point3d(3, 4, 1))
- classmethod by_vector(point, xyproj)[source]
Construct from an endpoint and a direction vector. Not yet implemented.
- property mid
Midpoint of the line as
(xmid, ymid, zmid)tuple.Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).mid
- property xmid
x-coordinate of the midpoint.
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).xmid
- property ymid
y-coordinate of the midpoint.
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).ymid
- property zmid
z-coordinate of the midpoint.
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).zmid
- property gradient
Gradient of the line as
[dx/dz, dy/dz].Returns
math.infin the corresponding component when the line is horizontal (z0 == z1).Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).gradient
- property delxyz
Length increments
(dx, dy, dz)along each axis.Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).delxyz
- property dx
Signed length increment along x (
x1 - x0).Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).dx
- property dy
Signed length increment along y (
y1 - y0).Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).dy
- property dz
Signed length increment along z (
z1 - z0).Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).dz
- property ang
Orientation angles in radians as
[angle_x, angle_y, angle_z].Computed as:
angle_x = atan2(dy, dz),angle_y = atan2(dx, dz),angle_z = atan2(dy, dx).Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).ang
- property angd
Orientation angles in degrees as
[angle_x, angle_y, angle_z].Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).angd
- property length
Euclidean length of the line segment.
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).length
- property dc
Direction cosines
(dx/L, dy/L, dz/L)where L is the length.Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).dc
- property coords
Flat coordinate list
[x0, y0, z0, x1, y1, z1].Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).coords
- property coord_list
Endpoint coordinates as
[[x0, y0, z0], [x1, y1, z1]].Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d sl3d(0, 0, 0, 1, 1, 1).coord_list
- property coord_i
Start coordinate as
[x0, y0, z0].
- property coord_j
End coordinate as
[x1, y1, z1].
- property points
Return
[Point3d(i), Point3d(mid), Point3d(j)].
- is_point_endpoint(point)[source]
Return
Trueifpointcoincides with either endpoint.- Parameters:
point (array-like, length 3) – Candidate
[x, y, z]coordinate.- Returns:
Trueifpointequals(x0, y0, z0)or(x1, y1, z1);Falseotherwise.- Return type:
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d line = sl3d(0, 0, 0, 1, 1, 1) print(line.is_point_endpoint((0, 0, 0))) # True print(line.is_point_endpoint([1, 2, 3])) # False
- f
- distance_to_points(points=None, *, ref='all')[source]
Calculate the Euclidean distance from a reference location on the line to a set of points.
- Parameters:
points (list of Point3d) – Target points to measure distance to.
ref ({'all', 'i', 'start', 'mid', 'j', 'end'}, optional) –
Reference location on the line:
'all'— compute from start, mid, and end (returns list of 3 arrays).'i'/'start'— from the start endpoint.'mid'— from the midpoint.'j'/'end'— from the end endpoint.
Default is
'all'.
- Returns:
When
ref='all', a list of three distance arrays[dist_from_i, dist_from_mid, dist_from_j]; otherwise a single distance array.- Return type:
Examples
Example 1 — distances from all three reference locations:
from upxo.geoEntities.point3d import Point3d as p3d from upxo.geoEntities.sline3d import Sline3d as sl3d import numpy as np line = sl3d(0, 0, 0, 1, 1, 1) points = [p3d(xy[0], xy[1], xy[2]) for xy in np.random.random((10, 3))] line.distance_to_points(points, ref='all') line.distance_to_points(points, ref='i') line.distance_to_points(points, ref='mid') line.distance_to_points(points, ref='j')
- perp_distance(point, ptype='coord_list')[source]
Compute the perpendicular distance from a point to the infinite line.
- Parameters:
- Returns:
Perpendicular distance from
pointto the line.- Return type:
Examples
Example 1 — single coordinate triple:
from upxo.geoEntities.sline3d import Sline3d as sl3d line = sl3d(0, 0, 0, 1, 0, 0) line.perp_distance((1, 1, 1))
Example 2 — vectorised version for many points (see
perp_distance_vectorized()):from upxo.geoEntities.sline3d import Sline3d as sl3d import numpy as np line = sl3d(0, 0, 0, 1, 0, 0) plist = np.random.random((10000, 3)) line.perp_distance_vectorized(plist, ptype='coord_list')
- perp_distance_vectorized(points, ptype='coord_list')[source]
Compute perpendicular distances from many points to the infinite line (vectorised).
- Parameters:
points (numpy.ndarray, shape (M, 3), or list of Point3d) – Target points.
ptype ({'coord_list', '[point3d]', 'point3d', 'p3d'}, optional) – Format of
points. Default is'coord_list'.
- Returns:
Perpendicular distance from each point to the line.
- Return type:
numpy.ndarray, shape (M,)
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d import numpy as np line = sl3d(0, 0, 0, 0.5, 0.5, 0.5) x = np.linspace(0, 1, 4) points = np.stack(np.meshgrid(x, x, x), axis=-1).reshape(-1, 3) line.perp_distance_vectorized(points, ptype='coord_list')
- extend(dincr, direction='both', saa=True, throw=False)[source]
Extend the line by
dincrat the start, end, or both ends.- Parameters:
dincr (float) – Extension increment (in the same units as the line coordinates).
direction ({'both', 'start', 'end'}, optional) – Which end(s) to extend. Default is
'both'.saa (bool, optional) – If
True, updateselfin place. Default isTrue.throw (bool, optional) – If
True, return the new endpoint arrays. Default isFalse.
- Returns:
When
throw=True, returns(P1_extended, P2_extended); otherwiseNone.- Return type:
tuple of numpy.ndarray or None
- extend_until_exhaustion(points, voxel_size=1.0, dincr_factor=0.1, direction='end', max_iterations=1000, saa_final=True, throw_final=False)[source]
Iteratively extend the line until no new points fall within the threshold distance.
At each iteration the line is extended by
dincr_factor * lengthin the requested direction. Iteration stops when the count of nearby points ceases to increase.- Parameters:
points (array-like, shape (M, 3)) – 3-D point cloud the line is extended towards.
voxel_size (float, optional) – Voxel edge length; the proximity threshold is
sqrt(3) * voxel_size(body diagonal). Default is 1.0.dincr_factor (float, optional) – Extension per iteration as a fraction of the current line length. Default is 0.1.
direction ({'end', 'start', 'both'}, optional) – Which end(s) to extend. Default is
'end'.max_iterations (int, optional) – Safety cap on the number of iterations. Default is 1000.
saa_final (bool, optional) – If
True, setselfendpoints to the final detected extent. Default isTrue.throw_final (bool, optional) – If
True, return the final endpoint coordinates. Default isFalse.
- Returns:
When
throw_final=Trueanddirection='end', returns(start_point, actual_end_point); fordirection='both', returns(actual_start_point, actual_end_point).- Return type:
tuple of numpy.ndarray or None
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d import numpy as np LINE = sl3d(0, 0, 0, 0.5, 0.5, 0.5) x = np.linspace(0, 5, 4) points = np.stack(np.meshgrid(x, x, x), axis=-1).reshape(-1, 3) LINE.extend_until_exhaustion(points, voxel_size=x[1]-x[0], dincr_factor=0.1, direction='end') print(LINE)
- split(f=0.5, saa=False, throw=True, retain=0)[source]
Split the line at one or more fractional positions.
- Parameters:
f (float or iterable of float) – Fractional position(s) along the line in the open interval (0, 1). When a scalar, the line is split into two segments. Iterable support is reserved for future implementation.
saa (bool, optional) – If
True, shortenselfto retain the segment specified byretainand discard the other. Default isFalse.throw (bool, optional) – If
True, return the two newSline3dobjects. Default isTrue.retain ({0, 1}, optional) – When
saa=True, which half to keep: 0 = start half, 1 = end half. Default is 0.
- Returns:
When
throw=Trueandsaa=False, returns[line_start_half, line_end_half]; otherwiseNone.- Return type:
Examples
from upxo.geoEntities.sline3d import Sline3d as sl3d line = sl3d(0, 0, 0, 1, 0, 0) halves = line.split(f=0.75, saa=False, throw=True) print(halves[0].length, halves[1].length)