or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animations.mdcameras.mdcoordinate-systems.mdindex.mdmobjects.mdrendering.mdscenes.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

Essential utility functions including mathematical operations, color management, rate functions, file operations, and debugging tools for animation development. These utilities provide the foundational support functions that enable smooth animation development and mathematical precision.

3

4

## Capabilities

5

6

### Constants and Directions

7

8

Fundamental mathematical and spatial constants used throughout Manim for positioning, animation, and mathematical calculations.

9

10

```python { .api }

11

# Coordinate system constants

12

ORIGIN: np.ndarray # [0, 0, 0] - Center of coordinate system

13

14

# Direction vectors (unit vectors)

15

UP: np.ndarray # [0, 1, 0] - Positive y direction

16

DOWN: np.ndarray # [0, -1, 0] - Negative y direction

17

LEFT: np.ndarray # [-1, 0, 0] - Negative x direction

18

RIGHT: np.ndarray # [1, 0, 0] - Positive x direction

19

IN: np.ndarray # [0, 0, -1] - Negative z direction (into screen)

20

OUT: np.ndarray # [0, 0, 1] - Positive z direction (out of screen)

21

22

# Coordinate axes

23

X_AXIS: np.ndarray # [1, 0, 0] - X-axis unit vector

24

Y_AXIS: np.ndarray # [0, 1, 0] - Y-axis unit vector

25

Z_AXIS: np.ndarray # [0, 0, 1] - Z-axis unit vector

26

27

# Diagonal directions (combinations)

28

UL: np.ndarray # UP + LEFT - Upper left diagonal

29

UR: np.ndarray # UP + RIGHT - Upper right diagonal

30

DL: np.ndarray # DOWN + LEFT - Lower left diagonal

31

DR: np.ndarray # DOWN + RIGHT - Lower right diagonal

32

33

# Mathematical constants

34

PI: float # π (pi) ≈ 3.14159

35

TAU: float # 2π (tau) ≈ 6.28318 - full circle

36

DEGREES: float # π/180 - conversion factor from degrees to radians

37

38

# Size and spacing constants

39

DEFAULT_DOT_RADIUS: float = 0.08

40

DEFAULT_SMALL_DOT_RADIUS: float = 0.04

41

DEFAULT_DASH_LENGTH: float = 0.05

42

DEFAULT_ARROW_TIP_LENGTH: float = 0.35

43

DEFAULT_STROKE_WIDTH: float = 4

44

DEFAULT_FONT_SIZE: float = 48

45

46

# Buffer distances for spacing

47

SMALL_BUFF: float = 0.1 # Small buffer distance

48

MED_SMALL_BUFF: float = 0.25 # Medium-small buffer

49

MED_LARGE_BUFF: float = 0.5 # Medium-large buffer

50

LARGE_BUFF: float = 1.0 # Large buffer distance

51

52

# Default positioning buffers

53

DEFAULT_MOBJECT_TO_EDGE_BUFFER: float = 0.5

54

DEFAULT_MOBJECT_TO_MOBJECT_BUFFER: float = 0.25

55

56

# Animation timing constants

57

DEFAULT_POINTWISE_FUNCTION_RUN_TIME: float = 3.0

58

DEFAULT_WAIT_TIME: float = 1.0

59

60

# Quality settings density

61

DEFAULT_POINT_DENSITY_2D: float = 25

62

DEFAULT_POINT_DENSITY_1D: float = 250

63

64

# Font and text scaling

65

SCALE_FACTOR_PER_FONT_POINT: float = 0.001

66

67

# Rendering quality constants

68

QUALITIES: dict = {

69

"fourk_quality": "4k quality rendering",

70

"production_quality": "Production quality rendering",

71

"high_quality": "High quality rendering",

72

"medium_quality": "Medium quality rendering",

73

"low_quality": "Low quality rendering",

74

"example_quality": "Example quality rendering"

75

}

76

DEFAULT_QUALITY: str = "high_quality"

77

78

# Renderer configuration

79

class RendererType:

80

"""Enumeration of available renderer types."""

81

CAIRO: str = "cairo" # Cairo 2D renderer

82

OPENGL: str = "opengl" # OpenGL 3D renderer

83

84

# Line styling enums

85

class LineJointType:

86

"""Enumeration of line joint types for stroke rendering."""

87

AUTO: int = 0 # Automatic joint type selection

88

ROUND: int = 1 # Rounded line joints

89

BEVEL: int = 2 # Beveled line joints

90

MITER: int = 3 # Mitered line joints

91

92

class CapStyleType:

93

"""Enumeration of line cap styles for stroke ends."""

94

AUTO: int = 0 # Automatic cap style selection

95

ROUND: int = 1 # Rounded line caps

96

BUTT: int = 2 # Flat butt line caps

97

SQUARE: int = 3 # Square line caps

98

99

# Font weight constants

100

THIN: int = 100

101

ULTRALIGHT: int = 200

102

LIGHT: int = 300

103

SEMILIGHT: int = 350

104

BOOK: int = 380

105

NORMAL: int = 400

106

MEDIUM: int = 500

107

SEMIBOLD: int = 600

108

BOLD: int = 700

109

ULTRABOLD: int = 800

110

HEAVY: int = 900

111

ULTRAHEAVY: int = 1000

112

113

# Font style constants

114

ITALIC: str = "italic"

115

OBLIQUE: str = "oblique"

116

117

# Interface constants

118

SHIFT_VALUE: int = 65505 # Keyboard shift key value

119

CTRL_VALUE: int = 65507 # Keyboard control key value

120

START_X: int = 30 # Default window x position

121

START_Y: int = 20 # Default window y position

122

```

