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.

x0, y0, z0

Start-point coordinates.

Type:

float

x1, y1, z1

End-point coordinates.

Type:

float

Notes

This class intentionally stores no Point3d endpoint objects. Use Sline3d when richer geometry state or mutation helpers 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.

Returns:

Segment length.

Return type:

float

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.

Parameters:
  • point (Point3d or array-like) – Endpoint through which the line should pass.

  • xyproj (array-like) – Direction or projected vector specification.

Raises:

NotImplementedError – This constructor is not yet implemented.

property mid

Midpoint of the line as (xmid, ymid, zmid) tuple.

Returns:

Midpoint coordinate tuple.

Return type:

tuple of float

Examples

from upxo.geoEntities.sline3d import Sline3d as sl3d
sl3d(0, 0, 0, 1, 1, 1).mid
property xmid

x-coordinate of the midpoint.

Returns:

Midpoint x-coordinate.

Return type:

float

Examples

from upxo.geoEntities.sline3d import Sline3d as sl3d
sl3d(0, 0, 0, 1, 1, 1).xmid
property ymid

y-coordinate of the midpoint.

Returns:

Midpoint y-coordinate.

Return type:

float

Examples

from upxo.geoEntities.sline3d import Sline3d as sl3d
sl3d(0, 0, 0, 1, 1, 1).ymid
property zmid

z-coordinate of the midpoint.

Returns:

Midpoint z-coordinate.

Return type:

float

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).

Returns:

Direction gradients [dx/dz, dy/dz].

Return type:

list of float

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.

Returns:

Signed endpoint differences (dx, dy, dz).

Return type:

tuple of float

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).

Returns:

Signed x-increment.

Return type:

float

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).

Returns:

Signed y-increment.

Return type:

float

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).

Returns:

Signed z-increment.

Return type:

float

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).

Returns:

Orientation angles in radians.

Return type:

list of float

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].

Returns:

Orientation angles in degrees.

Return type:

list of float

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.

Returns:

Segment length.

Return type:

float

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.

Returns:

Direction cosines along x, y, and z.

Return type:

tuple of float

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].

Returns:

Flat endpoint coordinate list.

Return type:

list of float

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]].

Returns:

Start and end endpoint coordinate lists.

Return type:

list of list of float

Examples

from upxo.geoEntities.sline3d import Sline3d as sl3d
sl3d(0, 0, 0, 1, 1, 1).coord_list
property coord_i

Start coordinate.

Returns:

[x0, y0, z0].

Return type:

list of float

property coord_j

End coordinate.

Returns:

[x1, y1, z1].

Return type:

list of float

property points

Return endpoint and midpoint objects.

Returns:

[Point3d(i), Point3d(mid), Point3d(j)].

Return type:

list of Point3d

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.

Returns:

The line is modified in place.

Return type:

None

f
move_i(point)[source]

Move the start point to point in place.

Parameters:

point (array-like, length 3) – New start coordinate.

Returns:

The line is modified in place.

Return type:

None

move_j(point)[source]

Move the end point to point in place.

Parameters:

point (array-like, length 3) – New end coordinate.

Returns:

The line is modified in place.

Return type:

None

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)