upxo.geoEntities.mulpoint2d module

2D multi-point collection.

This module provides a container class for managing ordered collections of 2D points in UPXO. It supports construction from coordinate arrays, individual Point2d objects, rectangular grids, and intersection results, and exposes numerical, geometric, and spatial-query operations over the full point set.

Usage

from upxo.geoEntities.mulpoint2d import MPoint2d

Metadata

  • Module: upxo.geoEntities.mulpoint2d

  • Package: upxo

  • License: GPL-3.0-only

  • Author: Dr. Sunil Anandatheertha

  • Email: vaasu.anandatheertha@ukaea.uk

  • Status: Active development

  • Last updated: 2026-03-12

Applications

  • Storing and manipulating polycrystal grain-boundary vertex sets

  • Batch spatial queries (distances, centroid proximity, containment)

  • Rectangular-grid point generation for structured-domain discretization

  • Clustering-based synthetic point-cloud generation

  • Intersection-point collection from multi-line geometry operations

Classes

  • MPoint2d - ordered 2D multi-point collection backed by a (N x 2) NumPy array

Definitions

coordsnp.ndarray, shape (N, 2)

Array of (x, y) coordinate pairs for all points in the collection.

pointslist of Point2d

Corresponding list of UPXO Point2d objects.

nint

Number of points in the collection (read-only property).

centroidnp.ndarray, shape (2,)

Arithmetic mean of all (x, y) coordinates.

class upxo.geoEntities.mulpoint2d.MPoint2d(coords=None, points=None)[source]

Bases: object

UPXO core class. Collection of 2D points. Offers wide spectrucm of operations.

Stores points both as a NumPy array (coords) for vectorised numerical operations and as a list of UPXO Point2d objects (points) for object-level access. Supports construction from raw coordinates, existing Point2d instances, rectangular grids, clustering distributions, and multi-line intersection results.

Parameters:
  • coords (np.array([[0, 0], [1, 1], [2, 3], [4, 5]])) – Sequence of (x, y) coordinate pairs. If provided, points must be None; individual Point2d objects are created automatically.

  • points (list of Point2d, optional) – Pre-constructed UPXO Point2d objects. If provided, coords must be None; the coordinate array is derived from the points.

  • format (Standard data)

  • --------------------

  • coords

  • Usage

  • -----

  • MPoint2d (from upxo.geoEntities.mulpoint2d import)

  • mp2d (from upxo.geoEntities.mulpoint2d import MPoint2d as)

EPS = 1e-08
points
coords
add(toadd=None, operation='add')[source]

Add toadd to self.coords.

Parameters:
  • toadd (object, optional) – Point, coordinate, or coordinate collection to add according to operation.

  • operation (str, optional) – Add operation mode.

Returns:

Updates self.coords in place for supported branches.

Return type:

None

Examples

Example 1 — add a scalar:

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((10,2)))
mulpoint2d.coords
mulpoint2d.add(toadd=10, operation='add')
mulpoint2d.coords

Example 2 — add a 2-element list:

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((10,2)))
mulpoint2d.coords
mulpoint2d.add(toadd=[-10, 20], operation='add')
mulpoint2d.coords

Example 3 — add an (N, 2) array:

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((10,2)))
mulpoint2d.coords
mulpoint2d.add(toadd=np.random.random((mulpoint2d.n, 2)), operation='add')
mulpoint2d.coords

Example 4 — add a transposed (2, N) array:

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((10,2)))
mulpoint2d.coords
mulpoint2d.add(toadd=np.random.random((mulpoint2d.n, 2)).T, operation='add')
mulpoint2d.coords

Example 5 — append rows:

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((10,2)))
mulpoint2d.coords
mulpoint2d.add(toadd=np.random.random((10,2)), operation='append')
mulpoint2d.coords
classmethod from_coords(point_coords)[source]

Instantiate mulpoint2d using list of point coordinates.

Parameters:

point_coords (array-like, shape (N, 2)) – Coordinate rows used to build the collection.

Returns:

Multi-point collection populated from point_coords.

Return type:

MPoint2d

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
point_coords = np.array([[0, 0], [1, 1], [2, 3], [4, 5]])
MULPOINT2D = mp2d.from_coords(point_coords)
MULPOINT2D.coords
MULPOINT2D.points
classmethod from_xy(xy)[source]

Instantiate MPoint2d using x and y coordinate lists.

Parameters:

xy (array-like, shape (2, N)) – Coordinate matrix with x-coordinates in the first row and y-coordinates in the second row.

Returns:

Multi-point collection populated from xy.

Return type:

MPoint2d

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
xy = np.array([[0, 0], [1, 1], [2, 3], [4, 5]]).T
MULPOINT2D = mp2d.from_xy(xy)
MULPOINT2D.coords
classmethod from_upxo_points2d(points, zloc=0.0)[source]

Construct from a list of Point2d objects.