123

124

### Rate Functions

125

126

Mathematical functions that control animation timing and easing for natural, expressive motion curves.

127

128

```python { .api }

129

# Basic rate functions

130

def linear(t: float) -> float:

131

"""

132

Linear interpolation - constant speed throughout animation.

133

134

Parameters:

135

- t: Time parameter [0, 1]

136

137

Returns:

138

- float: Linear progress [0, 1]

139

"""

140

141

def smooth(t: float) -> float:

142

"""

143

Smooth S-curve interpolation using smoothstep function.

144

145

Provides smooth acceleration and deceleration with no sudden changes

146

in velocity at start or end.

147

148

Parameters:

149

- t: Time parameter [0, 1]

150

151

Returns:

152

- float: Smooth progress [0, 1]

153

"""

154

155

def rush_into(t: float) -> float:

156

"""

157

Start slow, then rapidly accelerate toward end.

158

159

Parameters:

160

- t: Time parameter [0, 1]

161

162

Returns:

163

- float: Rush-in progress [0, 1]

164

"""

165

166

def rush_from(t: float) -> float:

167

"""

168

Start fast, then decelerate toward end.

169

170

Parameters:

171

- t: Time parameter [0, 1]

172

173

Returns:

174

- float: Rush-from progress [0, 1]

175

"""

176

177

def slow_into(t: float) -> float:

178

"""

179

Gradually accelerate throughout animation.

180

181

Parameters:

182

- t: Time parameter [0, 1]

183

184

Returns:

185

- float: Slow-into progress [0, 1]

186

"""

187

188

def double_smooth(t: float) -> float:

189

"""

190

Extra smooth S-curve with more gradual acceleration/deceleration.

191

192

Parameters:

193

- t: Time parameter [0, 1]

194

195

Returns:

196

- float: Double-smooth progress [0, 1]

197

"""

198

199

def there_and_back(t: float) -> float:

200

"""

201

Go from 0 to 1 and back to 0 during animation.

202

203

Creates a motion that reaches the target at the midpoint

204

then returns to the starting position.

205

206

Parameters:

207

- t: Time parameter [0, 1]

208

209

Returns:

210

- float: There-and-back progress [0, 1, 0]

211

"""

212

213

def there_and_back_with_pause(

214

t: float,

215

pause_ratio: float = 1/3

216

) -> float:

217

"""

218

Go to target, pause, then return with customizable pause duration.

219

220

Parameters:

221

- t: Time parameter [0, 1]

222

- pause_ratio: Fraction of time to pause at target

223

224

Returns:

225

- float: Progress with pause [0, 1, pause, 0]

226

"""

227

228

def running_start(

229

t: float,

230

pull_factor: float = -0.5

231

) -> float:

232

"""

233

Start by moving backward, then accelerate forward.

234

235

Creates anticipation by initially moving in opposite direction

236

before accelerating toward target.

237

238

Parameters:

239

- t: Time parameter [0, 1]

240

- pull_factor: How far backward to go initially

241

242

Returns:

243

- float: Running start progress

244

"""

245

246

def wiggle(t: float, wiggles: float = 2) -> float:

247

"""

248

Oscillating motion that settles at target.

249

250

Parameters:

251

- t: Time parameter [0, 1]

252

- wiggles: Number of oscillations

253

254

Returns:

255

- float: Wiggling progress [0, 1]

256

"""

257

258

def exponential_decay(t: float) -> float:

259

"""

260

Exponentially approach target value.

261

262

Parameters:

263

- t: Time parameter [0, 1]

264

265

Returns:

266

- float: Exponential progress [0, 1)

267

"""

268

269

# Standard easing functions (CSS/web animation style)

270

# Sine easing

271

def ease_in_sine(t: float) -> float:

272

"""Sine-based ease-in curve."""

273

274

def ease_out_sine(t: float) -> float:

275

"""Sine-based ease-out curve."""

276

277

def ease_in_out_sine(t: float) -> float:

278

"""Sine-based ease-in-out curve."""

279

280

# Quadratic easing

281

def ease_in_quad(t: float) -> float:

282

"""Quadratic ease-in curve (t²)."""

283

284

def ease_out_quad(t: float) -> float:

285

"""Quadratic ease-out curve."""

286

287

def ease_in_out_quad(t: float) -> float:

288

"""Quadratic ease-in-out curve."""

289

290

# Cubic easing

291

def ease_in_cubic(t: float) -> float:

292

"""Cubic ease-in curve (t³)."""

293

294

def ease_out_cubic(t: float) -> float:

295

"""Cubic ease-out curve."""

296

297

def ease_in_out_cubic(t: float) -> float:

298

"""Cubic ease-in-out curve."""

299

300

# Quartic easing

301

def ease_in_quart(t: float) -> float:

302

"""Quartic ease-in curve (t⁴)."""

303

304

def ease_out_quart(t: float) -> float:

305

"""Quartic ease-out curve."""

306

307

def ease_in_out_quart(t: float) -> float:

308

"""Quartic ease-in-out curve."""

309

310

# Exponential easing

311

def ease_in_expo(t: float) -> float:

312

"""Exponential ease-in curve."""

313

314

def ease_out_expo(t: float) -> float:

315

"""Exponential ease-out curve."""

316

317

def ease_in_out_expo(t: float) -> float:

318

"""Exponential ease-in-out curve."""

319

320

# Circular easing

321

def ease_in_circ(t: float) -> float:

322

"""Circular ease-in curve."""

323

324

def ease_out_circ(t: float) -> float:

325

"""Circular ease-out curve."""

326

327

def ease_in_out_circ(t: float) -> float:

328

"""Circular ease-in-out curve."""

329

330

# Back easing (overshoots target)

331

def ease_in_back(t: float) -> float:

332

"""Back ease-in with overshoot."""

333

334

def ease_out_back(t: float) -> float:

335

"""Back ease-out with overshoot."""

336

337

def ease_in_out_back(t: float) -> float:

338

"""Back ease-in-out with overshoot."""

339

340

# Elastic easing (bouncing effect)

341

def ease_in_elastic(t: float) -> float:

342

"""Elastic ease-in with bouncing."""

343

344

def ease_out_elastic(t: float) -> float:

345

"""Elastic ease-out with bouncing."""

346

347

def ease_in_out_elastic(t: float) -> float:

348

"""Elastic ease-in-out with bouncing."""

349

350

# Bounce easing

351

def ease_in_bounce(t: float) -> float:

352

"""Bounce ease-in curve."""

353

354

def ease_out_bounce(t: float) -> float:

355

"""Bounce ease-out curve."""

356

357

def ease_in_out_bounce(t: float) -> float:

358

"""Bounce ease-in-out curve."""

359

360

# Rate function utilities

361

def squish_rate_func(

362

func: Callable[[float], float],

363

a: float = 0.4,

364

b: float = 0.6

365

) -> Callable[[float], float]:

366

"""

367

Compress rate function to operate within [a, b] interval.

368

369

Parameters:

370

- func: Rate function to compress

371

- a: Start of active interval

372

- b: End of active interval

373

374

Returns:

375

- Callable: Compressed rate function

376

"""

377

378

def lingering(t: float) -> float:

379

"""

380

Linger at start, then smoothly progress to end.

381

382

Parameters:

383

- t: Time parameter [0, 1]

384

385

Returns:

386

- float: Lingering progress [0, 1]

387

"""

388

```

