"""Helper variable or function for UI Elements."""
import numpy as np
from fury.decorators import warn_on_args_to_kwargs
TWO_PI = 2 * np.pi
[docs]
@warn_on_args_to_kwargs()
def clip_overflow(textblock, width, *, side="right"):
"""Clips overflowing text of TextBlock2D with respect to width.
Parameters
----------
textblock : TextBlock2D
The textblock object whose text needs to be clipped.
width : int
Required width of the clipped text.
side : str, optional
Clips the overflowing text according to side.
It takes values "left" or "right".
Returns
-------
clipped text : str
Clipped version of the text.
"""
original_str = textblock.message
prev_bg = textblock.have_bg
clip_idx = check_overflow(textblock, width, overflow_postfix="...", side=side)
if clip_idx == 0:
return original_str
textblock.have_bg = prev_bg
return textblock.message
[docs]
@warn_on_args_to_kwargs()
def wrap_overflow(textblock, wrap_width, *, side="right"):
"""Wraps overflowing text of TextBlock2D with respect to width.
Parameters
----------
textblock : TextBlock2D
The textblock object whose text needs to be wrapped.
wrap_width : int
Required width of the wrapped text.
side : str, optional
Clips the overflowing text according to side.
It takes values "left" or "right".
Returns
-------
wrapped text : str
Wrapped version of the text.
"""
original_str = textblock.message
str_copy = textblock.message
wrap_idxs = []
wrap_idx = check_overflow(textblock, wrap_width, overflow_postfix="", side=side)
if wrap_idx == 0:
return original_str
wrap_idxs.append(wrap_idx)
while wrap_idx != 0:
str_copy = str_copy[wrap_idx:]
textblock.message = str_copy
wrap_idx = check_overflow(textblock, wrap_width, overflow_postfix="", side=side)
if wrap_idx != 0:
wrap_idxs.append(wrap_idxs[-1] + wrap_idx + 1)
for idx in wrap_idxs:
original_str = original_str[:idx] + "\n" + original_str[idx:]
textblock.message = original_str
return textblock.message
[docs]
@warn_on_args_to_kwargs()
def check_overflow(textblock, width, *, overflow_postfix="", side="right"):
"""Checks if the text is overflowing.
Parameters
----------
textblock : TextBlock2D
The textblock object whose text is to be checked.
width: int
Required width of the text.
overflow_postfix: str, optional
Postfix to be added to the text if it is overflowing.
Returns
-------
mid_ptr: int
Overflow index of the text.
"""
side = side.lower()
if side not in ["left", "right"]:
raise ValueError("side can only take values 'left' or 'right'")
original_str = textblock.message
start_ptr = 0
mid_ptr = 0
end_ptr = len(original_str)
if side == "left":
original_str = original_str[::-1]
if textblock.cal_size_from_message()[0] <= width:
return 0
while start_ptr < end_ptr:
mid_ptr = (start_ptr + end_ptr) // 2
textblock.message = original_str[:mid_ptr] + overflow_postfix
if textblock.cal_size_from_message()[0] < width:
start_ptr = mid_ptr
elif textblock.cal_size_from_message()[0] > width:
end_ptr = mid_ptr
if (
mid_ptr == (start_ptr + end_ptr) // 2
or textblock.cal_size_from_message()[0] == width
):
if side == "left":
textblock.message = textblock.message[::-1]
return mid_ptr
[docs]
def cal_bounding_box_2d(vertices):
"""Calculate the min, max position and the size of the bounding box.
Parameters
----------
vertices : ndarray
vertices of the actors.
"""
if vertices.ndim != 2 or vertices.shape[1] not in [2, 3]:
raise IOError("vertices should be a 2D array with shape (n,2) or (n,3).")
if vertices.shape[1] == 3:
vertices = vertices[:, :-1]
min_x, min_y = vertices[0]
max_x, max_y = vertices[0]
for x, y in vertices:
if x < min_x:
min_x = x
if y < min_y:
min_y = y
if x > max_x:
max_x = x
if y > max_y:
max_y = y
bounding_box_min = np.asarray([min_x, min_y], dtype="int")
bounding_box_max = np.asarray([max_x, max_y], dtype="int")
bounding_box_size = np.asarray([max_x - min_x, max_y - min_y], dtype="int")
return bounding_box_min, bounding_box_max, bounding_box_size
[docs]
def rotate_2d(vertices, angle):
"""Rotate the given vertices by an angle.
Parameters
----------
vertices : ndarray
vertices of the actors.
angle: float
Value by which the vertices are rotated in radian.
"""
if vertices.ndim != 2 or vertices.shape[1] != 3:
raise IOError("vertices should be a 2D array with shape (n,3).")
rotation_matrix = np.array(
[
[np.cos(angle), np.sin(angle), 0],
[-np.sin(angle), np.cos(angle), 0],
[0, 0, 1],
]
)
new_vertices = np.matmul(vertices, rotation_matrix)
return new_vertices