1. coords — A structured collection of 3D coordinates.

The coords module defines the Coords class, which is the basic data structure in pyFormex to store the coordinates of points in a 3D space.

This module implements a data class for storing large sets of 3D coordinates and provides an extensive set of methods for transforming these coordinates. Most of pyFormex’s classes which represent geometry (e.g. Formex, Mesh, TriSurface, Curve) use a Coords object to store their coordinates, and thus inherit all the transformation methods of this class.

While the user will mostly use the higher level classes, he might occasionally find good reason to use the Coords class directly as well.

1.1. Classes defined in module coords

class coords.Coords(data=None, dtyp=at.Float, copy=False)[source]

A structured collection of points in a 3D cartesian space.

The Coords class is the basic data structure used throughout pyFormex to store the coordinates of points in a 3D space. It is used by other classes, such as Formex, Mesh, TriSurface, Curve, which thus inherit the same transformation capabilities. Applications will mostly use the higher level classes, which have more elaborated consistency checking and error handling.

Coords is implemented as a subclass of numpy.ndarray, and thus inherits all its methods and atttributes. The last axis of the Coords however always has a length equal to 3. Each set of 3 values along the last axis are the coordinates (in a global 3D cartesian coordinate system) of a single point in space. The full Coords array thus is a collection of points. It the array is 2-dimensional, the Coords is a flat list of points. But if the array has more dimensions, the collection of points itself becomes structured.

The float datatype is only checked at creation time. It is the responsibility of the user to keep this consistent throughout the lifetime of the object.

Note

Methods that transform a Coords object, like scale(), translate(), rotate(), … do not change the original Coords object, but return a new object. Some methods however have an inplace option that allows the user to force coordinates to be changed in place. This option is seldom used however: rather we conveniently use statements like:

X = X.some_transform()

and Python can immediately free and recollect the memory used for the old object X.

Parameters
  • data (float array_like, or string) –

    Data to initialize the Coords. The last axis should have a length of 1, 2 or 3, but will be expanded to 3 if it is less, filling the missing coordinates with zeros. Thus, if you only specify two coordinates, all points are lying in the z=0 plane. Specifying only one coordinate creates points along the x-axis.

    As a convenience, data may also be entered as a string, which will be passed to the pattern() function to create the actual coordinates of the points.

    If no data are provided, an empty Coords with shape (0,3) is created.

  • dtyp (float datatype, optional) – It not provided, the datatype of data is used, or the default Float (which is equivalent to numpy.float32).

  • copy (bool) – If True, the data are copied. The default setting will try to use the original data if possible, e.g. if data is a correctly shaped and typed numpy.ndarray.

Returns

Coords – An instance of the Coords class, which is basically an ndarray of floats, with the last axis having a length of 3.

The Coords instance has a number of attributes that provide views on (part of) the data. They are a notational convenience over using indexing. These attributes can be used to set all or some of the coordinates by direct assignment. The assigned data should however be broadcast compatible with the assigned shape: the shape of the Coords can not be changed.

Examples

>>> Coords([1.,2.])
Coords([1., 2., 0.])
>>> X = Coords(np.arange(6).reshape(2,3))
>>> print(X)
[[0. 1. 2.]
 [3. 4. 5.]]
>>> print(X.y)
[1. 4.]
>>> X.z[1] = 9.
>>> print(X)
[[0. 1. 2.]
 [3. 4. 9.]]
>>> print(X.xz)
[[0. 2.]
 [3. 9.]]
>>> X.x = 0.
>>> print(X)
[[0. 1. 2.]
 [0. 4. 9.]]
>>> Y = Coords(X)             # Y shares its data with X
>>> Z = Coords(X, copy=True)  # Z is independent
>>> Y.y = 5
>>> Z.z = 6
>>> print(X)
[[0.  5.  2.]
 [0.  5.  9.]]
>>> print(Y)
[[0.  5.  2.]
 [0.  5.  9.]]
>>> print(Z)
[[0.  1.  6.]
 [0.  4.  6.]]
>>> X.coords is X
True
>>> Z.xyz = [1,2,3]
>>> print(Z)
[[1.  2.  3.]
 [1.  2.  3.]]
>>> print(Coords('0123'))  # initialize with string
[[0. 0. 0.]
 [1. 0. 0.]
 [1. 1. 0.]
 [0. 1. 0.]]

1.2. Functions defined in module coords

coords.bbox(objects)[source]

Compute the bounding box of a list of objects.