389

390

### Color System

391

392

Comprehensive color management system with predefined colors, color space conversions, and gradient utilities.

393

394

```python { .api }

395

# Color class and core functions

396

class ManimColor:

397

"""

398

Manim color class supporting multiple color spaces and formats.

399

400

Handles color parsing, conversion, and manipulation with support

401

for RGB, HSV, hex, and named colors.

402

"""

403

404

def __init__(color_value: str | tuple | np.ndarray) -> None:

405

"""

406

Parameters:

407

- color_value: Color specification (hex, name, RGB tuple, etc.)

408

"""

409

410

@staticmethod

411

def parse(color: str | ManimColor) -> ManimColor:

412

"""Parse color from various input formats."""

413

414

def hex() -> str:

415

"""Get color as hex string (#RRGGBB)."""

416

417

def rgb() -> tuple[float, float, float]:

418

"""Get color as RGB tuple [0,1]."""

419

420

def rgba() -> tuple[float, float, float, float]:

421

"""Get color as RGBA tuple [0,1]."""

422

423

def hsv() -> tuple[float, float, float]:

424

"""Get color as HSV tuple."""

425

426

def invert() -> ManimColor:

427

"""Get inverted/complementary color."""

428

429

def interpolate(other: ManimColor, alpha: float) -> ManimColor:

430

"""Interpolate between this color and another."""

431

432

# Core color constants (most commonly used)

433

WHITE: ManimColor

434

BLACK: ManimColor

435

GRAY: ManimColor

436

GREY: ManimColor # Alternative spelling

437

438

RED: ManimColor

439

GREEN: ManimColor

440

BLUE: ManimColor

441

YELLOW: ManimColor

442

ORANGE: ManimColor

443

PURPLE: ManimColor

444

PINK: ManimColor

445

BROWN: ManimColor

446

447

# Extended color palette

448

RED_A: ManimColor # Light red

449

RED_B: ManimColor # Medium red

450

RED_C: ManimColor # Standard red

451

RED_D: ManimColor # Dark red

452

RED_E: ManimColor # Very dark red

453

454

BLUE_A: ManimColor # Light blue

455

BLUE_B: ManimColor # Medium blue

456

BLUE_C: ManimColor # Standard blue

457

BLUE_D: ManimColor # Dark blue

458

BLUE_E: ManimColor # Very dark blue

459

460

GREEN_A: ManimColor # Light green

461

GREEN_B: ManimColor # Medium green

462

GREEN_C: ManimColor # Standard green

463

GREEN_D: ManimColor # Dark green

464

GREEN_E: ManimColor # Very dark green

465

466

# Additional standard colors

467

MAROON_A: ManimColor

468

MAROON_B: ManimColor

469

MAROON_C: ManimColor

470

MAROON_D: ManimColor

471

MAROON_E: ManimColor

472

473

YELLOW_A: ManimColor

474

YELLOW_B: ManimColor

475

YELLOW_C: ManimColor

476

YELLOW_D: ManimColor

477

YELLOW_E: ManimColor

478

479

TEAL_A: ManimColor

480

TEAL_B: ManimColor

481

TEAL_C: ManimColor

482

TEAL_D: ManimColor

483

TEAL_E: ManimColor

484

485

GOLD_A: ManimColor

486

GOLD_B: ManimColor

487

GOLD_C: ManimColor

488

GOLD_D: ManimColor

489

GOLD_E: ManimColor

490

491

# Color manipulation functions

492

def interpolate_color(

493

color1: ManimColor | str,

494

color2: ManimColor | str,

495

alpha: float

496

) -> ManimColor:

497

"""

498

Interpolate between two colors.

499

500

Parameters:

501

- color1: Starting color

502

- color2: Ending color

503

- alpha: Interpolation factor [0, 1]

504

505

Returns:

506

- ManimColor: Interpolated color

507

"""

508

509

def color_gradient(

510

colors: Sequence[ManimColor | str],

511

length: int

512

) -> list[ManimColor]:

513

"""

514

Create smooth gradient between multiple colors.

515

516

Parameters:

517

- colors: List of colors to interpolate between

518

- length: Number of colors in resulting gradient

519

520

Returns:

521

- list[ManimColor]: Gradient color sequence

522

"""

523

524

def random_color() -> ManimColor:

525

"""Generate random color."""

526

527

def random_bright_color() -> ManimColor:

528

"""Generate random bright/saturated color."""

529

530

def invert_color(color: ManimColor | str) -> ManimColor:

531

"""

532

Get inverted/complementary color.

533

534

Parameters:

535

- color: Color to invert

536

537

Returns:

538

- ManimColor: Inverted color

539

"""

540

541

def color_to_rgb(color: ManimColor | str) -> np.ndarray:

542

"""Convert color to RGB array [0,1]."""

543

544

def color_to_rgba(

545

color: ManimColor | str,

546

alpha: float = 1.0

547

) -> np.ndarray:

548

"""Convert color to RGBA array [0,1]."""

549

550

def rgb_to_color(rgb: np.ndarray) -> ManimColor:

551

"""Convert RGB array to ManimColor."""

552

553

def hex_to_color(hex_code: str) -> ManimColor:

554

"""Convert hex string to ManimColor."""

555

556

# Extended color collections

557

# Access additional color palettes

558

XKCD: module # XKCD color names (XKCD.AVOCADO, etc.)

559

X11: module # X11 color names

560

DVIPSNAMES: module # LaTeX DVIPS color names

561

BS381: module # British Standard colors

562

AS2700: module # Australian Standard colors

563

SVGNAMES: module # SVG/HTML color names

564

```

