10.16. shape#

The class shape represents 2D geometric elements with floating (or subpixel) precision. Any shape is given by a set of base points and an optional transformation matrix. The following shapes are currently defined:

  • Point

  • Line (a direct connection between two points)

  • Rectangle (an rectangle that is mainly defined by the top-left and bottom-right corner point)

  • Square (similar to a rectangle, however the side lengths are equal. It is defined by the center point and the side lengths)

  • Ellipse (an ellipse that is defined by the top-left and bottom-right corner of its outer rectangle)

  • Circle (similar to an ellipse, however the side lengths are equal. It is defined by the center point and the side lengths)

  • Polygon (polygon with n points)

Examples for the creation of shapes are:

point = shape(shape.Point, (0,0))
line = shape(shape.Line, (0,0), (100,50))
rect = shape(shape.Rectangle, (20,20), (70,100)) #top-left, bottom-right
square = shape(shape.Square, (30,-50), 20) #center, side-length
ellipse = shape(shape.Ellipse, (-50,-70), (-20, 0)) #top-left, bottom-right
circle = shape(shape.Circle, (-30, 100), 40) #center, side-length

If the optional transformation matrix (2x3 float64 matrix) is set, the shape can be translated and/or rotated. Please consider, that any rotation is currently not supported in any plot. Rectangles, squares, ellipses or circles are always defined, such that their main axes are parallel to the x- and y-axis. Use the rotation to choose another principal orientation. The base points of the shape are never affected by any transformation matrix. Only the contour points can be requested with the applied coordinate transformation (if desired).

It is possible to obtain a region from any shape with a valid area (points and lines don’t have an area). The region is always a pixel-precise structure. Regions can be combined using union or intersection operators.

Furthermore, a mask dataObject can be obtained from any dataObject using the method createMask() if one or multiple shapes are given.

The demo script demoShapes.py show further examples about the usage of shape objects.

class itom.shape(type=shape.Invalid, param1=None, param2=None, index=-1, name='')#

Bases: object

Creates a shape object of a specific type.

A shape object is used to describe a vectorized object, that can for instance be displayed in plots or might also be passed to different methods, e.g. in order to define a masked area etc. A shape object can also be converted into a region object, however the vector information is then projected onto a raster with a given resolution.

Depending on the type, the following arguments are allowed, where the first argument must be given to param1 and the 2nd one to param2:

  • shape.Invalid: -

  • shape.Point: point

  • shape.Line: start-point, end-point

  • shape.Rectangle: top left point, bottom right point

  • shape.Square: center point, side-length

  • shape.Ellipse: top left point, bottom right point of bounding box

  • shape.Circle: center point, radius

  • shape.Polygon: 2xM float64 array with M points of polygon

The parameters point, start-point, … can be all array-like types (e.g. dataObject, list, tuple, np.ndarray) that can be mapped to float64 and have two elements.

Another possibility to create a shape object for a certain type is to use one of the following static creation functions:

During construction, all shapes are aligned with respect to the x- and y-axis. Set a 2d transformation (attribute transform) to rotate and move it.

Parameters:
typeint

Type of the shape (see list above).

param1list of float or tuple of float or dataObject or numpy.ndarray, optional

1st initialization argument. This argument is depending on the type (see list above).

param2list of float or tuple of float or dataObject or numpy.ndarray, optional

2nd initialization argument. This argument is depending on the type (see list above).

indexint

index of the shape, or -1 if not further specified (default).

namestr

name of the shape, can for instance be displayed next to shapes in plots (depending on the parameterization of the plot).

contains(points) bool | dataObject#

Checks if one or multiple points are contained in this shape.

Tests if one or multiple points lie within the contour of the given shape. If the shape has an empty area (e.g. points, line…) the test will always return False.

Parameters:
pointssequence of float or dataObject or numpy.ndarray

The coordinates (x, y) of the point to be tested as sequence or an array-like object (shape 2 x N), where the first row contains the x-coordinates and the 2nd-row the y-coordinates of N points to be tested. The array-like object must be convertible to float64, which is internally done before testing.

Returns:
resultbool or dataObject

If one point is passed as sequence, True is returned if this point is within the contour of this shape, otherwise False. If points is given as array-like object, a 1 x N dataObject with dtype uint8 is returned, where the value 255 indicates, that the corresponding point is inside of the shape’s contour and 0 outside.

contour(applyTrafo=True, tol=-1.0) dataObject#

Returns the contour points of this shape as 2 x N, float64 dataObject.

For most shapes, the contour is exactly given by its corner points. However for circles or ellipses, the contour has to be approximated by line segments. Use the argument tol to set the maximum distance between each line segment and the real contour of the shape. If tol is set to -1.0, tol is assumed to be 1 % of the smallest diameter.

Shapes can have a transformation matrix (attribute transform). If applyTrafo is True, the returned contour points correspond to the transformed base shape, else the contour with respect to the base points is returned.

Parameters:
applyTrafobool

Define if the transformation matrix (default: unity matrix, attribute transform) should be considered for the returned contour points (True) or not (False).

tolfloat

