Skip to content

Region

FluxRender.regions

CircularRegion

CircularRegion(center: Sequence[float], radius: float, world_fixed: bool = False, visible: bool = False, color_active: Sequence[float] = (1, 1, 1, 0.3), color_inactive: Sequence[float] = (0, 0.1, 0.2, 0.3))

Bases: SpatialRegion

A static, circular spatial boundary used for spatial queries and interactions.

The CircularRegion defines a precise area within the simulation. It is primarily utilized as a localized spawning zone for ParticleSystems (acting as an emitter) or as a targeted sampling area for DataProbes.

Its most powerful feature is its dual-coordinate nature: it can either be rigidly anchored to the UI screen space (pixels) or embedded directly into the mathematical world space, scaling and panning seamlessly with the camera.

Parameters:

Name Type Description Default
center Sequence[float]

The (x, y) coordinates of the region's center. Units depend strictly on the world_fixed flag.

required
radius float

The radius of the circle. Units depend strictly on the world_fixed flag.

required
world_fixed bool

The coordinate system toggle.

  • False (Default): center and radius are evaluated in screen pixels. The region stays fixed on the screen regardless of camera movement.
  • True: center and radius are evaluated in mathematical world units. The region acts as a physical area in the mathematical space.
False
visible bool

Whether to render region on screen (useful for debugging).

False
color_active Sequence[float]

RGBA color sequence when Region.active is True.

(1, 1, 1, 0.3)
color_inactive Sequence[float]

RGBA color sequence when Region.active is False.

(0, 0.1, 0.2, 0.3)
Notes
  • units: The world_fixed flag is crucial for determining how the center and radius parameters are interpreted. When world_fixed is False, they are in screen pixels; when True, they are in world units.
Example

Creating a screen-fixed UI Particle emitter:

import FluxRender as fr

# [Initialize scene and math engine here]

# A fixed 50px radius circle in the bottom-left corner of the screen UI
ui_emitter = fr.CircularRegion(center=(100.0, 100.0), radius=50.0, world_fixed=False)

particle_system = fr.ParticleSystem(
    vec_function = lambda x, y: (0.0, 1.0),  # Example vector function that emits particles upwards
    emitter=ui_emitter
)

Creating a visible, world-fixed Particle emitter:

import FluxRender as fr

# [Initialize scene and math engine here]

# A visible circular region centered at (1, 1) with a radius of 0.25 world unit
world_emitter = fr.CircularRegion(center=(1.0, 1.0), radius=0.25, world_fixed=True, visible=True)

particle_system = fr.ParticleSystem(
    vec_function = lambda x, y: (y, -x),  # Example vector function that emits particles in a circular pattern
    emitter=world_emitter
)

Source code in FluxRender/regions.py
def __init__(self,
             center: Sequence[float],
             radius: float,
             world_fixed: bool = False,
             visible: bool = False,
             color_active: Sequence[float] = (1, 1, 1, 0.3),
             color_inactive: Sequence[float] = (0, 0.1, 0.2, 0.3),
             ):
    """
    Args:
        center (Sequence[float]): The (x, y) coordinates of the region's center.
            Units depend strictly on the `world_fixed` flag.
        radius (float): The radius of the circle. Units depend strictly on the `world_fixed` flag.
        world_fixed (bool, optional): The coordinate system toggle.

            * **False** (Default): `center` and `radius` are evaluated in screen pixels. The region stays fixed on the screen regardless of camera movement.
            * **True**: `center` and `radius` are evaluated in mathematical world units. The region acts as a physical area in the mathematical space.
        visible (bool, optional): Whether to render region on screen (useful for debugging).
        color_active (Sequence[float], optional): RGBA color sequence when Region.active is True.
        color_inactive (Sequence[float], optional): RGBA color sequence when Region.active is False.

    Notes:
        * **units**: The `world_fixed` flag is crucial for determining how the `center` and `radius` parameters are interpreted. When `world_fixed` is False, they are in screen pixels; when True, they are in world units.

    Example:
        Creating a screen-fixed UI Particle emitter:
        ```python
        import FluxRender as fr

        # [Initialize scene and math engine here]

        # A fixed 50px radius circle in the bottom-left corner of the screen UI
        ui_emitter = fr.CircularRegion(center=(100.0, 100.0), radius=50.0, world_fixed=False)

        particle_system = fr.ParticleSystem(
            vec_function = lambda x, y: (0.0, 1.0),  # Example vector function that emits particles upwards
            emitter=ui_emitter
        )

        ```

        Creating a visible, world-fixed Particle emitter:
        ```python
        import FluxRender as fr

        # [Initialize scene and math engine here]

        # A visible circular region centered at (1, 1) with a radius of 0.25 world unit
        world_emitter = fr.CircularRegion(center=(1.0, 1.0), radius=0.25, world_fixed=True, visible=True)

        particle_system = fr.ParticleSystem(
            vec_function = lambda x, y: (y, -x),  # Example vector function that emits particles in a circular pattern
            emitter=world_emitter
        )

        ```
    """

    super().__init__()
    self.center = center
    self.radius = radius

    self.world_fixed = world_fixed
    self.visible = visible

    self.color_active = tuple(color_active)
    self.color_inactive = tuple(color_inactive)