565

566

### Space Operations

567

568

Mathematical utilities for 3D space calculations, coordinate transformations, and geometric operations.

569

570

```python { .api }

571

# Vector operations

572

def normalize(vect: np.ndarray) -> np.ndarray:

573

"""

574

Normalize vector to unit length.

575

576

Parameters:

577

- vect: Vector to normalize

578

579

Returns:

580

- np.ndarray: Unit vector in same direction

581

"""

582

583

def get_norm(vect: np.ndarray) -> float:

584

"""

585

Get length/magnitude of vector.

586

587

Parameters:

588

- vect: Input vector

589

590

Returns:

591

- float: Vector magnitude

592

"""

593

594

def cross(v1: np.ndarray, v2: np.ndarray) -> np.ndarray:

595

"""

596

Cross product of two 3D vectors.

597

598

Parameters:

599

- v1: First vector

600

- v2: Second vector

601

602

Returns:

603

- np.ndarray: Cross product vector

604

"""

605

606

def dot(v1: np.ndarray, v2: np.ndarray) -> float:

607

"""

608

Dot product of two vectors.

609

610

Parameters:

611

- v1: First vector

612

- v2: Second vector

613

614

Returns:

615

- float: Dot product scalar

616

"""

617

618

def angle_between_vectors(v1: np.ndarray, v2: np.ndarray) -> float:

619

"""

620

Calculate angle between two vectors in radians.

621

622

Parameters:

623

- v1: First vector

624

- v2: Second vector

625

626

Returns:

627

- float: Angle in radians [0, π]

628

"""

629

630

def angle_of_vector(vector: np.ndarray) -> float:

631

"""

632

Get angle of 2D vector from positive x-axis.

633

634

Parameters:

635

- vector: 2D or 3D vector (z-component ignored)

636

637

Returns:

638

- float: Angle in radians [-π, π]

639

"""

640

641

# Coordinate transformations

642

def spherical_to_cartesian(

643

radius: float,

644

theta: float,

645

phi: float

646

) -> np.ndarray:

647

"""

648

Convert spherical coordinates to Cartesian.

649

650

Parameters:

651

- radius: Radial distance

652

- theta: Azimuthal angle (from x-axis)

653

- phi: Polar angle (from z-axis)

654

655

Returns:

656

- np.ndarray: Cartesian coordinates [x, y, z]

657

"""

658

659

def cartesian_to_spherical(point: np.ndarray) -> tuple[float, float, float]:

660

"""

661

Convert Cartesian coordinates to spherical.

662

663

Parameters:

664

- point: Cartesian point [x, y, z]

665

666

Returns:

667

- tuple: (radius, theta, phi) in spherical coordinates

668

"""

669

670

def cylindrical_to_cartesian(

671

radius: float,

672

theta: float,

673

z: float

674

) -> np.ndarray:

675

"""

676

Convert cylindrical coordinates to Cartesian.

677

678

Parameters:

679

- radius: Radial distance from z-axis

680

- theta: Angle around z-axis

681

- z: Height along z-axis

682

683

Returns:

684

- np.ndarray: Cartesian coordinates [x, y, z]

685

"""

686

687

# Rotation and transformation matrices

688

def rotation_matrix(

689

angle: float,

690

axis: np.ndarray = OUT

691

) -> np.ndarray:

692

"""

693

Create rotation matrix for rotating around specified axis.

694

695

Parameters:

696

- angle: Rotation angle in radians

697

- axis: Rotation axis vector

698

699

Returns:

700

- np.ndarray: 3x3 rotation matrix

701

"""

702

703

def rotation_about_z(angle: float) -> np.ndarray:

704

"""Rotation matrix for rotation about z-axis."""

705

706

def z_to_vector(z: complex) -> np.ndarray:

707

"""Convert complex number to 2D vector."""

708

709

def complex_to_R3(z: complex) -> np.ndarray:

710

"""Convert complex number to 3D point [Re(z), Im(z), 0]."""

711

712

def R3_to_complex(point: np.ndarray) -> complex:

713

"""Convert 3D point to complex number."""

714

715

def rotate_vector(

716

vector: np.ndarray,

717

angle: float,

718

axis: np.ndarray = OUT

719

) -> np.ndarray:

720

"""

721

Rotate vector around specified axis.

722

723

Parameters:

724

- vector: Vector to rotate

725

- angle: Rotation angle in radians

726

- axis: Rotation axis

727

728

Returns:

729

- np.ndarray: Rotated vector

730

"""

731

732

# Geometric utilities

733

def line_intersection(

734

line1: tuple[np.ndarray, np.ndarray],

735

line2: tuple[np.ndarray, np.ndarray]

736

) -> np.ndarray:

737

"""

738

Find intersection point of two 2D lines.

739

740

Parameters:

741

- line1: (point1, point2) defining first line

742

- line2: (point1, point2) defining second line

743

744

Returns:

745

- np.ndarray: Intersection point

746

"""

747

748

def get_closest_point_on_line(

749

a: np.ndarray,

750

b: np.ndarray,

751

p: np.ndarray

752

) -> np.ndarray:

753

"""

754

Find closest point on line segment to given point.

755

756

Parameters:

757

- a: Line start point

758

- b: Line end point

759

- p: Reference point

760

761

Returns:

762

- np.ndarray: Closest point on line to p

763

"""

764

765

def perpendicular_bisector(

766

line: tuple[np.ndarray, np.ndarray]

767

) -> tuple[np.ndarray, np.ndarray]:

768

"""

769

Get perpendicular bisector of line segment.

770

771

Parameters:

772

- line: (start_point, end_point) of line segment

773

774

Returns:

775

- tuple: (point, direction) defining perpendicular bisector

776

"""

777

778

def compass_directions(n: int = 4, start_vect: np.ndarray = RIGHT) -> list[np.ndarray]:

779

"""

780

Generate n evenly spaced unit vectors around circle.

781

782

Parameters:

783

- n: Number of directions

784

- start_vect: Starting direction

785

786

Returns:

787

- list[np.ndarray]: List of direction vectors

788

"""

789

```