Parameters:
  • points (list of Point2d) – Point objects used to populate the collection.

  • zloc (float, optional) – Retained for API compatibility; not used by the current 2D implementation.

Returns:

Multi-point collection built from points.

Return type:

MPoint2d

classmethod from_mulpoint2d(mp2d, zloc=0.0)[source]

Construct from an existing MPoint2d instance.

Parameters:
  • mp2d (MPoint2d) – Source multi-point object.

  • zloc (float, optional) – Retained for API compatibility.

Raises:

NotImplementedError – This method is not yet implemented.

classmethod from_rect_grid(xstart, xinc, xend, ystart, yinc, yend)[source]

Instantiate a rectangular grid of 2D points.

Parameters:
  • xstart (float) – Start, increment, and stop values for x-grid coordinates.

  • xinc (float) – Start, increment, and stop values for x-grid coordinates.

  • xend (float) – Start, increment, and stop values for x-grid coordinates.

  • ystart (float) – Start, increment, and stop values for y-grid coordinates.

  • yinc (float) – Start, increment, and stop values for y-grid coordinates.

  • yend (float) – Start, increment, and stop values for y-grid coordinates.

Returns:

Multi-point collection containing the rectangular grid points.

Return type:

MPoint2d

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d
mp = MPoint2d.from_rect_grid(0, 1, 5, 0, 1, 3)
classmethod from_clustering_around_centroid(centroid, n=10, r=1, distribution='urand', dmin=None)[source]

Build a point cluster uniformly distributed around a centroid.

Parameters:
  • centroid (array-like) – Cluster centroid coordinate.

  • n (int, optional) – Number of points to generate.

  • r (float, optional) – Cluster radius.

  • distribution (str, optional) – Distribution type.

  • dmin (float, optional) – Optional minimum separation distance.

Returns:

Multi-point collection containing generated cluster points.

Return type:

MPoint2d

Examples

Single cluster at (-5, -10) with 1000 points, radius 1:

import matplotlib.pyplot as plt
from upxo.geoEntities.mulpoint2d import MPoint2d
MP2D = MPoint2d.from_clustering_around_centroid(
    (-5, -10), n=1000, r=1, distribution='urand', dmin=0.1)
plt.scatter(MP2D.coords[:, 0], MP2D.coords[:, 1])

Multiple clusters along the x-axis:

cenx, ceny = [0, 1, 2, 3, 4], [0, 0, 0, 0, 0]
for cx, cy in zip(cenx, ceny):
    MP2D = MPoint2d.from_clustering_around_centroid(
        (cx, cy), n=250, r=0.25, distribution='urand', dmin=0.1)
    plt.scatter(MP2D.coords[:, 0], MP2D.coords[:, 1])
classmethod from_intersection_linesA_linesB(La, Lb, return_ordered_points=True, plot=False)[source]

Create mulpoint from intersection of many lines.

Checks lines for intersections and creates UPXO point object at every intersection.NOTE: This method can potentially cause a bottleneck in case of large lines array size.

Parameters:
  • La (list of Sline2d) – Line objects for the first group.

  • Lb (list of Sline2d) – Line objects for the second group.

  • return_ordered_points (bool, optional) – If True, ordered points will also be returned. Default is True.

  • plot (bool, optional) – If True, lines and intersection points will be visualized.

Returns:

  • cls (MPoint2d) – Collection of intersection points.

  • points (list of list of Point2d) – Ordered intersection points; len(Lb) rows by len(La) columns.

Examples

from upxo.geoEntities.sline2d import Sline2d
from upxo.geoEntities.point2d import Point2d
from upxo.geoEntities.mulpoint2d import MPoint2d

na, nb = 5, 5
R = np.random.rand
La = [Sline2d.by_coord([-10-R(),-10+R()], [10+R(),10-R()])
      for _ in range(na)]
Lb = [Sline2d.by_coord([-10+R(),-10-R()], [10-R(),10+R()])
      for _ in range(nb)]
MPoint2d.from_intersection_linesA_linesB(La, Lb,
    return_ordered_points=True,
    plot=True)
MP2D = MPoint2d.from_intersection_linesA_linesB(La, Lb,
    return_ordered_points=False,
    plot=False)
MP2D.points, MP2D.coords
property n

Number of points in the collection.

Returns:

Number of coordinate rows.

Return type:

int

property centroid

Mean coordinate of all points.

Returns:

Arithmetic mean of the stored (x, y) coordinates.

Return type:

numpy.ndarray, shape (2,)

property get_points

Return point objects built from self.coords.

Returns:

One point object per coordinate row.

Return type:

list of Point2d

property x

x-coordinates of all points.

Returns:

x-coordinate column.

Return type:

numpy.ndarray, shape (N,)

property y

y-coordinates of all points.

Returns:

y-coordinate column.

Return type:

numpy.ndarray, shape (N,)

squared_distances_to_point(point, validate=True)[source]