contains

contains(point: tuple)

Checks whether a given spatial point falls within the circular region. The point should be in the same coordinate space as the region (screen or world) based on the world_fixed flag.

Parameters:

Name Type Description Default
point tuple

A tuple representing the (x, y) coordinates of the point to check. The coordinate space of the point must match the region's coordinate space as determined by the world_fixed flag.

required

Returns:

Name Type Description
contains bool

True if the point is within the circular region, False otherwise.

Source code in FluxRender/regions.py
def contains(self, point: tuple):
    """
    Checks whether a given spatial point falls within the circular region.
    The point should be in the same coordinate space as the region (screen or world) based on the `world_fixed` flag.

    Args:
        point (tuple): A tuple representing the (x, y) coordinates of the point to check. The coordinate space of the point must match the region's coordinate space as determined by the `world_fixed` flag.

    Returns:
        contains (bool): True if the point is within the circular region, False otherwise.
    """

    dx = point[0] - self.center[0]
    dy = point[1] - self.center[1]
    return dx * dx + dy * dy <= self.radius ** 2

get_center

get_center()

Returns the current center coordinates of the circular region in math coordinates, regardless of the world_fixed setting.

Returns:

Name Type Description
center Tuple[float, float]

The (x, y) coordinates of the region's center in math coordinates.

Source code in FluxRender/regions.py
def get_center(self):
    """
    Returns the current center coordinates of the circular region in math coordinates, regardless of the `world_fixed` setting.

    Returns:
        center (Tuple[float, float]): The (x, y) coordinates of the region's center in math coordinates.
    """

    if not self.world_fixed:
        return self.scene.coords.to_math(*self.center)

    return self.center

random_point_screen

random_point_screen()

Generates a single random point uniformly distributed within the circular region. The generated point is returned in screen coordinates, regardless of the region's world_fixed setting.

Returns:

Name Type Description
point Tuple[float, float]

The (x, y) coordinates of the generated point in screen coordinates.

Source code in FluxRender/regions.py
def random_point_screen(self):
    """
    Generates a single random point uniformly distributed within the circular region.
    The generated point is returned in screen coordinates, regardless of the region's `world_fixed` setting.

    Returns:
        point (Tuple[float, float]): The (x, y) coordinates of the generated point in screen coordinates.
    """

    radius = np.sqrt(np.random.uniform(0, self.radius ** 2))
    angle = np.random.uniform(0, 2 * np.pi)

    x = self.center[0] + radius * np.cos(angle)
    y = self.center[1] + radius * np.sin(angle)

    if self.world_fixed and self.scene is not None:
        # Convert from world to screen coordinates
        x, y = self.scene.coords.to_screen(x, y)

    return x, y

random_points_screen

random_points_screen(count: int)

Generates a specified number of random points uniformly distributed within the circular region. The generated points are returned in screen coordinates, regardless of the region's world_fixed setting. Args: count (int): The number of random points to generate.

Returns:

Name Type Description
points Tuple of two numpy arrays

(x_coordinates, y_coordinates) of the generated points in screen coordinates.