790

791

### File and Path Operations

792

793

File system utilities for handling assets, output files, and resource management.

794

795

```python { .api }

796

# File operations

797

def guarantee_existence(path: str) -> str:

798

"""

799

Ensure directory exists, creating it if necessary.

800

801

Parameters:

802

- path: Directory path

803

804

Returns:

805

- str: Verified directory path

806

"""

807

808

def add_extension_if_not_present(

809

file_name: str,

810

extension: str

811

) -> str:

812

"""

813

Add file extension if not already present.

814

815

Parameters:

816

- file_name: Base filename

817

- extension: Extension to add (with or without dot)

818

819

Returns:

820

- str: Filename with extension

821

"""

822

823

def get_sorted_integer_files(directory: str) -> list[str]:

824

"""

825

Get list of files with integer names, sorted numerically.

826

827

Parameters:

828

- directory: Directory to search

829

830

Returns:

831

- list[str]: Sorted list of integer-named files

832

"""

833

834

def seek_full_path_from_defaults(

835

file_name: str,

836

default_dir: str,

837

extensions: list[str] = None

838

) -> str:

839

"""

840

Find file in default directory with optional extension matching.

841

842

Parameters:

843

- file_name: Base filename to search for

844

- default_dir: Directory to search in

845

- extensions: List of extensions to try

846

847

Returns:

848

- str: Full path to found file

849

"""

850

851

def open_media_file(file_path: str) -> None:

852

"""

853

Open media file with system default application.

854

855

Parameters:

856

- file_path: Path to media file

857

"""

858

859

# Path utilities

860

def get_manim_dir() -> str:

861

"""Get Manim installation directory."""

862

863

def get_downloads_dir() -> str:

864

"""Get user downloads directory."""

865

866

def get_output_dir() -> str:

867

"""Get configured output directory."""

868

869

def get_tex_dir() -> str:

870

"""Get directory for LaTeX files."""

871

872

def get_raster_image_dir() -> str:

873

"""Get directory for raster images."""

874

875

def get_vector_image_dir() -> str:

876

"""Get directory for vector images."""

877

878

# Asset management

879

def find_file(

880

file_name: str,

881

directories: list[str] = None

882

) -> str:

883

"""

884

Search for file in multiple directories.

885

886

Parameters:

887

- file_name: Name of file to find

888

- directories: List of directories to search

889

890

Returns:

891

- str: Full path to found file

892

"""

893

```