Return squared distances from all points to point.

Parameters:
  • point (Point2d or array-like) – Target point. When validate is True, accepted coordinate forms are delegated to val_point_and_get_coord. When validate is False, point must expose x and y attributes.

  • validate (bool, optional) – Whether to validate and coerce point before distance calculation.

Returns:

Squared Euclidean distances.

Return type:

numpy.ndarray, shape (N,)

distances_to_point(point)[source]

Return Euclidean distances from all points to point.

Parameters:

point (Point2d or array-like) – Target point.

Returns:

Euclidean distances.

Return type:

numpy.ndarray, shape (N,)

squared_distance_to_centroid(points, validate_points=True, points_type='numpy')[source]

Calculates squared distances between self.centroid and other 2D points.

Parameters:
  • points (list of Point2d or numpy.ndarray) – Points to compute distances from.

  • validate_points (bool, optional) – If True, validation will be used. When confident that points are provided as a numpy array of coordinate pairs, it is advised to keep this False. When unknown, keep it True. True may increase computation time depending on the number of points.

  • points_type (str, optional) – If validate_points is False, then points_type must be 'numpy'. You could also use 'coord' but this would include an additional overhead of conversion from coord to numpy array.

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d
from upxo.geoEntities.point2d import Point2d
MULPOINT2D = MPoint2d.from_coords(np.random.random((10, 2)))
POINTS = make_p2d(2+np.random.random((10, 2)), return_type='p2d')
MULPOINT2D.squared_distance_to_centroid(POINTS, validate_points=True)
POINTS = 2+np.random.random((10, 2))
MULPOINT2D.squared_distance_to_centroid(POINTS, validate_points=False,
    points_type='numpy')
distance_to_centroid(points, validate_points=True, points_type='numpy')[source]

Calculates distances between self.centroid and other 2D points.

Parameters:
  • points (list of Point2d or numpy.ndarray) – Points to compute distances from.

  • validate_points (bool, optional) – Whether to validate and coerce the input point collection.

  • points_type (str, optional) – Type hint used when validate_points is False.

Returns:

Euclidean distances from self.centroid to the supplied points.

Return type:

numpy.ndarray

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d
from upxo.geoEntities.point2d import Point2d
MULPOINT2D = MPoint2d.from_coords(np.random.random((10, 2)))
POINTS = make_p2d(2+np.random.random((10, 2)), return_type='p2d')
MULPOINT2D.squared_distance_to_centroid(POINTS, validate_points=True)
POINTS = 2+np.random.random((10, 2))
MULPOINT2D.distance_to_centroid(POINTS, validate_points=False,
    points_type='numpy')
linreg()[source]

Fit a linear regression line through all points.

Raises:

NotImplementedError – This method is not yet implemented.

relax()[source]

Relax point positions.

Raises:

NotImplementedError – This method is not yet implemented.

convex_hull()[source]

Compute the convex hull of the point set.

Raises:

NotImplementedError – This method is not yet implemented.

find_boundary(boundary_type='chull')[source]

Find boundary points using the requested boundary method.

Parameters:

boundary_type (str, optional) – Boundary-detection strategy. 'chull' indicates convex-hull based detection.

Raises:

NotImplementedError – This method is not yet implemented.

bbox()[source]

Return bounding box of the mulpoint.

Returns:

bbox – Keys 'bl', 'br', 'tr', 'tl' for bottom-left, bottom-right, top-right, and top-left corners.

Return type:

dict

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
MP2D = mp2d.from_coords(np.random.random((10,2)))
MP2D.bbox()
maketree(treeType='ckdtree')[source]

Use tree structure to deal with a very large system of points.

Parameters:

treeType ({'ckdtree', 'kdtree'}, optional) – Spatial tree type to construct.

Returns:

KD-tree over self.coords for supported tree types; otherwise None.

Return type:

scipy.spatial.cKDTree or None

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((25, 3)))
mulpoint2d.coords
from scipy.spatial import cKDTree as ckdt
a = ckdt(mulpoint2d.coords, copy_data=False, balanced_tree=True)
a.data
plot(points=None, primary_ms=None, secondary_ms=None)[source]

Scatter plot points and choose to overlay over specifried points.

Parameters:
  • points (List of secondary points)

  • primary_ms (marker size to use for primary list of points)

  • secondary_ms (marker size to use for secondary list of points)

Examples

from upxo.geoEntities.mulpoint2d import MPoint2d as mp2d
mulpoint2d = mp2d.from_coords(np.random.random((25, 3)))
MULPOINT2D = mp2d.from_mulpoint2d(mulpoint2d=mulpoint2d,
dxy=[0.0, 0.0],
translate_ref=mulpoint2d.centroid,
rot=[10, 0.0, 0.0],
rot_ref=mulpoint2d.centroid,
degree=True)
mulpoint2d.plot(MULPOINT2D.coords, primary_ms=50)