Skip to content

points

CoordsCalculator

CoordsCalculator(
    section_array: SectionArray,
    span_model: ISpan,
    cable_loads: CableLoads,
    get_displacement: Callable[[], ndarray],
    obstacle_array: ObstacleArray | None = None,
    additional_points_array: ObstacleArray | None = None,
    **_,
)

Parameters:

Name Type Description Default

section_array

SectionArray

section array

required

span_model

ISpan

The span model to use for the points generation.

required

cable_loads

CableLoads

cable loads, used for beta angle

required

get_displacement

Callable

function that returns an array of chain displacement. Usually, comes from BalanceModel.get_displacement()

required
Source code in src/mechaphlowers/core/geometry/points.py
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
def __init__(
    self,
    section_array: SectionArray,
    span_model: ISpan,
    cable_loads: CableLoads,
    get_displacement: Callable[[], np.ndarray],
    obstacle_array: ObstacleArray | None = None,
    additional_points_array: ObstacleArray | None = None,
    **_,
):
    """Initialize the CoordsCalculator object with section parameters and a span model.

    Args:
        section_array (SectionArray): section array
        span_model (ISpan): The span model to use for the points generation.
        cable_loads (CableLoads): cable loads, used for beta angle
        get_displacement (Callable): function that returns an array of chain displacement. Usually, comes from BalanceModel.get_displacement()
    """
    if obstacle_array is None:
        obstacle_array = ObstacleArray.build_empty_array()
    if additional_points_array is None:
        additional_points_array = ObstacleArray.build_empty_array()
    self.store_references(
        section_array,
        span_model,
        cable_loads,
        get_displacement,
        obstacle_array,
        additional_points_array,
    )
    self.reset()

beta property

beta: ndarray

Get the beta angles for the cable spans. Beta is the angle du to the load on the cable

get_insulators

get_insulators() -> Points

Get the insulators in the section frame.

Source code in src/mechaphlowers/core/geometry/points.py
589
590
591
592
593
594
595
def get_insulators(self) -> Points:
    """Get the insulators in the section frame."""
    insulator_layers = get_insulator_layer(
        self.edge_arm_coords,
        self.get_attachments_coords(),
    )
    return Points.from_coords(insulator_layers)

get_points_for_plot

get_points_for_plot(
    project=False, frame_index=0
) -> tuple[Points, Points, Points]

Get Points objects for span, supports and insulators. Can be used for plotting 2D or 3D graphs.

Parameters:

Name Type Description Default

project

bool

Set to True if 2d graph: this project all objects into a support frame. Defaults to False.

False

frame_index

int

Index of the frame the projection is made. Should be between 0 and nb_supports-1 included. Unused if project is set to False. Defaults to 0.

0

Returns:

Type Description
tuple[Points, Points, Points]

tuple[Points, Points, Points]: Points for spans, supports and insulators respectively.

Raises:

Type Description
ValueError

frame_index is out of range

Source code in src/mechaphlowers/core/geometry/points.py
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
def get_points_for_plot(
    self,
    project=False,
    frame_index=0,
    # origin_position: Literal[
    #     "support", "attachment", "absolute"
    # ] = "attachment",
) -> tuple[Points, Points, Points]:
    """Get Points objects for span, supports and insulators.
    Can be used for plotting 2D or 3D graphs.

    Args:
        project (bool, optional): Set to True if 2d graph: this project all objects into a support frame. Defaults to False.
        frame_index (int, optional): Index of the frame the projection is made. Should be between 0 and nb_supports-1 included. Unused if project is set to False. Defaults to 0.

    Returns:
        tuple[Points, Points, Points]: Points for spans, supports and insulators respectively.

    Raises:
        ValueError: frame_index is out of range
    """
    spans_points: Points = self.get_spans("section")
    supports_points: Points = self.get_supports()
    insulators_points: Points = self.get_insulators()
    # TODO: remove this -> will eventually be delegated to GroupPoints
    if project:
        self._validate_frame_index(frame_index)
        spans_points, supports_points, insulators_points = (
            self.project_to_selected_frame(
                [spans_points, supports_points, insulators_points],
                frame_index,
            )
        )
    return spans_points, supports_points, insulators_points

get_sea_level_supports

get_sea_level_supports() -> Points

Get the supports in the section frame.