894

895

### Mathematical Utilities

896

897

Essential mathematical functions and utilities for calculations, interpolation, and numerical operations.

898

899

```python { .api }

900

# Interpolation functions

901

def interpolate(start: float, end: float, alpha: float) -> float:

902

"""

903

Linear interpolation between two values.

904

905

Parameters:

906

- start: Starting value

907

- end: Ending value

908

- alpha: Interpolation factor [0, 1]

909

910

Returns:

911

- float: Interpolated value

912

"""

913

914

def inverse_interpolate(

915

start: float,

916

end: float,

917

value: float

918

) -> float:

919

"""

920

Find interpolation factor for given value between start and end.

921

922

Parameters:

923

- start: Starting value

924

- end: Ending value

925

- value: Value to find factor for

926

927

Returns:

928

- float: Interpolation factor

929

"""

930

931

def clip(value: float, min_val: float, max_val: float) -> float:

932

"""

933

Clamp value to specified range.

934

935

Parameters:

936

- value: Value to clamp

937

- min_val: Minimum allowed value

938

- max_val: Maximum allowed value

939

940

Returns:

941

- float: Clamped value

942

"""

943

944

def binary_search(

945

function: Callable[[float], float],

946

target: float,

947

lower_bound: float,

948

upper_bound: float,

949

tolerance: float = 1e-6

950

) -> float:

951

"""

952

Binary search for input that produces target output.

953

954

Parameters:

955

- function: Function to search

956

- target: Target output value

957

- lower_bound: Lower bound for search

958

- upper_bound: Upper bound for search

959

- tolerance: Accuracy tolerance

960

961

Returns:

962

- float: Input value producing target output

963

"""

964

965

# Numerical utilities

966

def choose(n: int, k: int) -> int:

967

"""

968

Binomial coefficient "n choose k".

969

970

Parameters:

971

- n: Total number of items

972

- k: Number to choose

973

974

Returns:

975

- int: Binomial coefficient

976

"""

977

978

def bezier(points: np.ndarray) -> Callable[[float], np.ndarray]:

979

"""

980

Create Bézier curve function from control points.

981

982

Parameters:

983

- points: Array of control points

984

985

Returns:

986

- Callable: Function mapping t∈[0,1] to curve points

987

"""

988

989

def partial_bezier_points(

990

points: np.ndarray,

991

a: float,

992

b: float

993

) -> np.ndarray:

994

"""

995

Get control points for partial Bézier curve.

996

997

Parameters:

998

- points: Original control points

999

- a: Start parameter [0, 1]

1000

- b: End parameter [0, 1]

1001

1002

Returns:

1003

- np.ndarray: Control points for partial curve

1004

"""

1005

1006

# Array and sequence utilities

1007

def make_smooth_bezier_curve_connections(

1008

bezier_point_sets: list[np.ndarray]

1009

) -> list[np.ndarray]:

1010

"""

1011

Connect Bézier curves smoothly by adjusting control points.

1012

1013

Parameters:

1014

- bezier_point_sets: List of Bézier control point sets

1015

1016

Returns:

1017

- list[np.ndarray]: Smoothly connected control point sets

1018

"""

1019

1020

def get_smooth_handle_points(

1021

points: np.ndarray

1022

) -> tuple[np.ndarray, np.ndarray]:

1023

"""

1024

Generate smooth Bézier handles for curve through points.

1025

1026

Parameters:

1027

- points: Points to create smooth curve through

1028

1029

Returns:

1030

- tuple: (left_handles, right_handles) for smooth curve

1031

"""

1032

```