Maximum tolerance to determine the approximated contour in the case of circular or elliptical shapes. The approximated contour consists of line segments, that can differ from the real contour by a maximum of tol. If -1.0, the tolerance is assumed to be one percent of the smallest diameter.

copy() shape#

Returns a deep copy of this shape.

Returns:
copyshape

deep copy of this shape.

static createCircle(center, radius, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Circle.

This static method is equal to the command:

myShape = shape(shape.Circle, center, radius, index, name)
myShape.flags = flags #optional
Parameters:
centersequence of float or dataObject or numpy.ndarray

(x,y) coordinate of the center point, given as any type that can be interpreted as array with two values

radiusfloat

radius of the circle

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createEllipse(corner1=None, corner2=None, center=None, size=None, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Ellipse.

Basically, there are two different ways to construct the ellipse: Either by the top left and bottom right corner points of the outer bounding box (corner1 and corner2), or by the center point (x,y) and the size, as array of (width, height).

Furthermore, you can indicate a size together with corner1 OR corner2, where corner1.x + width = corner2.x and corner1.y + height = corner2.y.

This static method is equal to the command:

myShape = shape(shape.Ellipse, corner1, corner2, index, name)
myShape.flags = flags #optional
Parameters:
corner1sequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the top, left corner point of the bounding box, given as any type that can be interpreted as array with two values

corner2sequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the bottom, right corner point of the bounding box, given as any type that can be interpreted as array with two values

centersequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the center point, given as any type that can be interpreted as array with two values

sizesequence of float or dataObject or numpy.ndarray, optional

(width, height) of the rectangle, given as any type that can be interpreted as array with two values

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createLine(point1, point2, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Line.

This static method is equal to the command:

myShape = shape(shape.Line, point1, point2, index, name)
myShape.flags = flags #optional
Parameters:
point1sequence of float or dataObject or numpy.ndarray

(x,y) coordinate of the first point, given as any type that can be interpreted as array with two values

point2sequence of float or dataObject or numpy.ndarray

(x,y) coordinate of the 2nd point, given as any type that can be interpreted as array with two values

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createPoint(point, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Point.

This static method is equal to the command:

myShape = shape(shape.Point, point, index, name)
myShape.flags = flags  # optional
Parameters:
pointsequence of float or dataObject or numpy.ndarray

(x,y) coordinate of the point, given as any type that can be interpreted as array with two float64 values.

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createPolygon(points, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Polygon.

This static method is equal to the command:

myShape = shape(shape.Polygon, points, index, name)
myShape.flags = flags #optional
Parameters:
pointssequence of sequence of float or dataObject or numpy.ndarray

An array-like object of shape 2 x M (with M > 2), that can be converted to float64. This object defines M points for the polygon (order: x, y). If a sequence is given, it must look like this:

points = ((1, 2, 3), (4, 5, 6))

where the first inner tuple defines the x-coordinates, and the 2nd tuple the y-coordinates.

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createRectangle(corner1=None, corner2=None, center=None, size=None, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Rectangle.

Basically, there are two different ways to construct a rectangle: Either by the top left and bottom right corner points (corner1 and corner2), or by the center point (x, y) and the size, as array of (width, height).

Furthermore, you can indicate a size together with corner1 OR corner2, where corner1.x + width = corner2.x and corner1.y + height = corner2.y.

This static method is equal to the command:

myShape = shape(shape.Rectangle, corner1, corner2, index, name)
myShape.flags = flags #optional
Parameters:
corner1sequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the top, left corner point, given as any type that can be interpreted as array with two values

corner2sequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the bottom, right corner point, given as any type that can be interpreted as array with two values

centersequence of float or dataObject or numpy.ndarray, optional

(x,y) coordinate of the center point, given as any type that can be interpreted as array with two values

sizesequence of float or dataObject or numpy.ndarray, optional

(width, height) of the rectangle, given as any type that can be interpreted as array with two values

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

static createSquare(center, sideLength, index=-1, name='', flags=0) shape#

Returns a new shape object of type shape.Square.

This static method is equal to the command:

myShape = shape(shape.Square, center, sideLength, index, name)
myShape.flags = flags #optional
Parameters:
centersequence of float or dataObject or numpy.ndarray

(x,y) coordinate of the center point, given as any type that can be interpreted as array with two values

sideLengthfloat

side length of the square

indexint, optional

index of this shape or -1 (default) if not further specified.

namestr, optional

optional name of this shape (default: “”). This name can for instance be displayed in a plot.

flagsint, optional

if the user should not be able to rotate, resize and / or move this shape in any plot canvas, then pass an or-combination of the restricitive flag values shape.ResizeLock, shape.RotateLock or shape.MoveLock.

Returns:
shape

The new shape object.

normalized() shape#

Returns the normalized version of this shape.

The normalized shape guarantees that the bounding box of the shape never has a non-negative width or height. Therefore, the order or position of the two corner points (base points) is switched or changed, if necessary. Shapes different than rectangles, squares, circles or ellipses are not affected by this such that the original shape object is returned as it is.

Returns:
normalizedshape

The normalized shape of this object (for types shape.Rectangle, shape.Square shape.Circle or shape.Ellipse) or this object (for all other types).

region() region#

Returns a region object from this shape.

The region object only contains valid regions if the shape has an area > 0. A region object is an integer based object (pixel raster), therefore the shapes are rounded to the nearest fixed-point coordinate.

Returns:
region

The region, whose contour approximates this shape. The inner of this shaped is part of the region.

rotateDeg(angle)#

Rotate shape by given angle in degrees around the center point of this shape (counterclockwise). This method only affects the transform matrix, not the base points themselves.

Parameters:
anglefloat

is the rotation angle (in radians) by which the shape is rotated by its center.

See also

translate, rotateRad
rotateRad(angle)#

Rotate shape by given angle in radians around the center point of this shape (counterclockwise). This method only affects the transform matrix, not the base points themselves.

Parameters:
anglefloat

is the rotation angle (in radians) by which the shape is rotated by its center.

See also

translate, rotateDeg
translate(dxy)#

Translate shape by given (dx, dy) value.

Moves the shape by dx and dy along the x- and y-axis of the base coordinate system. This means, that dx and dy are added to the existing tx and ty values of the current transformation matrix.

Parameters:
dxysequence of float or dataObject or numpy.ndarray

array-like object with two elements, that define the desired dx and dy component.

See also

rotateRad, rotateDeg
angleDeg#

float : Gets or sets the current angle of rotation of the transformation matrix in degree.

A rotation is always defined counter-clockwise.

angleRad#

float : Gets or sets the current angle of rotation of the transformation matrix in Radians.

A rotation is always defined counter-clockwise.

area#

float : Get area of this shape

Shapes of type shape.Line and shape.Point will always return 0.0.

basePoints#

dataObject : base points of this shape, given as 2 x M, float64 dataObject.

The M base points are untransformed points that describe the shape dependent on its type:

  • shape.Point: one point

  • shape.Line : start point, end point

  • shape.Rectangle, shape.Square : top left point, bottom right point

  • shape.Ellipse, shape.Circle : top left point, bottom right point of bounding box

  • shape.Polygon : points of polygon, the last and first point are connected, too.

center#

tuple of float : Gets or sets the center point of this shape.

The center point is defined for all types of shapes, beside shape.Polygon. Changing the center point will directly influence the base points of the shape.

If the value is set, it is also possible to pass any other array-like object with two values that can be converted to float64.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no center defined.

color#

None or rgba : Gets or sets color of this shape.

The default color is an invalid color, given by the None value. The color of shapes is for instance be used for visualization purposes in plots.

flags#

int : Gets or sets a flag (bitmask) that define denied manipulation of this shape.

It is possible to deny the following manipulations:

  • shape.MoveLock

  • `` shape.RotateLock``

  • `` shape.ResizeLock``

height#

float : Gets or sets the height of this shape.

A height can only be set or read for shapes of type shape.Square and shape.Rectangle.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no height defined.

index#

int : Gets or sets the index of this shape.

The default is -1, however if the shape is a geometric shape of a plot, an auto-incremented index is assigned once the shape is drawn or set. If >= 0 it is possible to modify an existing shape with the same index.

name#

str : Gets or sets the name (label) of this shape.

point1#

tuple of float : Gets or sets the 1st point of the bounding box of this shape.

The first point is the first point of a shape.Point or shape.Line or the upper left point of the bounding box of a shape.Rectangle, shape.Square shape.Ellipse or shape.Circle. The point always considers a possible 2D coordinate transformation matrix.

For setting this value, it is also possible to pass any other array-like object with two elements, that can be converted to float64.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no 2nd point defined.

point2#

tuple of float : Gets or sets the second point of the bounding box of this shape.

The second point is the 2nd point of a shape.Line or the bottom right point of the bounding box (types: shape.Rectangle, shape.Square, shape.Ellipse or shape.Circle). The point always considers a possible 2D coordinate transformation matrix.

For setting this value, it is also possible to pass any other array-like object with two elements, that can be converted to float64.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no 2nd point defined.

radius#

float or tuple of float : Gets or sets the radius of this shape.

A radius can only be set for shapes of type shape.Circle or shape.Ellipse. For a circle, the radius is a scalar float value. For an ellipse, a tuple of two values (a, b) define the half side-length in x- and y-direction of the base coordinate system.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no radius defined.

transform#

dataObject : gets or sets the affine, non scaled 2D transformation matrix as dataObject.

The returned matrix is a 2 x 3, float64 dataObject, where the left 2 x 2 matrix describes a rotation matrix, and the right 2 x 1 part is the translation vector.

type#

int : Get the type of this shape.

Possible types are:

  • shape.Line

  • shape.Point

  • shape.Rectangle

  • shape.Ellipse

  • shape.Circle

  • shape.Square

valid#

bool : Returns True if this shape is valid, otherwise False.

An invalid shape is the one constructed with the type shape.Invalid. All other shapes are valid.

width#

float : Gets or sets the width of this shape.

A width can only be set or read for shapes of type shape.Square and shape.Rectangle.

Raises:
TypeError

if this attribute is read or assigned for a type, that has no width defined.