The bounding box of an object is the smallest rectangular cuboid in the global Cartesian coordinates, such that no points of the objects lie outside that cuboid. The resulting bounding box of the list of objects is the smallest bounding box that encloses all the objects in the list.

Parameters

objects (object or list of objects) – One or more (list or tuple) objects that have a method bbox() returning the object’s bounding box as a Coords with two points.

Returns

Coords – A Coords object with two points: the first contains the minimal coordinate values, the second has the maximal ones of the overall bounding box encompassing all objects.

Notes

Objects that do not have a bbox() method or whose bbox() method returns invalid values, are silently ignored.

See also

Coords.bbox

compute the bounding box of a Coords object.

Examples

>>> bbox((Coords([-1.,1.,0.]),Coords([2,-3])))
Coords([[-1., -3.,  0.],
        [ 2.,  1.,  0.]])
coords.bboxIntersection(A, B)[source]

Compute the intersection of the bounding box of two objects.

Parameters
  • A (first object) – An object having a bbox method returning its boundary box.

  • B (second object) – Another object having a bbox method returning its boundary box.

Returns

Coords (2,3) – A Coords specifying the intersection of the bounding boxes of the two objects. This again has the format of a bounding box: a coords with two points: one with the minimal and one with the maximal coordinates. If the two bounding boxes do not intersect, an empty Coords is returned.

Notes

Since bounding boxes are Coords objects, it is possible to pass computed bounding boxes as arguments. The bounding boxes are indeed their own bounding box.

Examples

>>> A = Coords([[-1.,1.],[2,-3]])
>>> B = Coords([[0.,1.],[4,2]])
>>> C = Coords([[0.,2.],[4,2]])
>>> bbox((A,B))
Coords([[-1., -3.,  0.],
        [ 4.,  2.,  0.]])

The intersection of the bounding boxes of A and B degenerates into a line segment parallel to the x-axis:

>>> bboxIntersection(A,B)
Coords([[0., 1., 0.],
        [2., 1., 0.]])

The bounding boxes of A and C do not intersect:

>>> bboxIntersection(A,C)
Coords([], shape=(0, 3))
coords.origin()[source]

ReturnCreate a Coords holding the origin of the global coordinate system.

Returns

  • Coords (3,) – A Coords holding a single point with coordinates (0.,0.,0.).

  • Exmaples

  • ——–

  • >>> origin()

  • Coords([0., 0., 0.])

coords.pattern(s, aslist=False)[source]

Generate a sequence of points on a regular grid.

This function creates a sequence of points that are on a regular grid with unit step. These points are created from a simple string input, interpreting each character as a code specifying how to move from the last to the next point. The start position is always the origin (0.,0.,0.).

Currently the following codes are defined:

  • 0 or +: goto origin (0.,0.,0.)

  • 1..8: move in the x,y plane

  • 9 or .: remain at the same place (i.e. duplicate the last point)

  • A..I: same as 1..9 plus step +1. in z-direction

  • a..i: same as 1..9 plus step -1. in z-direction

  • /: do not insert the next point

Any other character raises an error.

When looking at the x,y-plane with the x-axis to the right and the y-axis up, we have the following basic moves: 1 = East, 2 = North, 3 = West, 4 = South, 5 = NE, 6 = NW, 7 = SW, 8 = SE.

Adding 16 to the ordinal of the character causes an extra move of +1. in the z-direction. Adding 48 causes an extra move of -1. This means that ‘ABCDEFGHI’, resp. ‘abcdefghi’, correspond with ‘123456789’ with an extra z +/-= 1. This gives the following schema:

    z+=1             z unchanged            z -= 1

F    B    E          6    2    5         f    b    e
     |                    |                   |
     |                    |                   |
C----I----A          3----9----1         c----i----a
     |                    |                   |
     |                    |                   |
G    D    H          7    4    8         g    d    h

The special character ‘/’ can be put before any character to make the move without inserting the new point. The string should start with a ‘0’ or ‘9’ to include the starting point (the origin) in the output.

Parameters
  • s (str) – A string with characters generating subsequent points.

  • aslist (bool, optional) – If True, the points are returned as lists of integer coordinates instead of a Coords object.

Returns

Coords | list – The default is to return the generated points as a Coords. With aslist=True however, the points are returned as a list of tuples holding 3 integer grid coordinates.

See also

xpattern

create a Coords from a pattern and group them into elements

fpattern

create a Coords from a pattern with a grouping prefix

Examples

>>> pattern('0123')
Coords([[0., 0., 0.],
        [1., 0., 0.],
        [1., 1., 0.],
        [0., 1., 0.]])
