Group

Qualified name: algan.mobs.group.Group

class Group(*mobs, link_children=True, **kwargs)[source]

Bases: Mob

Combine a collection of Mobs into a single Mob.

Specifically, creates an empty mob at the mid-point of the bounding box of the given mob collection and adds the mobs as children.

Parameters:
  • *mobs – The Mobs to group, as separate arguments or as one iterable – Group(a, b) and Group([a, b]) are the same call, and nested iterables are flattened. They must all belong to the same Scene.

  • link_children (bool) – Whether the Mobs become real children of the Group, so that they carry it as a parent and follow its transforms. Defaults to True. False makes an observational view: transforms still recurse over the members, but their parents are untouched, which is what group[1:3] returns.

  • **kwargs – Passed to Mob – notably scene, which must be the members’ own Scene, and name.

Raises:

TypeError – If a member is not an Animatable instance.

Examples

Arrange 3 mobs horizontally in a line, left to right.

Example: Example1Group

from algan import *

group = Group([Square() for _ in range(3)]).arrange_in_line(RIGHT).spawn()
group.rotate(90, OUT)

Scene.save_video()

Methods

add

Add Mobs to the Group.

arrange_between_points

Space the members evenly along the segment between two points.

arrange_in_grid

Lay the members out in a grid, filling row by row.

arrange_in_line

Lay the members out in a line.

get_parts_as_mobs

Get the Group's members as a list.

Attributes

animation_manager

This mob's scene-owned animation manager.

basis

The Mob's orientation and scale, as a flattened 3x3 matrix of shape (*, 9).

casts_shadows

Whether this Mob's geometry blocks light on its way from a light source to another surface -- whether it casts a shadow.

children

The Mobs attached below this one, in attachment order.

closed_shell

Whether this Mob's triangles form a CLOSED shell -- every camera ray that enters the geometry crosses a second time on its way out.

draws_descendants

Whether get_render_primitives returns geometry belonging to this Mob's DESCENDANTS as well as its own.

forward

Get the direction the Mob is facing.

lifespan

This mob's [spawn, despawn) interval on its Scene timeline (a Lifespan).

location

The Mob's position in world space, shape (*, 3).

normalized_basis

The Mob's orientation with scale divided out, shape (*, 9).

parents

The Mobs this one is attached to, in attachment order.

receives_shadows

Whether this Mob's surfaces are darkened by shadows cast onto them.

right

Get the Mob's own rightward direction.

scale_coefficient

The Mob's scale along its own right, up and forward axes, shape (*, 3).

two_sided

Whether this Mob's geometry should be lit from whichever side the ray arrives on.

up

Get the Mob's own upward direction.

x

The Mob's x coordinate in world units, shape (*, 1).

xy

The Mob's x and y coordinates in world units, shape (*, 2).

y

The Mob's y coordinate in world units, shape (*, 1).

z

The Mob's z coordinate in world units, shape (*, 1).

add(*mobs)[source]

Add Mobs to the Group.

The added Mobs become children, so the Group’s transforms carry them along, and the Group’s anchor moves to the middle of the enlarged collection. Re-adding an existing member does nothing.

Animation

Not animated: membership and the Group’s re-centering both happen instantly (the re-centering is done inside Off(), so it costs no video time and does not drag the existing members around).

Parameters:

*mobs – Mobs to add. Nested iterables are flattened, so group.add([a, b]) and group.add(a, b) are the same.

Returns:

This Group, so calls can be chained.

Return type:

Group

Raises:

.HierarchyError – If a Mob is added twice, belongs to another Scene, or the change would create a cycle.

arrange_between_points(start, end)[source]

Space the members evenly along the segment between two points.

Members are placed at equal fractions of the way from start to end, both endpoints excluded, so n members divide the segment into n + 1 equal steps. Sizes are ignored – it is the centers that are evenly spaced.

Animation

Recorded as an animation: every member moves at once inside a Sync, over the current context’s runtime (1 second by default).

