bluemira.geometry.coordinates

Utility for sets of coordinates

Attributes

DIM

Classes

RotationAxis

Enumeration of rotation axes.

Coordinates

Coordinates object for storing ordered sets of coordinates.

Functions

xyz_process(func)

Decorator for parsing x, y, z coordinates to numpy float arrays and dimension

_validate_coordinates(x, y[, z])

vector_lengthnorm(→ numpy.ndarray)

Get a normalised 1-D parameterisation of a set of x-y(-z) coordinates.

interpolate_points(→ tuple[numpy.ndarray, ...)

Interpolate points.

_interpolate_points(→ tuple[numpy.ndarray, ...)

interpolate_midpoints(→ tuple[numpy.ndarray, ...)

Interpolate the points adding the midpoint of each segment to the points.

get_normal_vector(→ numpy.ndarray)

Calculate the normal vector from a series of planar points.

get_perimeter(→ float)

Calculate the perimeter of a set of coordinates.

get_perimeter_2d(→ float)

Calculate the perimeter of a 2-D set of coordinates.

get_perimeter_3d(→ float)

Calculate the perimeter of a set of 3-D coordinates.

_get_perim_3d(→ float)

Calculate the perimeter of a set of 3-D coordinates.

get_area(→ float)

Calculate the area inside a closed polygon with x, y coordinate vectors.

get_area_2d(→ float)

Calculate the area inside a closed polygon with x, y coordinate vectors.

get_area_3d(→ float)

Calculate the area inside a closed polygon.

check_ccw(→ bool)

Check that a set of x, z coordinates are counter-clockwise.

check_ccw_3d(→ bool)

Check if a set of coordinates is counter-clockwise w.r.t a normal vector.

get_centroid(→ numpy.ndarray)

Calculate the centroid of a non-self-intersecting 2-D counter-clockwise polygon.

get_centroid_2d(→ list[float])

Calculate the centroid of a non-self-intersecting 2-D counter-clockwise polygon.

get_centroid_3d(→ list[float])

Calculate the centroid of a non-self-intersecting counterclockwise polygon

get_angle_between_points(→ float)

Angle between points. P1 is vertex of angle. ONly tested in 2d

get_angle_between_vectors(→ float)

Angle between vectors. Will return the signed angle if specified.

rotation_matrix(→ numpy.ndarray)

Old-fashioned rotation matrix: \(\mathbf{R_{u}}(\theta)\)

rotation_matrix_v1v2(→ numpy.ndarray)

Get a rotation matrix based off two vectors.

project_point_axis(→ numpy.ndarray)

Project a 3-D point onto a 3-D axis.

principal_components(→ tuple[numpy.ndarray, numpy.ndarray])

Principal component analysis.

check_linesegment(→ bool)

Check that point C is on the line between points A and B.

in_polygon(→ bool)

Determine if a point (x, z) is inside a 2-D polygon.

polygon_in_polygon(→ numpy.ndarray)

Determine what points of a 2-D polygon are inside another 2-D polygon.

on_polygon(→ bool)

Determine if a point (x, z) is on the perimeter of a closed 2-D polygon.

normal_vector(→ numpy.ndarray)

Find the anti-clockwise normal vector to the given side vectors.

vector_intersect(→ numpy.ndarray)

Get the intersection point between two 2-D vectors.

get_bisection_line(...)

Find the bisection line between two lines.

_parse_to_xyz_array(→ numpy.typing.NDArray)

Make a 3, N xyz array out of just about anything.

_parse_array(xyz_array)

_parse_dict(xyz_dict)

vector_intersect_3d(→ numpy.ndarray)

Get the intersection point between two 3-D vectors.

coords_plane_intersect(→ numpy.ndarray | None)

Calculate the intersection of Coordinates with a plane.

_coords_plane_intersect(→ list[float])

get_intersect(...)

Calculates the intersection points between two sets of 2-D coordinates. Will return

_intersect_count(→ numpy.ndarray)

Get the indices of the intersects that are

join_intersect(→ tuple[Coordinates, ...)

Add the intersection points between tgt_poly and ref_poly to tgt_poly.

convex_2d_hull_coordinates(→ Coordinates)

Given a list of coordinates, simplify it so that only the points that makes up the

choose_direction(vector, lower_pt, higher_pt)

Flip the vector to the correct side (multiply by +1 or -1) so that

Module Contents

bluemira.geometry.coordinates.DIM = 3
class bluemira.geometry.coordinates.RotationAxis(*args, **kwds)

Bases: enum.Enum

Inheritance diagram of bluemira.geometry.coordinates.RotationAxis

Enumeration of rotation axes.

X
Y
Z
classmethod _missing_(value: str | RotationAxis) RotationAxis
Parameters:

value (str | RotationAxis)

Return type:

RotationAxis

bluemira.geometry.coordinates.xyz_process(func)

Decorator for parsing x, y, z coordinates to numpy float arrays and dimension checking.

Returns:

Decorator for parsing x, y, z coordinates to numpy float arrays and dimension checking.

bluemira.geometry.coordinates._validate_coordinates(x, y, z=None)
bluemira.geometry.coordinates.vector_lengthnorm(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray | None = None) numpy.ndarray

Get a normalised 1-D parameterisation of a set of x-y(-z) coordinates.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray | None) – The z coordinates. If None, carries out the operation in 2-D

Return type:

The normalised length vector

Notes

The normalized length vector is:

\[\text{Normalized Length} = \frac{L}{L[-1]}\]

where

\[L = \sum_{i=0}^{n-1} \sqrt{(\Delta x_i)^2 + (\Delta y_i)^2 + (\Delta z_i)^2}\]

Where \(\Delta x_i\), \(\Delta y_i\), and \(\Delta z_i\) are the finite differences along the x, y, and z dimensions, respectively for the i-th index. n is the length of the array of coordinates.

bluemira.geometry.coordinates.interpolate_points(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray, n_points: int) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Interpolate points.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

  • n_points (int) – number of points

Returns:

  • x – The interpolated x coordinates

  • y – The interpolated y coordinates

  • z – The interpolated z coordinates

Return type:

tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

bluemira.geometry.coordinates._interpolate_points(linterp, x, y, z) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]
Return type:

tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

bluemira.geometry.coordinates.interpolate_midpoints(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

Interpolate the points adding the midpoint of each segment to the points.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

Returns:

  • x – The interpolated x coordinates

  • y – The interpolated y coordinates

  • z – The interpolated z coordinates

Return type:

tuple[numpy.ndarray, numpy.ndarray, numpy.ndarray]

bluemira.geometry.coordinates.get_normal_vector(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) numpy.ndarray

Calculate the normal vector from a series of planar points.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

Return type:

The normalised normal vector

Raises:

CoordinatesError – Cannot find normal vector or arrays not of equal length >= 3

bluemira.geometry.coordinates.get_perimeter(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray | None = None) float

Calculate the perimeter of a set of coordinates.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray | None) – The z coordinates

Return type:

The perimeter of the coordinates

bluemira.geometry.coordinates.get_perimeter_2d(x: numpy.ndarray, y: numpy.ndarray) float

Calculate the perimeter of a 2-D set of coordinates.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

Return type:

The perimeter of the coordinates

bluemira.geometry.coordinates.get_perimeter_3d(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) float

Calculate the perimeter of a set of 3-D coordinates.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

Return type:

The perimeter of the coordinates

bluemira.geometry.coordinates._get_perim_3d(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) float

Calculate the perimeter of a set of 3-D coordinates.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

Return type:

The perimeter of the coordinates

bluemira.geometry.coordinates.get_area(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray | None = None) float

Calculate the area inside a closed polygon with x, y coordinate vectors. Link Shoelace method

Parameters:
  • x (numpy.ndarray) – The first set of coordinates [m]

  • y (numpy.ndarray) – The second set of coordinates [m]

  • z (numpy.ndarray | None) – The third set of coordinates or None (for a 2-D polygon)

Return type:

The area of the polygon [m^2]

bluemira.geometry.coordinates.get_area_2d(x: numpy.ndarray, y: numpy.ndarray) float

Calculate the area inside a closed polygon with x, y coordinate vectors. Link Shoelace method

Parameters:
  • x (numpy.ndarray) – The first set of coordinates [m]

  • y (numpy.ndarray) – The second set of coordinates [m]

Return type:

The area of the polygon [m^2]

bluemira.geometry.coordinates.get_area_3d(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) float

Calculate the area inside a closed polygon. Link Shoelace method

Parameters:
  • x (numpy.ndarray) – The first set of coordinates [m]

  • y (numpy.ndarray) – The second set of coordinates [m]

  • z (numpy.ndarray) – The third set of coordinates [m]

Return type:

The area of the polygon [m^2]

bluemira.geometry.coordinates.check_ccw(x: numpy.ndarray, z: numpy.ndarray) bool

Check that a set of x, z coordinates are counter-clockwise.

Parameters:
  • x (numpy.ndarray) – The x coordinates of the polygon

  • z (numpy.ndarray) – The z coordinates of the polygon

Return type:

True if polygon counterclockwise

bluemira.geometry.coordinates.check_ccw_3d(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray, normal: numpy.ndarray) bool

Check if a set of coordinates is counter-clockwise w.r.t a normal vector.

Parameters:
  • x (numpy.ndarray) – The first set of coordinates [m]

  • y (numpy.ndarray) – The second set of coordinates [m]

  • z (numpy.ndarray) – The third set of coordinates [m]

  • normal (numpy.ndarray) – The normal vector about which to check for CCW

Return type:

Whether or not the set is CCW about the normal vector

bluemira.geometry.coordinates.get_centroid(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray | None = None) numpy.ndarray

Calculate the centroid of a non-self-intersecting 2-D counter-clockwise polygon.

Parameters:
  • x (numpy.ndarray) – x coordinates of the coordinates to calculate on

  • y (numpy.ndarray) – y coordinates of the coordinates to calculate on

  • z (numpy.ndarray | None) – z coordinates of the coordinates to calculate on

Return type:

The x, y, [z] coordinates of the centroid [m]

bluemira.geometry.coordinates.get_centroid_2d(x: numpy.ndarray, z: numpy.ndarray) list[float]

Calculate the centroid of a non-self-intersecting 2-D counter-clockwise polygon.

Parameters:
  • x (numpy.ndarray) – x coordinates of the coordinates to calculate on

  • z (numpy.ndarray) – z coordinates of the coordinates to calculate on

Return type:

The x, z coordinates of the centroid [m]

bluemira.geometry.coordinates.get_centroid_3d(x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray) list[float]

Calculate the centroid of a non-self-intersecting counterclockwise polygon in 3-D.

Parameters:
  • x (numpy.ndarray) – The x coordinates

  • y (numpy.ndarray) – The y coordinates

  • z (numpy.ndarray) – The z coordinates

Return type:

The x, y, z coordinates of the centroid [m]

bluemira.geometry.coordinates.get_angle_between_points(p0: numpy.ndarray, p1: numpy.ndarray, p2: numpy.ndarray) float

Angle between points. P1 is vertex of angle. ONly tested in 2d

Returns:

The angle between points.

Parameters:
  • p0 (numpy.ndarray)

  • p1 (numpy.ndarray)

  • p2 (numpy.ndarray)

Return type:

float

bluemira.geometry.coordinates.get_angle_between_vectors(v1: numpy.ndarray, v2: numpy.ndarray, *, signed: bool = False) float

Angle between vectors. Will return the signed angle if specified.

Parameters:
  • v1 (numpy.ndarray) – The first vector

  • v2 (numpy.ndarray) – The second vector

  • signed (bool) – Whether or not to calculate the signed angle

Return type:

The angle between the vectors [radians]

bluemira.geometry.coordinates.rotation_matrix(theta: float, axis: str | RotationAxis | numpy.ndarray = RotationAxis.Z) numpy.ndarray
Old-fashioned rotation matrix: \(\mathbf{R_{u}}(\theta)\)

\(\mathbf{x^{'}}=\mathbf{R_{u}}(\theta)\mathbf{x}\)

\(\mathbf{R_{u}}(\theta)=cos(\theta)\mathbf{I}+sin(\theta)[\mathbf{u}]_{\times}(1-cos(\theta))(\mathbf{u}\otimes\mathbf{u})\)

Parameters:
  • theta (float) – The rotation angle [radians] (counter-clockwise about axis!)

  • axis (str | RotationAxis | numpy.ndarray) – The rotation axis (specified by axis label or vector)

Return type:

The (active) rotation matrix about the axis for an angle theta

bluemira.geometry.coordinates.rotation_matrix_v1v2(v1: numpy.ndarray, v2: numpy.ndarray) numpy.ndarray

Get a rotation matrix based off two vectors.

Returns:

A roational matrix based off two vectors.

Parameters:
  • v1 (numpy.ndarray)

  • v2 (numpy.ndarray)

Return type:

numpy.ndarray

bluemira.geometry.coordinates.project_point_axis(point: numpy.typing.ArrayLike, axis: numpy.typing.ArrayLike) numpy.ndarray
Project a 3-D point onto a 3-D axis.

\(\mathbf{p_{proj}} = \dfrac{\mathbf{p}\cdot\mathbf{a}}{\mathbf{a}\cdot\mathbf{a}}\mathbf{a}\)

Parameters:
  • point (numpy.typing.ArrayLike) – The point to project onto the axis

  • axis (numpy.typing.ArrayLike) – The axis onto which to project the point

Return type:

The coordinates of the projected point

bluemira.geometry.coordinates.principal_components(xyz_array: numpy.ndarray) tuple[numpy.ndarray, numpy.ndarray]

Principal component analysis.

Returns:

Eigenvalues and eigenvectors or an xyz array.

Parameters:

xyz_array (numpy.ndarray)

Return type:

tuple[numpy.ndarray, numpy.ndarray]

bluemira.geometry.coordinates.check_linesegment(point_a: numpy.ndarray, point_b: numpy.ndarray, point_c: numpy.ndarray) bool

Check that point C is on the line between points A and B.

Parameters:
  • point_a (numpy.ndarray) – The first line segment 2-D point

  • point_b (numpy.ndarray) – The second line segment 2-D point

  • point_c (numpy.ndarray) – The 2-D point which to check is on A–B

Returns:

True

Return type:

if C on A–B, else False

bluemira.geometry.coordinates.in_polygon(x: float, z: float, poly: numpy.ndarray, include_edges: bool = False) bool

Determine if a point (x, z) is inside a 2-D polygon.

Parameters:
  • x (float) – Point x coordinate

  • z (float) – Point z coordinate

  • poly (numpy.ndarray) – The 2-D array of polygon point coordinates

  • include_edges (bool) – Whether or not to return True if a point is on the perimeter of the polygon

Return type:

Whether or not the point is in the polygon

bluemira.geometry.coordinates.polygon_in_polygon(poly1: numpy.ndarray, poly2: numpy.ndarray, include_edges: bool = False) numpy.ndarray

Determine what points of a 2-D polygon are inside another 2-D polygon.

Parameters:
  • poly1 (numpy.ndarray) – The array of 2-D polygon1 point coordinates

  • poly2 (numpy.ndarray) – The array of 2-D polygon2 point coordinates

  • include_edges (bool) – Whether or not to return True if a point is on the perimeter of the polygon

Return type:

The array of boolean values per index of polygon1

bluemira.geometry.coordinates.on_polygon(x: float, z: float, poly: numpy.typing.NDArray[numpy.float64]) bool

Determine if a point (x, z) is on the perimeter of a closed 2-D polygon.

Parameters:
  • x (float) – Point x coordinate

  • z (float) – Point z coordinate

  • poly (numpy.typing.NDArray[numpy.float64]) – The array of 2-D polygon point coordinates

Return type:

Whether or not the point is on the perimeter of the polygon

bluemira.geometry.coordinates.normal_vector(side_vectors: numpy.ndarray) numpy.ndarray

Find the anti-clockwise normal vector to the given side vectors.

Parameters:

side_vectors (numpy.ndarray) – The side vectors of a polygon (shape: (2, N)).

Returns:

  • The array of 2-D normal vectors of each side of a polygon

  • (shape ((2, N)).)

Return type:

numpy.ndarray

Notes

The normal vector a is calculated using the formula:

\[\mathbf{a} = -\frac{-[\mathbf{v}[1],~ \mathbf{v}[0]]}{\sqrt{\mathbf{v}[0]^2~ + \mathbf{v}[1]^2}}\]

where \(\mathbf{v}\) are the side vectors.

bluemira.geometry.coordinates.vector_intersect(p1: numpy.ndarray, p2: numpy.ndarray, p3: numpy.ndarray, p4: numpy.ndarray) numpy.ndarray

Get the intersection point between two 2-D vectors.

Parameters:
  • p1 (numpy.ndarray) – The first point on the first vector (shape: (2,)).

  • p2 (numpy.ndarray) – The second point on the first vector (shape: (2,)).

  • p3 (numpy.ndarray) – The first point on the second vector (shape: (2,)).

  • p4 (numpy.ndarray) – The second point on the second vector (shape: (2,)).

Returns:

The point of the intersection between the two vectors (shape

Return type:

(2,)).

Notes

If the vectors are parallel:
  • The vectors do not intersect.

  • The function returns p2

Otherwise:
  • Calculates the intersection point using vector algebra:

\[\text{point} = \frac{ \lVert \mathbf{p2} - \mathbf{p1} \rVert~ \cdot (\mathbf{p1} - \mathbf{p3}) }{ \lVert \mathbf{p2} - \mathbf{p1} \rVert~ \cdot (\mathbf{p4} - \mathbf{p3}) } (\mathbf{p4} - \mathbf{p3}) + \mathbf{p3}\]
bluemira.geometry.coordinates.get_bisection_line(p1: numpy.typing.NDArray[float], p2: numpy.typing.NDArray[float], p3: numpy.typing.NDArray[float], p4: numpy.typing.NDArray[float]) tuple[numpy.typing.NDArray[float], numpy.typing.NDArray[float]]

Find the bisection line between two lines.

Parameters:
  • p1 (numpy.typing.NDArray[float]) – The first point on the first vector (shape: (2,)).

  • p2 (numpy.typing.NDArray[float]) – The second point on the first vector (shape: (2,)).

  • p3 (numpy.typing.NDArray[float]) – The first point on the second vector (shape: (2,)).

  • p4 (numpy.typing.NDArray[float]) – The second point on the second vector (shape: (2,)).

Returns:

  • origin – A point on that bisection line. (shape: (2,))

  • direction – A normal vector that the bisection line points in (shape: (2,))

Return type:

tuple[numpy.typing.NDArray[float], numpy.typing.NDArray[float]]

Notes

The intersection point is calculated using vector algebra, and the direction is the normalized sum of the normalized vectors of da and db.

bluemira.geometry.coordinates._parse_to_xyz_array(xyz_array: numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike]) numpy.typing.NDArray

Make a 3, N xyz array out of just about anything.

Returns:

A 3, N xyz array.

Raises:

CoordinatesError – Cannot instantiate coordinates

Parameters:

xyz_array (numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike])

Return type:

numpy.typing.NDArray

bluemira.geometry.coordinates._parse_array(xyz_array: numpy.typing.ArrayLike)
Parameters:

xyz_array (numpy.typing.ArrayLike)

bluemira.geometry.coordinates._parse_dict(xyz_dict)
class bluemira.geometry.coordinates.Coordinates(xyz_array: numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike])

Coordinates object for storing ordered sets of coordinates.

An array shape of (3, N) is enforced.

Counter-clockwise direction can be set relative to a normal vector.

Notes

This is a utility class for dealing with sets of coordinates in a number of different contexts. It should not be used for the creation of CAD geometries.

If a 3 x 3 array is provided it is assumed that the first axis is xyz and the second is the coordinate, this will output a warning to notify users.

Parameters:

xyz_array (numpy.typing.ArrayLike | dict[str, numpy.typing.ArrayLike])

__slots__ = ('_array', '_is_planar', '_normal_vector')
_array
_is_planar = None
_normal_vector = None
classmethod from_json(filename: str) Coordinates

Load a Coordinates object from a JSON file.

Parameters:

filename (str) – Full path file name of the data

Returns:

Coordinate object.

Raises:

CoordinatesError – Cannot read json file

Return type:

Coordinates

_set_plane_props()

Set the planar properties of the Coordinates.

_update_plane_props()
property is_planar: bool

Whether or not the Coordinates are planar.

Return type:

bool

property normal_vector: numpy.ndarray

The normal vector of the best-fit plane of the Coordinates.

Return type:

numpy.ndarray

check_ccw(axis: numpy.ndarray | None = None) bool

Whether or not the Coordinates are ordered in the counter-clockwise direction about a specified axis. If None is specified, the Coordinates normal vector will be used.

Returns:

The check for whether the Coordinates are ordered in counter-clockwise or not.

Raises:

CoordinatesError – axis must be of size 3

Parameters:

axis (numpy.ndarray | None)

Return type:

bool

set_ccw(axis: numpy.ndarray | None = None)

Set the Coordinates to be counter-clockwise about a specified axis. If None is specified, the Coordinates normal vector will be used.

Parameters:

axis (numpy.ndarray | None)

distance_to(point: numpy.ndarray) numpy.ndarray

Calculates the distances from each point in the Coordinates to the point.

Parameters:

point (numpy.ndarray) – The point (3-D) to which to calculate the distances

Return type:

The vector of distances of the Coordinates to the point

Notes

Euclidean distance:

\[d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2 + (z_2 - z_1)^2}\]

where indices refer to the Coordinate and the given point.

argmin(point: numpy.ndarray) int
Parameters:

point (numpy.ndarray) – The 3-D point to which to calculate the distances

Return type:

The index of the closest point

interpolate(ndiscr: int | None = None, dl: float | None = None, *, preserve_points: bool = False)

Interpolate coordinates

Parameters:
  • ndiscr (int | None) – number of points to discretise to

  • dl (float | None) – target discretisation length.

  • preserve_points (bool) – will preserve the original coordinates in addition to the discretisation

Returns:

Array of points

Raises:

ValueError – if neither dl or ndiscr are specified If ndiscr < 2 If dl <= 0.0

Notes

When preserving original points the dl will be <= the discretisation

property x: numpy.ndarray

The x coordinate vector

Return type:

numpy.ndarray

property y: numpy.ndarray

The y coordinate vector

Return type:

numpy.ndarray

property z: numpy.ndarray

The z coordinate vector

Return type:

numpy.ndarray

property xy: numpy.ndarray

The x-y coordinate array

Return type:

numpy.ndarray

property xz: numpy.ndarray

The x-z coordinate array

Return type:

numpy.ndarray

property yz: numpy.ndarray

The y-z coordinate array

Return type:

numpy.ndarray

property xyz: numpy.ndarray

The x-y-z coordinate array

Return type:

numpy.ndarray

property points: list[numpy.ndarray]

A list of the individual points of the Coordinates.

Return type:

list[numpy.ndarray]

as_dict() dict[str, numpy.ndarray]

Cast the Coordinates as a dictionary.

Returns:

d – Dictionary with {‘x’: [], ‘y’: [], ‘z’:[]}

Return type:

dict

to_json(filename: str, **kwargs: dict[str, Any]) str

Save the Coordinates as a JSON file.

Returns:

The Coordinates as a JSON file.

Parameters:
  • filename (str)

  • kwargs (dict[str, Any])

Return type:

str

property closed: bool

Whether or not this is a closed set of Coordinates.

Return type:

bool

property length: float

Perimeter length of the coordinates.

Return type:

float

property center_of_mass: tuple[float, float, float]

Geometrical centroid of the Coordinates.

Return type:

tuple[float, float, float]

property T: numpy.ndarray

Transpose of the Coordinates

Return type:

numpy.ndarray

property shape: tuple[int, int]

Shape of the Coordinates

Return type:

tuple[int, int]

reverse()

Reverse the direction of the Coordinates.

open()

Open the Coordinates (if they are closed)

insert(point: numpy.ndarray, index: int = 0)

Insert a point to the Coordinates.

Parameters:
  • point (numpy.ndarray) – The 3-D point to insert into the Coordinates

  • index (int) – The position of the point in the Coordinates (order index)

close()

Close the Coordinates (if they are open)

rotate(base: tuple[float, float, float] = (0, 0, 0), direction: tuple[float, float, float] = (0, 0, 1), degree: float = 0.0)

Rotate the Coordinates.

Parameters:
  • base (tuple[float, float, float]) – Origin location of the rotation

  • direction (tuple[float, float, float]) – The direction vector

  • degree (float) – rotation angle [degrees]

Raises:

CoordinatesError – Base and direction must be of size 3

translate(vector: tuple[float, float, float] = (0, 0, 0))

Translate this shape with the vector. This function modifies the self object.

Raises:

CoordinatesError – vector must be of size 3

Parameters:

vector (tuple[float, float, float])

simplify(max_angle: float, dx_min: float, dx_max: float = np.inf) tuple[Coordinates, numpy.typing.NDArray[numpy.int64]]

Generate a set of pivot points along the given boundary.

Given a set of boundary points, some maximum angle, and minimum and maximum segment length, this function derives a set of pivot points along the boundary, that define a ‘string’. You might picture a ‘string’ as a thread wrapped around some nails (pivot points) on a board.

Parameters:
  • max_angle (float) – Maximum turning angle [degree]

  • dx_min (float) – Minimum segment length

  • dx_max (float) – Maximum segment length

Returns:

  • new_points – The pivot points’ coordinates.

  • index – The indices of the pivot points into the input points.

Raises:

ValueError – dx_min > dx_maz

Return type:

tuple[Coordinates, numpy.typing.NDArray[numpy.int64]]

__eq__(other: Coordinates) bool

Check the Coordinates for equality with other Coordinates.

Parameters:

other (Coordinates) – The other Coordinates to compare against

Returns:

The check of the Coordinates for equality with other Coordinates.

Return type:

bool

Notes

Coordinates with identical coordinates but different orderings will not be counted as identical.

__hash__()

Hash of Coordinates

Returns:

The hash of Coordinates.

__len__() int

The number of points in the Coordinates.

Returns:

The number of points in the Coordinates.

Return type:

int

__repr__() str

Representation of the Coordinates.

Returns:

Representation of the Coordinates.

Return type:

str

__getitem__(*args, **kwargs)

Array-like indexing and slicing.

Returns:

Indexed or sliced array.

__iter__()

Array-like unpacking.

Returns:

Unpacked array.

copy()

Copy of itself

Returns:

  • An instance of Coordinates, with exactly the same class and coordinates,

  • but sharing a different underlying copy of the data array.

bluemira.geometry.coordinates.vector_intersect_3d(p_1: numpy.ndarray, p_2: numpy.ndarray, p_3: numpy.ndarray, p_4: numpy.ndarray) numpy.ndarray

Get the intersection point between two 3-D vectors.

Parameters:
  • p_1 (numpy.ndarray) – The first point on the first vector

  • p_2 (numpy.ndarray) – The second point on the first vector

  • p_3 (numpy.ndarray) – The first point on the second vector

  • p_4 (numpy.ndarray) – The second point on the second vector

Return type:

The point of the intersection between the two vectors

Raises:

CoordinatesError – If there is no intersection between the points

Notes

Credit: Paul Bourke at https://paulbourke.net/geometry/pointlineplane/#:~:text=The%20shortest%20line%20between%20two%20lines%20in%203D

bluemira.geometry.coordinates.coords_plane_intersect(coords: Coordinates, plane: bluemira.geometry.plane.BluemiraPlane) numpy.ndarray | None

Calculate the intersection of Coordinates with a plane.

Parameters:
Returns:

  • The xyz coordinates (3, n_intersections) of the intersections with the Coordinates.

  • Returns None if there are no intersections detected

Return type:

numpy.ndarray | None

bluemira.geometry.coordinates._coords_plane_intersect(array: numpy.ndarray, p1: numpy.ndarray, vec2: numpy.ndarray) list[float]
Parameters:
  • array (numpy.ndarray)

  • p1 (numpy.ndarray)

  • vec2 (numpy.ndarray)

Return type:

list[float]

bluemira.geometry.coordinates.get_intersect(xy1: numpy.ndarray, xy2: numpy.ndarray) numpy.ndarray[numpy.ndarray[numpy.float64], numpy.ndarray[numpy.float64]]

Calculates the intersection points between two sets of 2-D coordinates. Will return a unique list of x, z intersections (no duplicates in x-z space).

Parameters:
  • xy1 (numpy.ndarray) – The 2-D coordinates between which intersection points should be calculated. Shape = (2, N)

  • xy2 (numpy.ndarray) – The 2-D coordinates between which intersection points should be calculated. Shape = (2, N)

Returns:

The x, z coordinates of the intersection points. shape = (2, N)

Return type:

numpy.ndarray[numpy.ndarray[numpy.float64], numpy.ndarray[numpy.float64]]

Notes

  1. Schwarz, <https://uk.mathworks.com/matlabcentral/fileexchange/11837-fast-and-robust-curve-intersections>

bluemira.geometry.coordinates._intersect_count(xz_inter: numpy.ndarray, xz_2: numpy.ndarray) numpy.ndarray

Get the indices of the intersects that are

Parameters:
  • xz_inter (numpy.ndarray) – x and z coordinates of the points created by the get_intersect function, shape = (N, 2)

  • xz_2 (numpy.ndarray) – x and z coordinates of one of the vertices of the polygon inputted into the get_intersect function. shape = (N, 2)

Returns:

a list of indices j, where the xz_inter[i] is expected to lie on the [j]-th edge, i.e. between xz_2[j] and xz_2[j+1]

Return type:

insertion_locations

bluemira.geometry.coordinates.join_intersect(tgt_poly: Coordinates, ref_poly: Coordinates, *, get_arg: bool = False) tuple[Coordinates, list[int] | None] | Coordinates

Add the intersection points between tgt_poly and ref_poly to tgt_poly.

Parameters:
  • tgt_poly (Coordinates) – The target polygon’s vertices expressed as Coordinates. The intersection points should be inserted into this polygon.

  • ref_poly (Coordinates) – The reference polygon’s vertices expressed as Coordinates.

  • get_arg (bool) – Whether or not to return the indices in the MODIFIED tgt_poly which are newly inerted (intersection) points.

Returns:

  • dest_poly – Destination polygon, which is the union of the (target polygon) and (intersection points).

  • set of insertion_locations – Only returned if get_arg is True: The indices in tgt_poly in which the intersections were added.

Return type:

tuple[Coordinates, list[int] | None] | Coordinates

bluemira.geometry.coordinates.convex_2d_hull_coordinates(coordinates: Coordinates) Coordinates

Given a list of coordinates, simplify it so that only the points that makes up the convex hull of this coordinates set remains.

Parameter

coordinates:

Either a set of planar coordinates (in which case, a 2d convex hull is made), or a set of 3D, non-planar coordinates (in which case, a 3D convex hull is made.)

returns:

ONLY the list of vertices that forms the convex hull. Those that doesn’t form the convex hull are removed.

raises CoordinatesError:

Cannot process coplanar coordinates whose common plane is not perpendicular to one of the 3 cardinal axes.

Parameters:

coordinates (Coordinates)

Return type:

Coordinates

bluemira.geometry.coordinates.choose_direction(vector: numpy.typing.NDArray[float], lower_pt: numpy.typing.NDArray[float], higher_pt: numpy.typing.NDArray[float])

Flip the vector to the correct side (multiply by +1 or -1) so that when lower_pt is projected onto the vector, it has a smaller value than when higher_pt is projected onto the vector.

Returns:

The flipped vector.

Parameters:
  • vector (numpy.typing.NDArray[float])

  • lower_pt (numpy.typing.NDArray[float])

  • higher_pt (numpy.typing.NDArray[float])