>>> pattern('2'*4)
Coords([[0., 1., 0.],
        [0., 2., 0.],
        [0., 3., 0.],
        [0., 4., 0.]])
coords.xpattern(s, nplex=1)[source]

Create a Coords from a string pattern and group them into elements.

Creates a sequence of points using pattern(), and groups the points by nplex to create a Coords with shape (-1,nplex,3).

Parameters
  • s (str) – The string to pass to pattern() to produce the sequence of points.

  • nplex (int) – The number of subsequent points to group together to create the structured Coords.

Returns

Coords – A Coords with shape (-1,nplex,3).

Raises

ValueError – If the number of points produced by the input string s is not a multiple of nplex.

Examples

>>> print(xpattern('.12.34',3))
[[[0. 0. 0.]
  [1. 0. 0.]
  [1. 1. 0.]]

 [[1. 1. 0.]
  [0. 1. 0.]
  [0. 0. 0.]]]
coords.align(L, align='|--', offset=(0.0, 0.0, 0.0))[source]

Align a list of geometrical objects.

Parameters
  • L (list of Coords or Geometry objects) – A list of objects that have an appropriate align method, like the Coords and Geometry (and its subclasses).

  • align (str) –

    A string of three characters, one for each coordinate direction, that define how the subsequent objects have to be aligned in each of the global axis directions:

    • ’-‘ : align on the minimal coordinate value

    • ’+’ : align on the maximal coordinate value

    • ’0’ : align on the middle coordinate value

    • ’|’align the minimum value on the maximal value of the

      previous item

    Thus the string '|--' will juxtapose the objects in the x-direction, while aligning them on their minimal coordinates in the y- and z- direction.

  • offset (float array_like (3,), optional) – An extra translation to be given to each subsequent object. This can be used to create a space between the objects, instead of juxtaposing them.

Returns

list of objects – A list with the aligned objects.

Notes

See also example Align.

See also

Coords.align

align a single object with respect to a point.

coords.fpattern(s, nplex=1)[source]

Create a Coords from a string pattern containing a grouping prefix.

Create a sequence of points using pattern(), and group the points as described by the string prefix. The input string is of the form ‘#:pattern’ where # is either a number or ‘l’, and pattern is a valid input string for pattern(). The pattern is used to generate a series of points on a regular grid. Then # prefix is then used to create point groups:

  • If # is an int, its value is the plexitude of the point groups to be created by xpattern().

  • If # is an ‘l’ (line), a first point equal to the origin is added, and then plex-2 elements are created from each point to the next. This is an efficient way to create line elements connected into a polyline. In this case the ‘/’ character in the pattern makes the next point not being connected to the previous and the point thus becomes the start of a new polyline. A ‘+’ in the pattern is equivalent to ‘/0’ and creates a disconnected line starting again from the origin.

Parameters

s (str) – A string of the form ‘#:pattern’ where # is either an int or ‘l’, and pattern is a valid input string for pattern().

Returns

Coords – A Coords with shape (-1,nplex,3), where nplex is # if it was an int, or 2 if it was an ‘l’.

Raises

ValueError – If the pattern is invalid, if the prefix is invalid or absent, or if the number of points produced by the pattern is not a multiple of the plexitude specified in the prefix.

Examples

Create six points and split them in elements per three.

>>> print(fpattern('3:.12.34'))
[[[0. 0. 0.]
  [1. 0. 0.]
  [1. 1. 0.]]

 [[1. 1. 0.]
  [0. 1. 0.]
  [0. 0. 0.]]]
>>> fpattern('3:012')
Coords([[[0., 0., 0.],
         [1., 0., 0.],
         [1., 1., 0.]]])
>>> fpattern('l:012')
Coords([[[0., 0., 0.],
         [0., 0., 0.]],

        [[0., 0., 0.],
         [1., 0., 0.]],

        [[1., 0., 0.],
         [1., 1., 0.]]])
>>> fpattern('012')
Traceback (most recent call last):
...
ValueError: Invalid or missing prefix in fpattern string
>>> fpattern('4:012')
Traceback (most recent call last):
...
ValueError: Can not reshape 3 points to plexitude 4
coords.otherAxes(i)[source]

Return all global axes except the specified one

Parameters

i (int (0,1,2)) – One of the global axes.

Returns

  • tuple of ints – Two ints (j,k) identifying the other global axes in such order that (i,j,k) is a right-handed coordinate system.

  • >>> otherAxes(1)

  • (2, 0)