Parameters:
  • start (Tensor) – Start of the segment, shape (*, 3).

  • end (Tensor) – End of the segment, shape (*, 3).

Returns:

This Group, so calls can be chained.

Return type:

Group

arrange_in_grid(num_rows=None, row_direction=tensor([1., 0., 0.]), column_direction=tensor([-0., -1., -0.]), row_buffer=None, column_buffer=None, tight_axis=None)[source]

Lay the members out in a grid, filling row by row.

Cells are sized to the largest member so the grid stays regular, and the whole grid is centered on the Group’s location. Members fill along row_direction first, wrapping to the next line along column_direction.

Animation

Recorded as an animation: every member moves at once inside a Sync, over the current context’s runtime (1 second by default). Call it before spawning to lay a Group out for free.

Parameters:
  • num_rows (int) – Number of rows; columns follow from the member count. Defaults to None, meaning ceil(sqrt(len(mobs))) – as square a grid as the count allows.

  • row_direction (Tensor) – Non-zero direction along which a row runs; its magnitude is ignored. Defaults to RIGHT.

  • column_direction (Tensor) – Non-zero direction in which successive rows are stacked; its magnitude is ignored. Defaults to DOWN.

  • row_buffer – Gap between members within a row, in world units. Defaults to None, meaning SETTINGS.style.buffer (0.6).

  • column_buffer – Gap between rows, in world units. Defaults to None, meaning use row_buffer.

  • tight_axis – Which axis sizes its cells per row/column rather than uniformly across the whole grid: 0 for columns, 1 for rows. Defaults to None, meaning every cell is the same size. Use it to close up the gaps when members vary a lot in size.

Returns:

This Group, so calls can be chained.

Return type:

Group

Raises:

.AlganConfigurationError – If num_rows is not a positive integer, a direction is zero or invalid, or tight_axis is not 0, 1 or None.

Examples

Arrange mobs in a 3x3 grid slanted at a 45 degrees angle.

Example: Example1ArrangeInGrid

from algan import *

group = Group([Square() for _ in range(9)]).scale(1/3).arrange_in_grid(3, RIGHT+UP, RIGHT+DOWN).spawn()
group.rotate(90, OUT)

Scene.save_video()
arrange_in_line(direction=tensor([1., 0., 0.]), buffer=None, start_at_first=False, equal_widths=False, align_to=None)[source]

Lay the members out in a line.

Members are placed edge to edge with buffer between them, so differently sized Mobs still end up evenly gapped rather than evenly centred.

Animation

Recorded as an animation: every member moves at once inside a Sync, over the current context’s runtime (1 second by default). Call it before spawning to lay a Group out for free.

Parameters:
  • direction (Tensor) – Non-zero direction the line runs in; its magnitude is ignored. Defaults to RIGHT.

  • buffer (float | None) – Gap between neighbouring members, in world units; 0 puts them edge to edge. Defaults to None, meaning SETTINGS.style.buffer (0.6).

  • start_at_first (bool) – Whether to keep the first member where it is and build the line out from it. Defaults to False, which centers the line on the Group’s location.

  • equal_widths (bool) – Whether to space members by a constant pitch (that of the largest member) rather than by their own sizes. Defaults to False. True gives evenly spaced centers, which is what you want for a row of labelled cells.

  • align_to (Tensor | None) – Direction along which to additionally align members, e.g. DOWN to sit them all on a shared baseline. Defaults to None, meaning no secondary alignment.

Returns:

This Group, so calls can be chained.

Return type:

Group

Raises:

.AlganConfigurationError – If direction or align_to is zero or not a finite 3-D vector.

See also

arrange_in_grid()

Lay members out in rows and columns.

arrange_between_points()

Space members evenly between two points.

get_parts_as_mobs()[source]

Get the Group’s members as a list.

Returns:

The members. Unlike get_parts_as_mobs(), the Group itself is not included – it carries no geometry of its own.

Return type:

list[Mob]