Source code in src/mechaphlowers/core/geometry/points.py
585
586
587
def get_sea_level_supports(self) -> Points:
    """Get the supports in the section frame."""
    return Points.from_coords(self.supports_ground_coords)

get_spans

get_spans(
    frame: Literal['cable', 'localsection', 'section'],
) -> Points

get_spans

Get the spans Points in the specified frame.

Parameters:

Name Type Description Default

frame

Literal['cable', 'localsection', 'section']

frame

required

Raises:

Type Description
ValueError

If the frame is not one of 'cable', 'localsection', or 'section'.

Returns:

Name Type Description
Points Points

Points object containing the spans in the specified frame.

Source code in src/mechaphlowers/core/geometry/points.py
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
def get_spans(
    self, frame: Literal["cable", "localsection", "section"]
) -> Points:
    """get_spans

    Get the spans Points in the specified frame.

    Args:
        frame (Literal['cable', 'localsection', 'section']): frame

    Raises:
        ValueError: If the frame is not one of 'cable', 'localsection', or 'section'.

    Returns:
        Points: Points object containing the spans in the specified frame.
    """
    self.set_cable_coordinates(resolution=cfg.graphics.resolution)
    if frame == "cable":
        x_span, y_span, z_span = self.span_in_cable_frame()
    elif frame == "localsection":
        x_span, y_span, z_span = self.span_in_localsection_frame()
    elif frame == "section":
        x_span, y_span, z_span = self.span_in_section_frame()
    else:
        raise ValueError(
            "Frame must be 'cable', 'localsection' or 'section'"
        )

    return Points.from_vectors(x_span, y_span, z_span)

get_supports

get_supports() -> Points

Get the supports in the section frame.

Source code in src/mechaphlowers/core/geometry/points.py
576
577
578
579
580
581
582
583
def get_supports(self) -> Points:
    """Get the supports in the section frame."""
    supports_layers = get_supports_layer(
        self.supports_ground_coords,
        self.center_arm_coords,
        self.edge_arm_coords,
    )
    return Points.from_coords(supports_layers)

project_to_selected_frame

project_to_selected_frame(
    points_array: list[PointsT], frame_index: int
) -> list[PointsT]

Project points object into a support frame.

Used for 2D plots that need to be projected in a specific frame.

Parameters:

Name Type Description Default

points_array

list[PointsT]

array of Points of SparsePoints objects

required

frame_index

int

Index of the frame the projection is made.

required

Returns:

Type Description
list[PointsT]

list[PointsT]: array of points object projected in local frame

list[PointsT]

projected into the frame of support number frame_index.

Source code in src/mechaphlowers/core/geometry/points.py
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
def project_to_selected_frame(
    self,
    points_array: list[PointsT],
    frame_index: int,
) -> list[PointsT]:
    """Project points object into a support frame.

    Used for 2D plots that need to be projected in a specific frame.

    Args:
        points_array (list[PointsT]): array of Points of SparsePoints objects
        frame_index (int): Index of the frame the projection is made.

    Returns:
        list[PointsT]: array of points object projected in local frame
        projected into the frame of support number `frame_index`.
    """
    translation_vector = -self.get_supports().coords[frame_index, 0]
    # set z coordinate to zero
    translation_vector[2] = 0.0
    angle_to_project = np.cumsum(self.line_angle)[frame_index]
    result_points = []
    for original_points in points_array:
        new_points = compute_new_frame(
            original_points, translation_vector, angle_to_project
        )
        # invert y axis to get more natural view
        x, y, z = new_points.vectors
        new_points.coords = np.array([x, -y, z]).T
        result_points.append(new_points)
    return result_points

refresh_additional_points

refresh_additional_points() -> None

Need to be called when any modification to additional_points_array occurs

Source code in src/mechaphlowers/core/geometry/points.py
434
435
436
437
438
439
440
441
def refresh_additional_points(self) -> None:
    """Need to be called when any modification to additional_points_array occurs"""
    self.additional_points = SparsePoints.builder_from_obstacle_array(
        self.additional_points_array
    )
    self.compute_sparse_points_coords(
        self.additional_points_array, self.additional_points
    )

refresh_obstacles

refresh_obstacles() -> None

Need to be called when any modification to obstacle_array occurs