1033

1034

### Debugging and Development

1035

1036

Tools and utilities for debugging animations, performance monitoring, and development workflow enhancement.

1037

1038

```python { .api }

1039

# Logging and debugging

1040

from manim import logger

1041

1042

logger.debug(message: str) -> None:

1043

"""Log debug-level message."""

1044

1045

logger.info(message: str) -> None:

1046

"""Log info-level message."""

1047

1048

logger.warning(message: str) -> None:

1049

"""Log warning-level message."""

1050

1051

logger.error(message: str) -> None:

1052

"""Log error-level message."""

1053

1054

# Console output (use instead of print)

1055

from manim import console

1056

1057

console.print(*args, **kwargs) -> None:

1058

"""Rich console print with formatting support."""

1059

1060

console.log(*args, **kwargs) -> None:

1061

"""Rich console log with timestamp."""

1062

1063

# Development utilities

1064

def get_parameters_from_function(func: Callable) -> dict:

1065

"""Extract parameter information from function signature."""

1066

1067

def get_all_descendent_classes(Class: type) -> list[type]:

1068

"""Get all classes that inherit from given class."""

1069

1070

def get_mobject_family_members(

1071

mobjects: list[Mobject],

1072

only_those_with_points: bool = False

1073

) -> list[Mobject]:

1074

"""

1075

Get all mobjects including submobjects in flattened list.

1076

1077

Parameters:

1078

- mobjects: List of mobjects to expand

1079

- only_those_with_points: Whether to include only mobjects with points

1080

1081

Returns:

1082

- list[Mobject]: Flattened list including all submobjects

1083

"""

1084

1085

# Performance monitoring

1086

import time

1087

1088

def time_function(func: Callable) -> Callable:

1089

"""Decorator to measure function execution time."""

1090

1091

def profile_memory_usage(func: Callable) -> Callable:

1092

"""Decorator to profile memory usage of function."""

1093

1094

# Interactive development

1095

def interactive_embed() -> None:

1096

"""Start interactive Python session with current scene state."""

1097

1098

def pause_for_interaction() -> None:

1099

"""Pause animation for user interaction."""

1100

```

1101

1102

## Usage Examples

1103

1104

### Rate Functions

1105

1106

```python

1107

from manim import *

1108

1109

class RateFunctionExample(Scene):

1110

def construct(self):

1111

dot = Dot()

1112

1113

# Different easing styles

1114

animations = [

1115

dot.animate.shift(RIGHT * 2).set_rate_func(linear),

1116

dot.animate.shift(UP * 2).set_rate_func(smooth),

1117

dot.animate.shift(LEFT * 2).set_rate_func(there_and_back),

1118

dot.animate.shift(DOWN * 2).set_rate_func(ease_out_bounce)

1119

]

1120

1121

for anim in animations:

1122

self.play(anim)

1123

self.wait(0.5)

1124

```