Source code in FluxRender/regions.py
def random_points_screen(self, count: int):
    """
    Generates a specified number of random points uniformly distributed within the circular region.
    The generated points are returned in screen coordinates, regardless of the region's `world_fixed` setting.
    Args:
        count (int): The number of random points to generate.

    Returns:
        points (Tuple of two numpy arrays): (x_coordinates, y_coordinates) of the generated points in screen coordinates.
    """


    points = np.zeros((count, 2), dtype=np.float32)

    random_radius = np.sqrt(np.random.uniform(0, self.radius ** 2, count))
    random_angle = np.random.uniform(0, 2 * np.pi, count)

    points[:, 0] = self.center[0] + random_radius * np.cos(random_angle)
    points[:, 1] = self.center[1] + random_radius * np.sin(random_angle)

    if self.world_fixed and self.scene is not None:
        # Convert from world to screen coordinates
        points[:, 0], points[:, 1] = self.scene.coords.to_screen(points[:, 0], points[:, 1])

    return points[:, 0], points[:, 1]

CursorRegion

CursorRegion(radius: float = 50.0, visible: bool = False, color_active=(1, 1, 1, 0.3), color_inactive=(0, 0.1, 0.2, 0.3), always_active: bool = False)

Bases: SpatialRegion

A dynamic spatial region permanently attached to the user's mouse cursor.

The CursorRegion serves as the primary interactive bridge between the user and the mathematical simulation. By translating raw screen-space mouse coordinates into actionable world-space queries in real-time, it allows users to directly "paint" particles onto the screen (as an emitter) or dynamically sample local vector properties simply by hovering over them (as a DataProbe carrier).

Parameters:

Name Type Description Default
radius float

The interaction radius around the cursor, defined in screen pixels.

50.0
visible bool

Whether to render a visual halo around the mouse cursor.

False
color_active Sequence[float]

RGBA color of the halo when the region is actively triggered (e.g., mouse button held down).

(1, 1, 1, 0.3)
color_inactive Sequence[float]

RGBA color of the halo when the cursor is merely hovering.

(0, 0.1, 0.2, 0.3)
always_active bool

Behavioral toggle.

  • False (Default): The region only emits/probes when the user clicks and holds the mouse button.
  • True: The region constantly emits/probes data on every frame, regardless of mouse clicks.
False
Example

Setting up an interactive, visible cursor emitter:

import FluxRender as fr

# [Initialize scene and coordinate system here]

# Creates a 30px visible halo around the mouse. Particles will only spawn when the user clicks and drags the mouse across the field.
interactive_cursor = fr.CursorRegion(
    radius=30.0,
    visible=True,
)

particle_system = fr.ParticleSystem(
    vec_function = lambda x, y: (y, -x),  # Example vector function that emits particles in a circular pattern
    emitter=interactive_cursor
)

Setting up a constantly active cursor probe:

import FluxRender as fr

# [Initialize scene and coordinate system here]

math_engine = fr.VectorMathEngine(primary_vector_function=lambda x, y: (y, -x))

# A CursorRegion that continuously probes the vector field under the mouse cursor, even without clicks.
probing_cursor = fr.CursorRegion(
    radius=20.0,
    visible=False,
    always_active=True
)

probe = fr.DataProbe(
    target_region=probing_cursor,
    target_entity=math_engine,
    measured_property=fr.Property.VELOCITY
)
probe.add_listener(lambda value: print(f"Current velocity at cursor: {value}", end="\r"))

Source code in FluxRender/regions.py
def __init__(self,
             radius: float = 50.0,
             visible: bool = False,
             color_active=(1, 1, 1, 0.3), color_inactive=(0, 0.1, 0.2, 0.3),
             always_active: bool = False
             ):
    """
    Args:
        radius (float, optional): The interaction radius around the cursor, defined in screen pixels.
        visible (bool, optional): Whether to render a visual halo around the mouse cursor.
        color_active (Sequence[float], optional): RGBA color of the halo when the region is actively triggered (e.g., mouse button held down).
        color_inactive (Sequence[float], optional): RGBA color of the halo when the cursor is merely hovering.
        always_active (bool, optional): Behavioral toggle.

            * **False** (Default): The region only emits/probes when the user clicks and holds the mouse button.
            * **True**: The region constantly emits/probes data on every frame, regardless of mouse clicks.

    Example:
        Setting up an interactive, visible cursor emitter:
        ```python
        import FluxRender as fr

        # [Initialize scene and coordinate system here]

        # Creates a 30px visible halo around the mouse. Particles will only spawn when the user clicks and drags the mouse across the field.
        interactive_cursor = fr.CursorRegion(
            radius=30.0,
            visible=True,
        )

        particle_system = fr.ParticleSystem(
            vec_function = lambda x, y: (y, -x),  # Example vector function that emits particles in a circular pattern
            emitter=interactive_cursor
        )

        ```

        Setting up a constantly active cursor probe:
        ```python
        import FluxRender as fr

        # [Initialize scene and coordinate system here]

        math_engine = fr.VectorMathEngine(primary_vector_function=lambda x, y: (y, -x))

        # A CursorRegion that continuously probes the vector field under the mouse cursor, even without clicks.
        probing_cursor = fr.CursorRegion(
            radius=20.0,
            visible=False,
            always_active=True
        )

        probe = fr.DataProbe(
            target_region=probing_cursor,
            target_entity=math_engine,
            measured_property=fr.Property.VELOCITY
        )
        probe.add_listener(lambda value: print(f"Current velocity at cursor: {value}", end="\\r"))

        ```

    """

    super().__init__()
    self.scene = None
    self.radius = radius
    self.color_active = color_active
    self.color_inactive = color_inactive
    self.visible = visible
    self.always_active = always_active

