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: object

Lean 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: object

Full-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 Sline3d from two [x, y, z] coordinate lists.

Parameters:
  • start (list of float, length 3) – Start-point coordinates [x0, y0, z0].

  • end (list of float, length 3) – End-point coordinates [x1, y1, z1].

Returns:

New line from start to end.

Return type:

Sline3d

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 Sline3d from two Point3d endpoint objects.

Parameters:
  • start (Point3d) – Start-point UPXO point object.

  • end (Point3d) – End-point UPXO point object.

Returns:

New line from start to end.

Return type:

Sline3d

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.inf in 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 True if point coincides with either endpoint.

Parameters:

point (array-like, length 3) – Candidate [x, y, z] coordinate.

Returns:

True if point equals (x0, y0, z0) or (x1, y1, z1); False otherwise.

Return type:

bool

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
invert()[source]

Swap start and end endpoints in place.

f
move_i(point)[source]

Move the start point to point in place.

move_j(point)[source]

Move the end point to point in place.

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:

list or numpy.ndarray

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:
  • point (array-like or list of Point3d) – Target point(s). Interpretation depends on ptype.

  • ptype ({'coord_list', '[point3d]', 'point3d', 'p3d'}, optional) – Specifies the format of point. Default is 'coord_list'.

Returns:

Perpendicular distance from point to the line.

Return type:

float

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 dincr at 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, update self in place. Default is True.

  • throw (bool, optional) – If True, return the new endpoint arrays. Default is False.

Returns:

When throw=True, returns (P1_extended, P2_extended); otherwise None.

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 * length in 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, set self endpoints to the final detected extent. Default is True.

  • throw_final (bool, optional) – If True, return the final endpoint coordinates. Default is False.

Returns:

When throw_final=True and direction='end', returns (start_point, actual_end_point); for direction='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, shorten self to retain the segment specified by retain and discard the other. Default is False.

  • throw (bool, optional) – If True, return the two new Sline3d objects. Default is True.

  • retain ({0, 1}, optional) – When saa=True, which half to keep: 0 = start half, 1 = end half. Default is 0.

Returns:

When throw=True and saa=False, returns [line_start_half, line_end_half]; otherwise None.

Return type:

list of Sline3d or None

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)