1125

1126

### Color Operations

1127

1128

```python

1129

class ColorExample(Scene):

1130

def construct(self):

1131

# Using predefined colors

1132

circle1 = Circle(color=RED)

1133

circle2 = Circle(color=BLUE_D)

1134

circle3 = Circle(color=XKCD.AVOCADO)

1135

1136

# Color interpolation

1137

interpolated_color = interpolate_color(RED, BLUE, 0.5)

1138

circle4 = Circle(color=interpolated_color)

1139

1140

# Color gradients

1141

gradient_colors = color_gradient([RED, GREEN, BLUE], 10)

1142

circles = VGroup(*[

1143

Circle(color=color, radius=0.3)

1144

for color in gradient_colors

1145

])

1146

circles.arrange(RIGHT)

1147

1148

self.add(circles)

1149

```

1150

1151

### Space Operations

1152

1153

```python

1154

class SpaceOpsExample(Scene):

1155

def construct(self):

1156

# Vector operations

1157

v1 = np.array([1, 0, 0])

1158

v2 = np.array([0, 1, 0])

1159

1160

# Cross product

1161

cross_product = cross(v1, v2)

1162

arrow = Arrow(ORIGIN, cross_product, color=RED)

1163

1164

# Angle between vectors

1165

angle = angle_between_vectors(UP, RIGHT)

1166

arc = Arc(angle=angle, color=YELLOW)

1167

1168

# Rotation

1169

rotated_vector = rotate_vector(RIGHT, PI/4)

1170

rotated_arrow = Arrow(ORIGIN, rotated_vector, color=GREEN)

1171

1172

self.add(arrow, arc, rotated_arrow)

1173

```

1174

1175

### Mathematical Utilities

1176

1177

```python

1178

class MathUtilsExample(Scene):

1179

def construct(self):

1180

# Create smooth curve through points

1181

points = np.array([

1182

[-3, -1, 0],

1183

[-1, 1, 0],

1184

[1, -1, 0],

1185

[3, 1, 0]

1186

])

1187

1188

# Generate smooth Bézier curve

1189

curve = VMobject()

1190

curve.set_points_smoothly(points)

1191

curve.set_stroke(YELLOW, 3)

1192

1193

# Mark the control points

1194

dots = VGroup(*[Dot(p, color=RED) for p in points])

1195

1196

self.add(curve, dots)

1197

```

1198

1199

### Development and Debugging

1200

1201

```python

1202

class DebugExample(Scene):

1203

def construct(self):

1204

# Enable debug logging

1205

logger.setLevel("DEBUG")

1206

1207

# Time animation performance

1208

start_time = time.time()

1209

1210

circle = Circle()

1211

logger.info("Created circle")

1212

1213

self.play(Create(circle))

1214

1215

end_time = time.time()

1216

logger.info(f"Animation took {end_time - start_time:.2f} seconds")

1217

1218

# Interactive debugging (uncomment for interactive use)

1219

# self.interactive_embed()

1220

```

1221

1222

### File Operations

1223

1224

```python

1225

class FileOpsExample(Scene):

1226

def construct(self):

1227

# Ensure output directory exists

1228

output_dir = guarantee_existence("custom_output")

1229

1230

# Find asset file

1231

try:

1232

asset_path = find_file("my_image.png", [

1233

"assets/images",

1234

"resources",

1235

get_downloads_dir()

1236

])

1237

1238

# Use found image

1239

image = ImageMobject(asset_path)

1240

self.add(image)

1241

1242

except FileNotFoundError:

1243

# Fallback if image not found

1244

text = Text("Image not found")

1245

self.add(text)

1246

```

1247

1248

### Configuration and Constants

1249

1250

```python

1251

class ConstantsExample(Scene):

1252

def construct(self):

1253

# Use directional constants for positioning

1254

center_dot = Dot(ORIGIN, color=WHITE)

1255

1256

direction_dots = VGroup(

1257

Dot(UP, color=RED),

1258

Dot(DOWN, color=GREEN),

1259

Dot(LEFT, color=BLUE),

1260

Dot(RIGHT, color=YELLOW),

1261

Dot(UL, color=PURPLE),

1262

Dot(UR, color=ORANGE),

1263

Dot(DL, color=PINK),

1264

Dot(DR, color=TEAL)

1265

)

1266

1267

# Use buffer constants for spacing

1268

text = Text("Directions").next_to(

1269

center_dot,

1270

UP,

1271

buff=LARGE_BUFF

1272

)

1273

1274

self.add(center_dot, direction_dots, text)

1275

```