The Coords class is the basic data structure used throughout pyFormex to store coordinates of points in a 3D space.
The Coords class is used by other classes, such as Formex and Surface, which thus inherit the same transformation capabilities. Applications will mostly use the higher level classes, which usually have more elaborated consistency checking and error handling.
Coords is implemented as a floating point numpy (Numerical Python) array whose last axis has a length equal to 3. Each set of 3 values along the last axis thus represents a single point in 3D cartesian space.
The datatype should be a float type; the default is Float, which is equivalent to numpy's float32. These restrictions are currently only checked at creation time. It is the responsibility of the user to keep consistency.
The Coords class has this constructor:
cls,data=None,dtyp=Float,copy=False) |
If no data are given, a single point (0.,0.,0.) will be created. If specified, data should evaluate to an (...,3) shaped array of floats. If copy==True, the data are copied. If no dtyp is given that of data are used, or float32 by default.
Coords objects have the following methods:
) |
This reshapes the array to a 2-dimensional array, flattening the structure of the points.
) |
This is the shape of the Coords array with last axis removed. The full shape of the Coords array can be obtained from its shape attribute.
) |
) |
) |
) |
) |
The bounding box is the smallest rectangular volume in global coordinates, such at no points are outside the box. It is returned as a Coords object with shape (2,3): the first row holds the minimal coordinates and the second row the maximal.
) |
The center of a Coords is the center of its bbox(). The return value is a (3,) shaped Coords object.
) |
The centroid of a Coords is the point whose coordinates are the mean values of all points. The return value is a (3,) shaped Coords object.
) |
Return an array with the length of the bbox along the 3 axes.
) |
This estimate is the length of the diagonal of the bbox().
) |
The bounding sphere is the smallest sphere with center in the center() of the Coords, and such that no points of the Coords are lying outside the sphere.
p,n) |
p is a point specified by 3 coordinates. n is the normal vector to a plane, specified by 3 components.
The return value is a [...] shaped array with the distance of each point to the plane through p and having normal n. Distance values are positive if the point is on the side of the plane indicated by the positive normal.
p,n) |
p is a point on the line specified by 3 coordinates. n is a vector specifying the direction of the line through p.
The return value is a [...] shaped array with the distance of each point to the line through p with direction n. All distance values are positive or zero.
p) |
p is a single point specified by 3 coordinates.
The return value is a [...] shaped array with the distance of each point to point p. All distance values are positive or zero.
dir=0,min=None,max=None,atol=0.) |
This function is very convenient in clipping a Coords in a specified direction. It returns a 1D integer array flagging (with a value 1 or True) the elements having nodal coordinates in the required range. Use where(result) to get a list of element numbers passing the test. Or directly use clip() or cclip() to create the clipped Coords.
The test plane can be define in two ways depending on the value of dir. If dir == 0, 1 or 2, it specifies a global axis and min and max are the minimum and maximum values for the coordinates along that axis. Default is the 0 (or x) direction.
Else, dir should be compatible with a (3,) shaped array and specifies the direction of the normal on the planes. In this case, min and max are points and should also evaluate to (3,) shaped arrays.
One of the two clipping planes may be left unspecified.
fmt="%10.3e %10.3e %10.3e") |
The supplied format should contain 3 formatting sequences for the three coordinates of a point.
f) |
scale,dir=None,inplace=False) |
The scale should be a list of 3 scaling factors for the 3 axis directions, or a single scaling factor. In the latter case, dir (a single axis number or a list) may be given to specify the direction(s) to scale. The default is to produce a homothetic scaling.
vector,distance=None,inplace=False) |
The translation vector can be specified in one of the following ways: - an axis number (0,1,2), - a single translation vector, - an array of translation vectors. If an axis number is given, a unit vector in the direction of the specified axis will be used. If an array of translation vectors is given, it should be broadcastable to the size of the Coords array. If a distance value is given, the translation vector is multiplied with this value before it is added to the coordinates.
Thus, the following are all equivalent: F.translate(1) F.translate(1,1) F.translate([0,1,0]) F.translate([0,2,0],0.5)
angle,axis=2,around=None,inplace=False) |
The angle is specified in degrees. The axis is either one of (0,1,2) designating the global axes, or a vector specifying an axis through the origin. If no axis is specified, rotation is around the 2(z)-axis. This is convenient for working on 2D-structures.
As a convenience, the user may also specify a 3x3 rotation matrix, in which case the function rotate(mat) is equivalent to affine(mat).
All rotations are performed around the point [0,0,0], unless a rotation origin is specified in the argument 'around'.
dir,dir1,skew,inplace=False) |
The coordinate dir is replaced with (dir + skew * dir1).
dir=2,pos=0,inplace=False) |
Default position of the plane is through the origin. Default mirror direction is the z-direction.
mat,vec=None,inplace=False) |
The returned Coords has coordinates given by xorig * mat + vec, where mat is a 3x3 matrix and vec a length 3 list.
dir=[0,1,2],scale=[1.,1.,1.]) |
dir specifies which coordinates are interpreted as resp. distance(r), angle(theta) and height(z). Default order is [r,theta,z]. scale will scale the coordinate values prior to the transformation. (scale is given in order r,theta,z). The resulting angle is interpreted in degrees.
dir=[0,1,2]) |
dir specifies which coordinates axes are parallel to respectively the cylindrical axes distance(r), angle(theta) and height(z). Default order is [x,y,z]. The angle value is given in degrees.
dir=[0,1,2],scale=[1.,1.,1.],colat=False) |
<dir> specifies which coordinates are interpreted as resp. longitude(theta), latitude(phi) and distance(r). <scale> will scale the coordinate values prior to the transformation. Angles are then interpreted in degrees. Latitude, i.e. the elevation angle, is measured from equator in direction of north pole(90). South pole is -90. If colat=True, the third coordinate is the colatitude (90-lat) instead.
n=1.0,e=1.0,k=0.0,dir=[0,1,2],scale=[1.,1.,1.],colat=False) |
superSpherical is much like spherical, but adds some extra parameters to enable the creation of virtually any surface.
Just like with spherical(), the input coordinates are interpreted as the longitude, latitude and distance in a spherical coordinate system. <dir> specifies which coordinates are interpreted as resp. longitude(theta), latitude(phi) and distance(r). Angles are then interpreted in degrees. Latitude, i.e. the elevation angle, is measured from equator in direction of north pole(90). South pole is -90. If colat=True, the third coordinate is the colatitude (90-lat) instead. <scale> will scale the coordinate values prior to the transformation.
The n and e parameters define exponential transformations of the north_south (latitude), resp. the east_west (longitude) coordinates. Default values of 1 result in a circle.
k adds 'eggness' to the shape: a difference between the northern and southern hemisphere. Values > 0 enlarge the southern hemishpere and shrink the northern.
dir=[0,1,2]) |
dir specifies which coordinates axes are parallel to respectively the spherical axes distance(r), longitude(theta) and latitude(phi). Latitude is the elevation angle measured from equator in direction of north pole(90). South pole is -90. Default order is [0,1,2], thus the equator plane is the (x,y)-plane. The returned angle values are given in degrees.
dir,a,func,dist) |
dir specifies the axis of the modified coordinates; a is the point that forces the bumping; dist specifies the direction in which the distance is measured; func is a function that calculates the bump intensity from distance !! func(0) should be different from 0.
dir,a,func) |
dir specifies the axis of the modified coordinates; a is the point that forces the bumping; func is a function that calculates the bump intensity from distance !! func(0) should be different from 0.
dir,a,func,dist=None) |
A bump is a modification of a set of coordinates by a non-matching point. It can produce various effects, but one of the most common uses is to force a surface to be indented by some point.
dir specifies the axis of the modified coordinates; a is the point that forces the bumping; func is a function that calculates the bump intensity from distance (!! func(0) should be different from 0) dist is the direction in which the distance is measured : this can be one of the axes, or a list of one or more axes. If only 1 axis is specified, the effect is like function bump1 If 2 axes are specified, the effect is like bump2 This function can take 3 axes however. Default value is the set of 3 axes minus the direction of modification. This function is then equivalent to bump2.
func) |
This is one of the versatile mapping functions. func is a numerical function which takes three arguments and produces a list of three output values. The coordinates [x,y,z] will be replaced by func(x,y,z). The function must be applicable to arrays, so it should only include numerical operations and functions understood by the numpy module. This method is one of several mapping methods. See also map1 and mapd. Example: E.map(lambda x,y,z: [2*x,3*y,4*z]) is equivalent with E.scale([2,3,4])
func) |
This is one of the versatile mapping functions. func is a numerical function which takes three arguments and produces a list of three output values. The coordinates [x,y,z] will be replaced by func(x,y,z). The function must be applicable to arrays, so it should only include numerical operations and functions understood by the numpy module. This method is one of several mapping methods. See also map1 and mapd. Example: E.map(lambda x,y,z: [2*x,3*y,4*z]) is equivalent with E.scale([2,3,4])
dir,func,x=None) |
<func> is a numerical function which takes one argument and produces one result. The coordinate dir will be replaced by func(coord[x]). If no x is specified, x is taken equal to dir. The function must be applicable on arrays, so it should only include numerical operations and functions understood by the numpy module. This method is one of several mapping methods. See also map and mapd.
dir,func,point,dist=None) |
<func> is a numerical function which takes one argument and produces one result. The coordinate dir will be replaced by func(d), where <d> is calculated as the distance to <point>. The function must be applicable on arrays, so it should only include numerical operations and functions understood by the numpy module. By default, the distance d is calculated in 3-D, but one can specify a limited set of axes to calculate a 2-D or 1-D distance. This method is one of several mapping methods. See also map3 and map1. Example: E.mapd(2,lambda d:sqrt(10**2-d**2),f.center(),[0,1]) maps E on a sphere with radius 10
k) |
i,j,other=None) |
i and j are lists of axis numbers or single axis numbers. replace ([0,1,2],[1,2,0]) will roll the axes by 1. replace ([0,1],[1,0]) will swap axes 0 and 1. An optionally third argument may specify another Coords object to take the coordinates from. It should have the same dimensions.
i,j) |
Beware! This is different from numpy's swapaxes() method !
n=1) |
Default is 1, thus axis 0 becomes the new 1 axis, 1 becomes 2 and 2 becomes 0.
radius=1.,center=[0.,0.,0.]) |
The default sphere is a unit sphere at the origin. The center of the sphere should not be part of the Coords.
radius=1.,dir=0,center=[0.,0.,0.]) |
The default cylinder has its axis along the x-axis and a unit radius. No points of the Coords should belong to the axis..
) |
The result is a sequence of arrays with shape self.shape[1:]. Raises an error if self.ndim < 2.
nodesperbox=1,shift=0.5,rtol=1.e-5,atol=1.e-5) |
This method finds the points that are very close and replaces them with a single point. The return value is a tuple of two arrays: - the unique points as a Coords object, - an integer (nnod) array holding an index in the unique coordinates array for each of the original nodes. This index will have the same shape as the pshape() of the coords array.
The procedure works by first dividing the 3D space in a number of equally sized boxes, with a mean population of nodesperbox. The boxes are numbered in the 3 directions and a unique integer scalar is computed, that is then used to sort the nodes. Then only nodes inside the same box are compared on almost equal coordinates, using the numpy allclose() function. Two coordinates are considered close if they are within a relative tolerance rtol or absolute tolerance atol. See numpy for detail. The default atol is set larger than in numpy, because pyformex typically runs with single precision. Close nodes are replaced by a single one.
Currently the procedure does not guarantee to find all close nodes: two close nodes might be in adjacent boxes. The performance hit for testing adjacent boxes is rather high, and the probability of separating two close nodes with the computed box limits is very small. Nevertheless we intend to access this problem by repeating the procedure with the boxes shifted in space.
cls,L) |
All Coords object in the list L should have the same shape except for the length of the first axis. This function is equivalent to the numpy concatenate, but makes sure the result is a Coords object.
This is a class method, not an instance method.
) |
This convenience function uses the numpy fromfile function to read the coordinates from file. You just have to make sure that the coordinates are read in order (X,Y,Z) for subsequent points, and that the total number of coordinates read is a multiple of 3.
This is a class method, not an instance method.
clas,F,G,div) |
F and G are two Coords with the same shape. v is a list of floating point values. The result is the concatenation of the interpolations of F and G at all the values in div. An interpolation of F and G at value v is a Coords H where each coordinate Hijk is obtained from: Hijk = Fijk + v * (Gijk-Fijk). Thus, a Coords interpolate(F,G,[0.,0.5,1.0]) will contain all points of F and G and all points with mean coordinates between those of F and G.
As a convenience, if an integer is specified for div, it is taken as a number of divisions for the interval [0..1]. Thus, interpolate(F,G,n) is equivalent with interpolate(F,G,arange(0,n+1)/float(n))
The resulting Coords array has an extra axis (the first). Its shape is (n,) + F.shape, where n is the number of divisions.
This is a class method, not an instance method.