contains

contains(point: tuple)

Checks whether a given spatial point falls within the cursor region. The point should be in the screen coordinate space (pixels).

Parameters:

Name Type Description Default
point tuple

A tuple representing the (x, y) coordinates of the point to check in screen space.

required

Returns:

Name Type Description
contains bool

True if the point is within the cursor region, False otherwise.

Source code in FluxRender/regions.py
def contains(self, point: tuple):
    """
    Checks whether a given spatial point falls within the cursor region.
    The point should be in the screen coordinate space (pixels).

    Args:
        point (tuple): A tuple representing the (x, y) coordinates of the point to check in screen space.

    Returns:
        contains (bool): True if the point is within the cursor region, False otherwise.
    """

    cursor_x, cursor_y = self.scene.mouse_pos
    dx = point[0] - cursor_x
    dy = point[1] - cursor_y
    return dx * dx + dy * dy <= self.radius ** 2

get_center

get_center()

Returns the current center coordinates of the cursor region in math coordinates.

Returns:

Name Type Description
center Tuple[float, float]

The (x, y) coordinates of the region's center in math coordinates.

Source code in FluxRender/regions.py
def get_center(self):
    """
    Returns the current center coordinates of the cursor region in math coordinates.

    Returns:
        center (Tuple[float, float]): The (x, y) coordinates of the region's center in math coordinates.
    """

    if self.scene is not None:
        return self.scene.coords.to_math(*self.scene.mouse_pos)
    else:
        return (0, 0)

random_point_screen

random_point_screen()

Generates a single random point uniformly distributed within the cursor region. The generated point is returned in screen coordinates.

Returns:

Name Type Description
point Tuple[float, float]

The (x, y) coordinates of the generated point in screen coordinates.

Source code in FluxRender/regions.py
def random_point_screen(self):
    """
    Generates a single random point uniformly distributed within the cursor region.
    The generated point is returned in screen coordinates.

    Returns:
        point (Tuple[float, float]): The (x, y) coordinates of the generated point in screen coordinates.
    """

    cursor_x, cursor_y = self.scene.mouse_pos

    radius = np.sqrt(np.random.uniform(0, self.radius ** 2))
    angle = np.random.uniform(0, 2 * np.pi)

    x = cursor_x + radius * np.cos(angle)
    y = cursor_y + radius * np.sin(angle)

    return x, y

random_points_screen

random_points_screen(count: int)

Generates a specified number of random points uniformly distributed within the cursor region. The generated points are returned in screen coordinates. Args: count (int): The number of random points to generate.

Returns:

Name Type Description
points Tuple of two numpy arrays

(x_coordinates, y_coordinates) of the generated points in screen coordinates.

Source code in FluxRender/regions.py
def random_points_screen(self, count: int):
    """
    Generates a specified number of random points uniformly distributed within the cursor region.
    The generated points are returned in screen coordinates.
    Args:
        count (int): The number of random points to generate.

    Returns:
        points (Tuple of two numpy arrays): (x_coordinates, y_coordinates) of the generated points in screen coordinates.
    """

    cursor_x, cursor_y = self.scene.mouse_pos

    random_radius = np.sqrt(np.random.uniform(0.0, self.radius ** 2, count))
    random_angle = np.random.uniform(0.0, 2.0 * np.pi, count)

    generated_points_x = cursor_x + random_radius * np.cos(random_angle)
    generated_points_y = cursor_y + random_radius * np.sin(random_angle)

    return generated_points_x, generated_points_y