Source code in src/mechaphlowers/core/geometry/points.py
425
426
427
428
429
430
431
432
def refresh_obstacles(self) -> None:
    """Need to be called when any modification to obstacle_array occurs"""
    self.obstacles_points = SparsePoints.builder_from_obstacle_array(
        self.obstacle_array
    )
    self.compute_sparse_points_coords(
        self.obstacle_array, self.obstacles_points
    )

refresh_sparse_points

refresh_sparse_points() -> None

Refresh coordinates for both obstacle_array and additional_points_array.

Source code in src/mechaphlowers/core/geometry/points.py
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
def refresh_sparse_points(self) -> None:
    """Refresh coordinates for both obstacle_array and additional_points_array."""
    self.obstacles_points = SparsePoints.builder_from_obstacle_array(
        self.obstacle_array
    )
    self.compute_sparse_points_coords(
        self.obstacle_array, self.obstacles_points
    )

    self.additional_points = SparsePoints.builder_from_obstacle_array(
        self.additional_points_array
    )
    self.compute_sparse_points_coords(
        self.additional_points_array, self.additional_points
    )

set_cable_coordinates

set_cable_coordinates(resolution: int) -> None

Set the span in the cable frame 2D coordinates based on the span model and resolution.

Source code in src/mechaphlowers/core/geometry/points.py
405
406
407
def set_cable_coordinates(self, resolution: int) -> None:
    """Set the span in the cable frame 2D coordinates based on the span model and resolution."""
    self.x_cable, self.z_cable = self.span_model.get_coords(resolution)

span_in_cable_frame

span_in_cable_frame() -> tuple[ndarray, ndarray, ndarray]

Get spans as vectors in the cable frame.

Source code in src/mechaphlowers/core/geometry/points.py
509
510
511
512
513
514
515
516
517
518
519
520
def span_in_cable_frame(self) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Get spans as vectors in the cable frame."""
    # Rotate the cable with an angle to represent the wind
    self.set_cable_coordinates(resolution=cfg.graphics.resolution)
    x_span, y_span, z_span = cable_to_beta_plane(
        self.x_cable[:, :-1],
        self.z_cable[:, :-1],
        self.beta[:-1],
        self.plane.a_chain[:-1],
        self.plane.b_chain[:-1],
    )
    return x_span, y_span, z_span

span_in_localsection_frame

span_in_localsection_frame() -> (
    tuple[ndarray, ndarray, ndarray]
)

Get spans as vectors in the localsection frame.

Source code in src/mechaphlowers/core/geometry/points.py
522
523
524
525
526
527
528
529
530
def span_in_localsection_frame(
    self,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Get spans as vectors in the localsection frame."""
    x_span, y_span, z_span = self.span_in_cable_frame()
    x_span, y_span, z_span = cable_to_localsection_frame(
        x_span, y_span, z_span, self.plane.azimuth_angle[:-1]
    )
    return x_span, y_span, z_span

span_in_section_frame

span_in_section_frame() -> tuple[ndarray, ndarray, ndarray]

Get spans as vectors in the section frame.

