manim 0.17.0__py3-none-any.whl → 0.19.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. manim/__init__.py +11 -6
  2. manim/__main__.py +62 -19
  3. manim/_config/__init__.py +10 -9
  4. manim/_config/cli_colors.py +26 -9
  5. manim/_config/default.cfg +1 -3
  6. manim/_config/logger_utils.py +23 -13
  7. manim/_config/utils.py +662 -468
  8. manim/animation/animation.py +164 -18
  9. manim/animation/changing.py +34 -23
  10. manim/animation/composition.py +265 -67
  11. manim/animation/creation.py +208 -26
  12. manim/animation/fading.py +16 -18
  13. manim/animation/growing.py +35 -15
  14. manim/animation/indication.py +150 -76
  15. manim/animation/movement.py +56 -22
  16. manim/animation/numbers.py +64 -6
  17. manim/animation/rotation.py +78 -7
  18. manim/animation/specialized.py +6 -7
  19. manim/animation/speedmodifier.py +13 -10
  20. manim/animation/transform.py +14 -11
  21. manim/animation/transform_matching_parts.py +3 -4
  22. manim/animation/updaters/mobject_update_utils.py +152 -30
  23. manim/animation/updaters/update.py +10 -7
  24. manim/camera/camera.py +182 -118
  25. manim/camera/mapping_camera.py +34 -3
  26. manim/camera/moving_camera.py +95 -74
  27. manim/camera/multi_camera.py +23 -15
  28. manim/camera/three_d_camera.py +70 -52
  29. manim/cli/__init__.py +17 -0
  30. manim/cli/cfg/group.py +76 -44
  31. manim/cli/checkhealth/checks.py +192 -0
  32. manim/cli/checkhealth/commands.py +90 -0
  33. manim/cli/default_group.py +158 -25
  34. manim/cli/init/commands.py +33 -25
  35. manim/cli/plugins/commands.py +16 -3
  36. manim/cli/render/commands.py +72 -60
  37. manim/cli/render/ease_of_access_options.py +4 -3
  38. manim/cli/render/global_options.py +59 -17
  39. manim/cli/render/output_options.py +6 -5
  40. manim/cli/render/render_options.py +98 -33
  41. manim/constants.py +109 -59
  42. manim/data_structures.py +31 -0
  43. manim/mobject/frame.py +8 -5
  44. manim/mobject/geometry/__init__.py +1 -0
  45. manim/mobject/geometry/arc.py +277 -135
  46. manim/mobject/geometry/boolean_ops.py +32 -31
  47. manim/mobject/geometry/labeled.py +376 -0
  48. manim/mobject/geometry/line.py +192 -87
  49. manim/mobject/geometry/polygram.py +224 -58
  50. manim/mobject/geometry/shape_matchers.py +61 -25
  51. manim/mobject/geometry/tips.py +122 -48
  52. manim/mobject/graph.py +1027 -419
  53. manim/mobject/graphing/coordinate_systems.py +533 -278
  54. manim/mobject/graphing/functions.py +53 -32
  55. manim/mobject/graphing/number_line.py +123 -65
  56. manim/mobject/graphing/probability.py +88 -62
  57. manim/mobject/graphing/scale.py +33 -19
  58. manim/mobject/logo.py +118 -28
  59. manim/mobject/matrix.py +87 -83
  60. manim/mobject/mobject.py +912 -442
  61. manim/mobject/opengl/dot_cloud.py +16 -5
  62. manim/mobject/opengl/opengl_compatibility.py +4 -2
  63. manim/mobject/opengl/opengl_geometry.py +254 -153
  64. manim/mobject/opengl/opengl_image_mobject.py +3 -1
  65. manim/mobject/opengl/opengl_mobject.py +779 -482
  66. manim/mobject/opengl/opengl_point_cloud_mobject.py +41 -14
  67. manim/mobject/opengl/opengl_surface.py +14 -92
  68. manim/mobject/opengl/opengl_three_dimensions.py +12 -8
  69. manim/mobject/opengl/opengl_vectorized_mobject.py +98 -100
  70. manim/mobject/svg/brace.py +173 -41
  71. manim/mobject/svg/svg_mobject.py +139 -53
  72. manim/mobject/table.py +61 -68
  73. manim/mobject/text/code_mobject.py +193 -539
  74. manim/mobject/text/numbers.py +81 -34
  75. manim/mobject/text/tex_mobject.py +130 -78
  76. manim/mobject/text/text_mobject.py +288 -164
  77. manim/mobject/three_d/polyhedra.py +111 -13
  78. manim/mobject/three_d/three_d_utils.py +17 -8
  79. manim/mobject/three_d/three_dimensions.py +239 -106
  80. manim/mobject/types/image_mobject.py +50 -30
  81. manim/mobject/types/point_cloud_mobject.py +120 -75
  82. manim/mobject/types/vectorized_mobject.py +841 -408
  83. manim/mobject/value_tracker.py +105 -38
  84. manim/mobject/vector_field.py +50 -31
  85. manim/opengl/__init__.py +3 -3
  86. manim/plugins/__init__.py +14 -1
  87. manim/plugins/plugins_flags.py +10 -14
  88. manim/renderer/cairo_renderer.py +65 -50
  89. manim/renderer/opengl_renderer.py +89 -69
  90. manim/renderer/opengl_renderer_window.py +39 -18
  91. manim/renderer/shader.py +123 -87
  92. manim/renderer/shader_wrapper.py +44 -28
  93. manim/renderer/vectorized_mobject_rendering.py +38 -10
  94. manim/scene/moving_camera_scene.py +32 -3
  95. manim/scene/scene.py +507 -242
  96. manim/scene/scene_file_writer.py +371 -220
  97. manim/scene/section.py +20 -16
  98. manim/scene/three_d_scene.py +14 -22
  99. manim/scene/vector_space_scene.py +223 -129
  100. manim/scene/zoomed_scene.py +46 -41
  101. manim/typing.py +990 -0
  102. manim/utils/bezier.py +1823 -371
  103. manim/utils/caching.py +12 -5
  104. manim/utils/color/AS2700.py +236 -0
  105. manim/utils/color/BS381.py +318 -0
  106. manim/utils/color/DVIPSNAMES.py +96 -0
  107. manim/utils/color/SVGNAMES.py +179 -0
  108. manim/utils/color/X11.py +533 -0
  109. manim/utils/color/XKCD.py +952 -0
  110. manim/utils/color/__init__.py +61 -0
  111. manim/utils/color/core.py +1667 -0
  112. manim/utils/color/manim_colors.py +218 -0
  113. manim/utils/commands.py +48 -20
  114. manim/utils/config_ops.py +39 -19
  115. manim/utils/debug.py +8 -7
  116. manim/utils/deprecation.py +86 -39
  117. manim/utils/docbuild/__init__.py +17 -0
  118. manim/utils/docbuild/autoaliasattr_directive.py +236 -0
  119. manim/utils/docbuild/autocolor_directive.py +99 -0
  120. manim/utils/docbuild/manim_directive.py +94 -41
  121. manim/utils/docbuild/module_parsing.py +245 -0
  122. manim/utils/exceptions.py +6 -0
  123. manim/utils/family.py +5 -3
  124. manim/utils/family_ops.py +17 -4
  125. manim/utils/file_ops.py +27 -17
  126. manim/utils/hashing.py +55 -45
  127. manim/utils/images.py +13 -7
  128. manim/utils/ipython_magic.py +13 -7
  129. manim/utils/iterables.py +163 -120
  130. manim/utils/module_ops.py +66 -24
  131. manim/utils/opengl.py +77 -24
  132. manim/utils/parameter_parsing.py +32 -0
  133. manim/utils/paths.py +30 -33
  134. manim/utils/polylabel.py +235 -0
  135. manim/utils/qhull.py +218 -0
  136. manim/utils/rate_functions.py +98 -32
  137. manim/utils/simple_functions.py +25 -33
  138. manim/utils/sounds.py +7 -1
  139. manim/utils/space_ops.py +188 -115
  140. manim/utils/testing/__init__.py +17 -0
  141. manim/utils/testing/_frames_testers.py +13 -8
  142. manim/utils/testing/_show_diff.py +5 -3
  143. manim/utils/testing/_test_class_makers.py +34 -18
  144. manim/utils/testing/frames_comparison.py +37 -19
  145. manim/utils/tex.py +130 -198
  146. manim/utils/tex_file_writing.py +77 -47
  147. manim/utils/tex_templates.py +2 -1
  148. manim/utils/unit.py +6 -5
  149. {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/METADATA +64 -65
  150. manim-0.19.1.dist-info/RECORD +220 -0
  151. {manim-0.17.0.dist-info → manim-0.19.1.dist-info}/WHEEL +1 -1
  152. manim-0.19.1.dist-info/entry_points.txt +3 -0
  153. {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE.community +1 -1
  154. manim/cli/new/group.py +0 -189
  155. manim/communitycolors.py +0 -9
  156. manim/gui/__init__.py +0 -0
  157. manim/gui/gui.py +0 -82
  158. manim/plugins/import_plugins.py +0 -43
  159. manim/utils/color.py +0 -552
  160. manim-0.17.0.dist-info/RECORD +0 -206
  161. manim-0.17.0.dist-info/entry_points.txt +0 -4
  162. /manim/cli/{new → checkhealth}/__init__.py +0 -0
  163. {manim-0.17.0.dist-info → manim-0.19.1.dist-info/licenses}/LICENSE +0 -0
manim/utils/color.py DELETED
@@ -1,552 +0,0 @@
1
- """Colors and utility functions for conversion between different color models."""
2
-
3
- from __future__ import annotations
4
-
5
- __all__ = [
6
- "color_to_rgb",
7
- "color_to_rgba",
8
- "rgb_to_color",
9
- "rgba_to_color",
10
- "rgb_to_hex",
11
- "hex_to_rgb",
12
- "invert_color",
13
- "color_to_int_rgb",
14
- "color_to_int_rgba",
15
- "color_gradient",
16
- "interpolate_color",
17
- "average_color",
18
- "random_bright_color",
19
- "random_color",
20
- "get_shaded_rgb",
21
- ]
22
-
23
- import random
24
- from enum import Enum
25
- from typing import Iterable
26
-
27
- import numpy as np
28
- from colour import Color
29
-
30
- from ..utils.bezier import interpolate
31
- from ..utils.space_ops import normalize
32
-
33
-
34
- class Colors(Enum):
35
- """A list of pre-defined colors.
36
-
37
- Examples
38
- --------
39
-
40
- .. manim:: ColorsOverview
41
- :save_last_frame:
42
- :hide_source:
43
-
44
- from manim.utils.color import Colors
45
- class ColorsOverview(Scene):
46
- def construct(self):
47
- def color_group(color):
48
- group = VGroup(
49
- *[
50
- Line(ORIGIN, RIGHT * 1.5, stroke_width=35, color=Colors[name].value)
51
- for name in subnames(color)
52
- ]
53
- ).arrange_submobjects(buff=0.4, direction=DOWN)
54
-
55
- name = Text(color).scale(0.6).next_to(group, UP, buff=0.3)
56
- if any(decender in color for decender in "gjpqy"):
57
- name.shift(DOWN * 0.08)
58
- group.add(name)
59
- return group
60
-
61
- def subnames(name):
62
- return [name + "_" + char for char in "abcde"]
63
-
64
- color_groups = VGroup(
65
- *[
66
- color_group(color)
67
- for color in [
68
- "blue",
69
- "teal",
70
- "green",
71
- "yellow",
72
- "gold",
73
- "red",
74
- "maroon",
75
- "purple",
76
- ]
77
- ]
78
- ).arrange_submobjects(buff=0.2, aligned_edge=DOWN)
79
-
80
- for line, char in zip(color_groups[0], "abcde"):
81
- color_groups.add(Text(char).scale(0.6).next_to(line, LEFT, buff=0.2))
82
-
83
- def named_lines_group(length, colors, names, text_colors, align_to_block):
84
- lines = VGroup(
85
- *[
86
- Line(
87
- ORIGIN,
88
- RIGHT * length,
89
- stroke_width=55,
90
- color=Colors[color].value,
91
- )
92
- for color in colors
93
- ]
94
- ).arrange_submobjects(buff=0.6, direction=DOWN)
95
-
96
- for line, name, color in zip(lines, names, text_colors):
97
- line.add(Text(name, color=color).scale(0.6).move_to(line))
98
- lines.next_to(color_groups, DOWN, buff=0.5).align_to(
99
- color_groups[align_to_block], LEFT
100
- )
101
- return lines
102
-
103
- other_colors = (
104
- "pink",
105
- "light_pink",
106
- "orange",
107
- "light_brown",
108
- "dark_brown",
109
- "gray_brown",
110
- )
111
-
112
- other_lines = named_lines_group(
113
- 3.2,
114
- other_colors,
115
- other_colors,
116
- [BLACK] * 4 + [WHITE] * 2,
117
- 0,
118
- )
119
-
120
- gray_lines = named_lines_group(
121
- 6.6,
122
- ["white"] + subnames("gray") + ["black"],
123
- [
124
- "white",
125
- "lighter_gray / gray_a",
126
- "light_gray / gray_b",
127
- "gray / gray_c",
128
- "dark_gray / gray_d",
129
- "darker_gray / gray_e",
130
- "black",
131
- ],
132
- [BLACK] * 3 + [WHITE] * 4,
133
- 2,
134
- )
135
-
136
- pure_colors = (
137
- "pure_red",
138
- "pure_green",
139
- "pure_blue",
140
- )
141
-
142
- pure_lines = named_lines_group(
143
- 3.2,
144
- pure_colors,
145
- pure_colors,
146
- [BLACK, BLACK, WHITE],
147
- 6,
148
- )
149
-
150
- self.add(color_groups, other_lines, gray_lines, pure_lines)
151
-
152
- VGroup(*self.mobjects).move_to(ORIGIN)
153
-
154
-
155
- The preferred way of using these colors is by importing their constants from manim:
156
-
157
- .. code-block:: pycon
158
-
159
- >>> from manim import RED, GREEN, BLUE
160
- >>> RED
161
- '#FC6255'
162
-
163
- Note this way uses the name of the colors in UPPERCASE.
164
-
165
- Alternatively, you can also import this Enum directly and use its members
166
- directly, through the use of :code:`color.value`. Note this way uses the
167
- name of the colors in lowercase.
168
-
169
- .. code-block:: pycon
170
-
171
- >>> from manim.utils.color import Colors
172
- >>> Colors.red.value
173
- '#FC6255'
174
-
175
- .. note::
176
-
177
- The colors of type "C" have an alias equal to the colorname without a letter,
178
- e.g. GREEN = GREEN_C
179
-
180
- """
181
-
182
- white: str = "#FFFFFF"
183
- gray_a: str = "#DDDDDD"
184
- gray_b: str = "#BBBBBB"
185
- gray_c: str = "#888888"
186
- gray_d: str = "#444444"
187
- gray_e: str = "#222222"
188
- black: str = "#000000"
189
- lighter_gray: str = gray_a
190
- light_gray: str = gray_b
191
- gray: str = gray_c
192
- dark_gray: str = gray_d
193
- darker_gray: str = gray_e
194
-
195
- blue_a: str = "#C7E9F1"
196
- blue_b: str = "#9CDCEB"
197
- blue_c: str = "#58C4DD"
198
- blue_d: str = "#29ABCA"
199
- blue_e: str = "#236B8E"
200
- pure_blue: str = "#0000FF"
201
- blue: str = blue_c
202
- dark_blue: str = blue_e
203
-
204
- teal_a: str = "#ACEAD7"
205
- teal_b: str = "#76DDC0"
206
- teal_c: str = "#5CD0B3"
207
- teal_d: str = "#55C1A7"
208
- teal_e: str = "#49A88F"
209
- teal: str = teal_c
210
-
211
- green_a: str = "#C9E2AE"
212
- green_b: str = "#A6CF8C"
213
- green_c: str = "#83C167"
214
- green_d: str = "#77B05D"
215
- green_e: str = "#699C52"
216
- pure_green: str = "#00FF00"
217
- green: str = green_c
218
-
219
- yellow_a: str = "#FFF1B6"
220
- yellow_b: str = "#FFEA94"
221
- yellow_c: str = "#FFFF00"
222
- yellow_d: str = "#F4D345"
223
- yellow_e: str = "#E8C11C"
224
- yellow: str = yellow_c
225
-
226
- gold_a: str = "#F7C797"
227
- gold_b: str = "#F9B775"
228
- gold_c: str = "#F0AC5F"
229
- gold_d: str = "#E1A158"
230
- gold_e: str = "#C78D46"
231
- gold: str = gold_c
232
-
233
- red_a: str = "#F7A1A3"
234
- red_b: str = "#FF8080"
235
- red_c: str = "#FC6255"
236
- red_d: str = "#E65A4C"
237
- red_e: str = "#CF5044"
238
- pure_red: str = "#FF0000"
239
- red: str = red_c
240
-
241
- maroon_a: str = "#ECABC1"
242
- maroon_b: str = "#EC92AB"
243
- maroon_c: str = "#C55F73"
244
- maroon_d: str = "#A24D61"
245
- maroon_e: str = "#94424F"
246
- maroon: str = maroon_c
247
-
248
- purple_a: str = "#CAA3E8"
249
- purple_b: str = "#B189C6"
250
- purple_c: str = "#9A72AC"
251
- purple_d: str = "#715582"
252
- purple_e: str = "#644172"
253
- purple: str = purple_c
254
-
255
- pink: str = "#D147BD"
256
- light_pink: str = "#DC75CD"
257
-
258
- orange: str = "#FF862F"
259
- light_brown: str = "#CD853F"
260
- dark_brown: str = "#8B4513"
261
- gray_brown: str = "#736357"
262
-
263
-
264
- def print_constant_definitions():
265
- """
266
- A simple function used to generate the constant values below. To run it
267
- paste this function and the Colors class into a file and run them.
268
- """
269
- constants_names: list[str] = []
270
- for name in Colors.__members__.keys():
271
- name_upper = name.upper()
272
-
273
- constants_names.append(name_upper)
274
- print(f"{name_upper} = Colors.{name}")
275
-
276
- if "GRAY" in name_upper:
277
- name_upper = name_upper.replace("GRAY", "GREY")
278
-
279
- constants_names.append(name_upper)
280
- print(f"{name_upper} = Colors.{name}")
281
-
282
- constants_names_repr = '[\n "' + '",\n "'.join(constants_names) + '",\n]'
283
-
284
- print(f"\n__all__ += {constants_names_repr}")
285
-
286
-
287
- WHITE: str = "#FFFFFF"
288
- GRAY_A: str = "#DDDDDD"
289
- GREY_A: str = "#DDDDDD"
290
- GRAY_B: str = "#BBBBBB"
291
- GREY_B: str = "#BBBBBB"
292
- GRAY_C: str = "#888888"
293
- GREY_C: str = "#888888"
294
- GRAY_D: str = "#444444"
295
- GREY_D: str = "#444444"
296
- GRAY_E: str = "#222222"
297
- GREY_E: str = "#222222"
298
- BLACK: str = "#000000"
299
- LIGHTER_GRAY: str = "#DDDDDD"
300
- LIGHTER_GREY: str = "#DDDDDD"
301
- LIGHT_GRAY: str = "#BBBBBB"
302
- LIGHT_GREY: str = "#BBBBBB"
303
- GRAY: str = "#888888"
304
- GREY: str = "#888888"
305
- DARK_GRAY: str = "#444444"
306
- DARK_GREY: str = "#444444"
307
- DARKER_GRAY: str = "#222222"
308
- DARKER_GREY: str = "#222222"
309
- BLUE_A: str = "#C7E9F1"
310
- BLUE_B: str = "#9CDCEB"
311
- BLUE_C: str = "#58C4DD"
312
- BLUE_D: str = "#29ABCA"
313
- BLUE_E: str = "#236B8E"
314
- PURE_BLUE: str = "#0000FF"
315
- BLUE: str = "#58C4DD"
316
- DARK_BLUE: str = "#236B8E"
317
- TEAL_A: str = "#ACEAD7"
318
- TEAL_B: str = "#76DDC0"
319
- TEAL_C: str = "#5CD0B3"
320
- TEAL_D: str = "#55C1A7"
321
- TEAL_E: str = "#49A88F"
322
- TEAL: str = "#5CD0B3"
323
- GREEN_A: str = "#C9E2AE"
324
- GREEN_B: str = "#A6CF8C"
325
- GREEN_C: str = "#83C167"
326
- GREEN_D: str = "#77B05D"
327
- GREEN_E: str = "#699C52"
328
- PURE_GREEN: str = "#00FF00"
329
- GREEN: str = "#83C167"
330
- YELLOW_A: str = "#FFF1B6"
331
- YELLOW_B: str = "#FFEA94"
332
- YELLOW_C: str = "#FFFF00"
333
- YELLOW_D: str = "#F4D345"
334
- YELLOW_E: str = "#E8C11C"
335
- YELLOW: str = "#FFFF00"
336
- GOLD_A: str = "#F7C797"
337
- GOLD_B: str = "#F9B775"
338
- GOLD_C: str = "#F0AC5F"
339
- GOLD_D: str = "#E1A158"
340
- GOLD_E: str = "#C78D46"
341
- GOLD: str = "#F0AC5F"
342
- RED_A: str = "#F7A1A3"
343
- RED_B: str = "#FF8080"
344
- RED_C: str = "#FC6255"
345
- RED_D: str = "#E65A4C"
346
- RED_E: str = "#CF5044"
347
- PURE_RED: str = "#FF0000"
348
- RED: str = "#FC6255"
349
- MAROON_A: str = "#ECABC1"
350
- MAROON_B: str = "#EC92AB"
351
- MAROON_C: str = "#C55F73"
352
- MAROON_D: str = "#A24D61"
353
- MAROON_E: str = "#94424F"
354
- MAROON: str = "#C55F73"
355
- PURPLE_A: str = "#CAA3E8"
356
- PURPLE_B: str = "#B189C6"
357
- PURPLE_C: str = "#9A72AC"
358
- PURPLE_D: str = "#715582"
359
- PURPLE_E: str = "#644172"
360
- PURPLE: str = "#9A72AC"
361
- PINK: str = "#D147BD"
362
- LIGHT_PINK: str = "#DC75CD"
363
- ORANGE: str = "#FF862F"
364
- LIGHT_BROWN: str = "#CD853F"
365
- DARK_BROWN: str = "#8B4513"
366
- GRAY_BROWN: str = "#736357"
367
- GREY_BROWN: str = "#736357"
368
-
369
- __all__ += [
370
- "WHITE",
371
- "GRAY_A",
372
- "GREY_A",
373
- "GRAY_B",
374
- "GREY_B",
375
- "GRAY_C",
376
- "GREY_C",
377
- "GRAY_D",
378
- "GREY_D",
379
- "GRAY_E",
380
- "GREY_E",
381
- "BLACK",
382
- "LIGHTER_GRAY",
383
- "LIGHTER_GREY",
384
- "LIGHT_GRAY",
385
- "LIGHT_GREY",
386
- "GRAY",
387
- "GREY",
388
- "DARK_GRAY",
389
- "DARK_GREY",
390
- "DARKER_GRAY",
391
- "DARKER_GREY",
392
- "BLUE_A",
393
- "BLUE_B",
394
- "BLUE_C",
395
- "BLUE_D",
396
- "BLUE_E",
397
- "PURE_BLUE",
398
- "BLUE",
399
- "DARK_BLUE",
400
- "TEAL_A",
401
- "TEAL_B",
402
- "TEAL_C",
403
- "TEAL_D",
404
- "TEAL_E",
405
- "TEAL",
406
- "GREEN_A",
407
- "GREEN_B",
408
- "GREEN_C",
409
- "GREEN_D",
410
- "GREEN_E",
411
- "PURE_GREEN",
412
- "GREEN",
413
- "YELLOW_A",
414
- "YELLOW_B",
415
- "YELLOW_C",
416
- "YELLOW_D",
417
- "YELLOW_E",
418
- "YELLOW",
419
- "GOLD_A",
420
- "GOLD_B",
421
- "GOLD_C",
422
- "GOLD_D",
423
- "GOLD_E",
424
- "GOLD",
425
- "RED_A",
426
- "RED_B",
427
- "RED_C",
428
- "RED_D",
429
- "RED_E",
430
- "PURE_RED",
431
- "RED",
432
- "MAROON_A",
433
- "MAROON_B",
434
- "MAROON_C",
435
- "MAROON_D",
436
- "MAROON_E",
437
- "MAROON",
438
- "PURPLE_A",
439
- "PURPLE_B",
440
- "PURPLE_C",
441
- "PURPLE_D",
442
- "PURPLE_E",
443
- "PURPLE",
444
- "PINK",
445
- "LIGHT_PINK",
446
- "ORANGE",
447
- "LIGHT_BROWN",
448
- "DARK_BROWN",
449
- "GRAY_BROWN",
450
- "GREY_BROWN",
451
- ]
452
-
453
-
454
- def color_to_rgb(color: Color | str) -> np.ndarray:
455
- if isinstance(color, str):
456
- return hex_to_rgb(color)
457
- elif isinstance(color, Color):
458
- return np.array(color.get_rgb())
459
- else:
460
- raise ValueError("Invalid color type: " + str(color))
461
-
462
-
463
- def color_to_rgba(color: Color | str, alpha: float = 1) -> np.ndarray:
464
- return np.array([*color_to_rgb(color), alpha])
465
-
466
-
467
- def rgb_to_color(rgb: Iterable[float]) -> Color:
468
- return Color(rgb=rgb)
469
-
470
-
471
- def rgba_to_color(rgba: Iterable[float]) -> Color:
472
- return rgb_to_color(rgba[:3])
473
-
474
-
475
- def rgb_to_hex(rgb: Iterable[float]) -> str:
476
- return "#" + "".join("%02x" % round(255 * x) for x in rgb)
477
-
478
-
479
- def hex_to_rgb(hex_code: str) -> np.ndarray:
480
- hex_part = hex_code[1:]
481
- if len(hex_part) == 3:
482
- hex_part = "".join([2 * c for c in hex_part])
483
- return np.array([int(hex_part[i : i + 2], 16) / 255 for i in range(0, 6, 2)])
484
-
485
-
486
- def invert_color(color: Color) -> Color:
487
- return rgb_to_color(1.0 - color_to_rgb(color))
488
-
489
-
490
- def color_to_int_rgb(color: Color) -> np.ndarray:
491
- return (255 * color_to_rgb(color)).astype("uint8")
492
-
493
-
494
- def color_to_int_rgba(color: Color, opacity: float = 1.0) -> np.ndarray:
495
- alpha_multiplier = np.vectorize(lambda x: int(x * opacity))
496
-
497
- return alpha_multiplier(np.append(color_to_int_rgb(color), 255))
498
-
499
-
500
- def color_gradient(
501
- reference_colors: Iterable[Color],
502
- length_of_output: int,
503
- ) -> list[Color]:
504
- if length_of_output == 0:
505
- return reference_colors[0]
506
- rgbs = list(map(color_to_rgb, reference_colors))
507
- alphas = np.linspace(0, (len(rgbs) - 1), length_of_output)
508
- floors = alphas.astype("int")
509
- alphas_mod1 = alphas % 1
510
- # End edge case
511
- alphas_mod1[-1] = 1
512
- floors[-1] = len(rgbs) - 2
513
- return [
514
- rgb_to_color(interpolate(rgbs[i], rgbs[i + 1], alpha))
515
- for i, alpha in zip(floors, alphas_mod1)
516
- ]
517
-
518
-
519
- def interpolate_color(color1: Color, color2: Color, alpha: float) -> Color:
520
- rgb = interpolate(color_to_rgb(color1), color_to_rgb(color2), alpha)
521
- return rgb_to_color(rgb)
522
-
523
-
524
- def average_color(*colors: Color) -> Color:
525
- rgbs = np.array(list(map(color_to_rgb, colors)))
526
- mean_rgb = np.apply_along_axis(np.mean, 0, rgbs)
527
- return rgb_to_color(mean_rgb)
528
-
529
-
530
- def random_bright_color() -> Color:
531
- color = random_color()
532
- curr_rgb = color_to_rgb(color)
533
- new_rgb = interpolate(curr_rgb, np.ones(len(curr_rgb)), 0.5)
534
- return Color(rgb=new_rgb)
535
-
536
-
537
- def random_color() -> Color:
538
- return random.choice([c.value for c in list(Colors)])
539
-
540
-
541
- def get_shaded_rgb(
542
- rgb: np.ndarray,
543
- point: np.ndarray,
544
- unit_normal_vect: np.ndarray,
545
- light_source: np.ndarray,
546
- ) -> np.ndarray:
547
- to_sun = normalize(light_source - point)
548
- factor = 0.5 * np.dot(unit_normal_vect, to_sun) ** 3
549
- if factor < 0:
550
- factor *= 0.5
551
- result = rgb + factor
552
- return result