Source code in src/mechaphlowers/core/geometry/points.py
532
533
534
535
536
537
538
539
540
541
542
543
544
def span_in_section_frame(
    self,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
    """Get spans as vectors in the section frame."""
    # TODO: warning here : double call to set_cable_coordinates
    x_span, y_span, z_span = self.span_in_localsection_frame()
    x_span, y_span, z_span = translate_cable_to_support_from_attachments(
        x_span,
        y_span,
        z_span,
        self.get_attachments_coords(),
    )
    return x_span, y_span, z_span

Points

Points(coords: ndarray)

This class handles a set of points in 3D space, represented as a 3D numpy array. The points are stored in a 3D array with shape (number of layers, number of points, 3), where the last dimension represents the x, y, and z coordinates of each point.

It provides methods to convert the coordinates to vectors, points, and to create a Points object from.

Do not use this class directly, use the factory methods from_vectors or from_coords.

Examples:

1
2
3
4
5
6
7
>>> points = Points.from_vectors(x, y, z)
>>> span0, span1, span2, ... = points.coords
>>> span0
array([[x0, y0, z0],
    [x1, y1, z1],
    ...
    ])
Source code in src/mechaphlowers/core/geometry/points.py
 95
 96
 97
 98
 99
100
def __init__(self, coords: np.ndarray):
    if coords.ndim != 3 or coords.shape[2] != 3:
        raise ValueError(
            "Coordinates must be a 3D array with shape (number of layers, number of points, 3)"
        )
    self.coords = coords

vectors property

vectors: tuple[ndarray, ndarray, ndarray]

Convert the coordinates to vectors. Returns the x, y, z coordinates as separate 2D arrays.

Returns:

Type Description
tuple[ndarray, ndarray, ndarray]

tuple[np.ndarray, np.ndarray, np.ndarray]: Three 2D arrays representing the x, y, and z coordinates.

Examples:

1
2
3
4
5
6
>>> x, y, z = points.vectors
>>> x
array([[x0_span0, x0_span1, x0_span2],
    [x1_span0, x1_span1, x1_span2],
    ...
    ])

flat_layer

flat_layer() -> ndarray

Convert the coordinates to a 2D array of points with a column dedicated to layer number for plotting or other uses as dataframe usage.

Not implemented yet

Returns:

Type Description
ndarray

np.ndarray: A 2D array of shape (number of layers x number of points, 4) where each row is a point (num layer, x, y, z).

Source code in src/mechaphlowers/core/geometry/points.py
157
158
159
160
161
162
163
164
165
def flat_layer(self) -> np.ndarray:
    """Convert the coordinates to a 2D array of points with a column dedicated to layer number for plotting or other uses as dataframe usage.

    Not implemented yet

    Returns:
        np.ndarray: A 2D array of shape (number of layers x number of points, 4) where each row is a point (num layer, x, y, z).
    """
    raise NotImplementedError

from_coords classmethod

from_coords(coords: ndarray) -> Self

Create Points from separate x, y, and z coordinates. Args: coords (np.ndarray): A 3D array of shape (layers, n_points, 3) where each row is a point (x, y, z).

Returns:

Name Type Description
Points Self

An instance of the Points class containing the coordinates.

Source code in src/mechaphlowers/core/geometry/points.py
195
196
197
198
199
200
201
202
203
204
@classmethod
def from_coords(cls, coords: np.ndarray) -> Self:
    """Create Points from separate x, y, and z coordinates.
    Args:
        coords (np.ndarray): A 3D array of shape (layers, n_points, 3) where each row is a point (x, y, z).

    Returns:
        Points: An instance of the Points class containing the coordinates.
    """
    return cls(coords)

from_vectors classmethod

from_vectors(x: ndarray, y: ndarray, z: ndarray) -> Self

Create Points from a vector of coordinates.

Parameters:

Name Type Description Default

x

ndarray

Array of x-coordinates (N, L).

required

y

ndarray

Array of y-coordinates (N, L).

required

z

ndarray

Array of z-coordinates (N, L).

required

Returns:

Name Type Description
Points Self

An instance of the Points class containing the coordinates.

Raises:

Type Description
ValueError

If x, y, or z are not 2D arrays.

Source code in src/mechaphlowers/core/geometry/points.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
@classmethod
def from_vectors(cls, x: np.ndarray, y: np.ndarray, z: np.ndarray) -> Self:
    # Mypy does not support the Self type from typing
    """Create Points from a vector of coordinates.

    Args:
        x (np.ndarray): Array of x-coordinates (N, L).
        y (np.ndarray): Array of y-coordinates (N, L).
        z (np.ndarray): Array of z-coordinates (N, L).

    Returns:
        Points: An instance of the Points class containing the coordinates.

    Raises:
        ValueError: If x, y, or z are not 2D arrays.
    """
    if x.ndim != 2 or y.ndim != 2 or z.ndim != 2:
        raise ValueError("x, y, and z must be 2D arrays")

    return cls(vectors_to_coords(x, y, z))

points

points(stack=False) -> ndarray

Convert the coordinates to a 2D array of points for plotting or other uses.

Parameters:

Name Type Description Default

stack

bool

If True, stack NaN values to separate spans when plotting. Defaults to False.

False

Returns:

Type Description
ndarray

np.ndarray: A 2D array of shape (number of points, 3) where each row is a point (x, y, z).

Examples:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
>>> points_array = points.points(stack=False)
>>> points_array
array([[x0, y0, z0],
    [x1, y1, z1],
    [x2, y2, z2],
    ...
    ])
>>> points_array_stacked = points.points(stack=True)
>>> points_array_stacked
array([[x0_span0, y0_span0, z0_span0],
    [x1_span0, y1_span0, z1_span0],
    [x2_span0, y2_span0, z2_span0],
    ...
    [nan, nan, nan]
    [x0_span1, y0_span1, z0_span1],
    ...
    ])
Source code in src/mechaphlowers/core/geometry/points.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
def points(self, stack=False) -> np.ndarray:
    """Convert the coordinates to a 2D array of points for plotting or other uses.

    Args:
        stack (bool, optional): If True, stack NaN values to separate spans when plotting. Defaults to False.

    Returns:
        np.ndarray: A 2D array of shape (number of points, 3) where each row is a point (x, y, z).

    Examples:
        >>> points_array = points.points(stack=False)
        >>> points_array
        array([[x0, y0, z0],
            [x1, y1, z1],
            [x2, y2, z2],
            ...
            ])
        >>> points_array_stacked = points.points(stack=True)
        >>> points_array_stacked
        array([[x0_span0, y0_span0, z0_span0],
            [x1_span0, y1_span0, z1_span0],
            [x2_span0, y2_span0, z2_span0],
            ...
            [nan, nan, nan]
            [x0_span1, y0_span1, z0_span1],
            ...
            ])
    """
    if stack is False:
        return coords_to_points(self.coords)
    else:
        return stack_nan(self.coords)

SparsePoints

SparsePoints(
    object_name: list,
    point_index: ndarray,
    span_index: ndarray,
    x: ndarray,
    y: ndarray,
    z: ndarray,
    object_type: list,
)

Class handle set of 3D points grouped by objects, but all objects do not have the same number of points.

Main use case is for managing obstacle points.

Source code in src/mechaphlowers/core/geometry/points.py
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
def __init__(
    self,
    object_name: list,
    point_index: np.ndarray,
    span_index: np.ndarray,
    x: np.ndarray,
    y: np.ndarray,
    z: np.ndarray,
    object_type: list,
) -> None:
    self.object_name = object_name
    self.point_index = point_index
    self.span_index = span_index
    self.x = x
    self.y = y
    self.z = z
    self.object_type = object_type

dict_coords

dict_coords() -> dict

Returns a dictionary storing object coordinates.

Key is object name, value is coordinates of object.

Format: {'obs_0': [[x0, y0, z0], [x1, y1, z1], ...]}

Source code in src/mechaphlowers/core/geometry/points.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
def dict_coords(self) -> dict:
    """Returns a dictionary storing object coordinates.

    Key is object name, value is coordinates of object.

    Format: {'obs_0': [[x0, y0, z0], [x1, y1, z1], ...]}
    """
    points = self.points()
    split_indices = np.nonzero(self.point_index == 0)[0]
    if len(split_indices) > 1:
        array_coords = np.split(points, split_indices[1:], axis=0)
    else:
        array_coords = [points]
    dict_coords = {}
    for i in range(len(split_indices)):
        object_name = self.object_name[split_indices[i]]
        dict_coords[object_name] = array_coords[i]
    return dict_coords

points

points(stack=False) -> ndarray

[[x0, y0, z0], # first obstacle [x1, y1, z1], [np.nan, np.nan, np.nan], # separator if stack=True [x0, y0, z0], # second obstacle [x1, y1, z1], [x2, y2, z2], [np.nan, np.nan, np.nan], # separator if stack=True ]

Source code in src/mechaphlowers/core/geometry/points.py
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def points(self, stack=False) -> np.ndarray:
    """
    [[x0, y0, z0], # first obstacle
    [x1, y1, z1],
    [np.nan, np.nan, np.nan], # separator if stack=True
    [x0, y0, z0], # second obstacle
    [x1, y1, z1],
    [x2, y2, z2],
    [np.nan, np.nan, np.nan], # separator if stack=True
    ]
    """
    points = self.coords
    # This method assume that points are correctly ordered by object and point index
    if stack:
        # get indices at the beginning of each object
        insert_indices = np.nonzero(self.point_index == 0)[0]
        nan_array = np.array([np.nan, np.nan, np.nan])
        points = np.insert(points, insert_indices, nan_array, axis=0)
    return points

compute_new_frame

compute_new_frame(
    points: PointsT,
    translation_vector: ndarray,
    angle_to_project: float64,
) -> PointsT

Change the frame of the given Points by applying a translation and a rotation.

Parameters:

Name Type Description Default

points

Points

points to transform

required

translation_vector

ndarray

translation vector to apply

required

angle_to_project

float64

angle of the rotation in radians

required

Returns:

Name Type Description
Points PointsT

new Points object in the new frame

Source code in src/mechaphlowers/core/geometry/points.py
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
def compute_new_frame(
    points: PointsT,
    translation_vector: np.ndarray,
    angle_to_project: np.float64,
) -> PointsT:
    """Change the frame of the given Points by applying a translation and a rotation.

    Args:
        points (Points): points to transform
        translation_vector (np.ndarray): translation vector to apply
        angle_to_project (np.float64): angle of the rotation in radians

    Returns:
        Points: new Points object in the new frame
    """
    points.coords = points.coords + translation_vector

    points.coords = rotate_vector(points.vectors, angle_to_project).T
    return points

coords_to_points

coords_to_points(coords: ndarray) -> ndarray

Convert the support coordinates to a format suitable for plotting.

Parameters:

Name Type Description Default

coords

ndarray

A 3D array of shape (layers, n_points, 3) where each row is a point (x, y, z).

required

Returns:

Type Description
ndarray

np.ndarray: A 2D array of shape (number of points, 3) where each row is a point (x, y, z).

Source code in src/mechaphlowers/core/geometry/points.py
64
65
66
67
68
69
70
71
72
73
def coords_to_points(coords: np.ndarray) -> np.ndarray:
    """Convert the support coordinates to a format suitable for plotting.

    Args:
        coords (np.ndarray): A 3D array of shape (layers, n_points, 3) where each row is a point (x, y, z).

    Returns:
        np.ndarray: A 2D array of shape (number of points, 3) where each row is a point (x, y, z).
    """
    return coords.reshape(-1, 3, order='F')

stack_nan

stack_nan(coords: ndarray) -> ndarray

Stack NaN values to the coords array to ensure consistent shape when plot and separate layers in a 2D array.

Source code in src/mechaphlowers/core/geometry/points.py
35
36
37
38
39
40
def stack_nan(coords: np.ndarray) -> np.ndarray:
    """Stack NaN values to the coords array to ensure consistent shape when plot and separate layers in a 2D array."""
    stack_array = np.zeros((coords.shape[0], 1, coords.shape[2])) * np.nan
    return np.concatenate((coords, stack_array), axis=1).reshape(
        -1, 3, order='C'
    )

vectors_to_coords

vectors_to_coords(
    x: ndarray, y: ndarray, z: ndarray
) -> ndarray

Convert 3 vectors of coordinates into an array of points.

Takes 3 numpy arrays representing x, y, and z coordinates and combines them into a single array of 3D points. The input vector format is expected to be (N, L) where N is the number of points per layer and L is the number of layers. The output will be an array of shape (number of layers, number of points, 3) where each row represents a point in 3D space.

Parameters:

Name Type Description Default

x

ndarray

Array of x-coordinates (N, L)

required

y

ndarray

Array of y-coordinates (N, L)

required

z

ndarray

Array of z-coordinates (N, L)

required

Returns:

Type Description
ndarray

np.ndarray: Array of points with shape (L,N,3) where N is the length of input vectors

Source code in src/mechaphlowers/core/geometry/points.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def vectors_to_coords(
    x: np.ndarray, y: np.ndarray, z: np.ndarray
) -> np.ndarray:
    """Convert 3 vectors of coordinates into an array of points.

    Takes 3 numpy arrays representing x, y, and z coordinates and combines them into a single array of 3D points.
    The input vector format is expected to be (N, L) where N is the number of points per layer and L is the number of layers.
    The output will be an array of shape (number of layers, number of points, 3) where each row represents a point in 3D space.

    Args:
        x (np.ndarray): Array of x-coordinates (N, L)
        y (np.ndarray): Array of y-coordinates (N, L)
        z (np.ndarray): Array of z-coordinates (N, L)

    Returns:
        np.ndarray: Array of points with shape (L,N,3) where N is the length of input vectors

    """
    return np.array([x, y, z]).T