├── .github └── workflows │ └── renderer.yml ├── .gitignore ├── LICENSE ├── README.md ├── StudyEx.py ├── StudyManim.py ├── TODO.md ├── Test.py ├── active ├── DataStructure │ ├── Data_structure.pdf │ ├── chapter1.py │ ├── chapter2.py │ ├── chapter3.py │ ├── chapter4.py │ ├── chapter5.py │ ├── chapter6.py │ ├── chapter7.py │ └── 数据结构.pdf ├── FFTsp.py ├── Haskell │ ├── .DS_Store │ ├── Functor_Applicative_Monad.py │ ├── Functor_Applicative_Monad_oldpart.py │ ├── code.hs │ ├── file.txt │ └── text.txt ├── TODO.md ├── brainfuck │ ├── Brainfuck.pdf │ ├── P′′.pdf │ ├── brainfuck.py │ ├── gugugu.bf │ ├── helloworld.bf │ └── part1.py └── ncov.py ├── assets ├── OmegaCreature │ ├── omega_class.py │ ├── omega_creature.py │ ├── omega_creature_animations.py │ └── omega_creature_scene.py ├── fonts │ ├── FZQKBYSJW.TTF │ ├── Monaco_Powerline.otf │ ├── SourceHanSansCN-Bold.otf │ ├── SourceHanSansCN-ExtraLight.otf │ ├── SourceHanSansCN-Heavy.otf │ ├── SourceHanSansCN-Light.otf │ ├── SourceHanSansCN-Medium.otf │ ├── SourceHanSansCN-Normal.otf │ ├── SourceHanSansCN-Regular.otf │ ├── SourceHanSerifCN-Bold.otf │ ├── SourceHanSerifCN-ExtraLight.otf │ ├── SourceHanSerifCN-Heavy.otf │ ├── SourceHanSerifCN-Light.otf │ ├── SourceHanSerifCN-Medium.otf │ ├── SourceHanSerifCN-Regular.otf │ ├── SourceHanSerifCN-SemiBold.otf │ ├── consola.ttf │ ├── consolab.ttf │ ├── consolai.ttf │ └── consolaz.ttf ├── raster_images │ └── title.png └── svg_images │ ├── OmegaCreatures_plain.svg │ ├── __old_OmegaCreatures_plain.svg │ ├── coin.svg │ ├── favo.svg │ ├── good.svg │ └── video_icon.svg ├── graph.py ├── old ├── Bezier │ └── Bezier.py ├── BiliBili_Fourier │ ├── BilibiliFourier.py │ └── FourierOfBilibili.py ├── BinaryIndexedTree │ ├── BIT.py │ ├── Fenwick_tree.pdf │ ├── text.txt │ └── 树状数组.pdf ├── DP │ └── dp_knapsack.py ├── FastFourierTransform │ ├── FFT.py │ ├── FFT1.cpp │ ├── FFT2.cpp │ ├── IFFT.cpp │ ├── Polynomial.cpp │ ├── Rotate_by_complex.py │ ├── help.py │ ├── recordingcpp.cpp │ └── 旁白.txt ├── HomeworkV2.py ├── HomeworkV3.py ├── HowToMakeAVideo │ ├── ArticleCover.png │ ├── How.py │ └── RL0H1%)%~`ODJ]PPM1D91NC.png ├── Lissajous │ └── Lissajous.py ├── ManimTutorial-Color │ └── TeachColor.py ├── Mobius │ └── Mobius.py ├── Others │ ├── Threebody.py │ └── VisualQSort.py ├── PeriodicTable │ ├── PeriodicTable.py │ ├── data │ │ ├── Atomic_radii_of_the_elements_(data_page).pdf │ │ ├── Covalent_radius.pdf │ │ ├── Electronegativities_of_the_elements_(data_page).pdf │ │ ├── Electronegativity.pdf │ │ ├── Molar_ionization_energies_of_the_elements.pdf │ │ ├── 第一电离能.csv │ │ ├── 第三电离能.csv │ │ └── 第二电离能.csv │ └── images │ │ ├── PeriodicTable_2D.png │ │ ├── PeriodicTable_2D_BLACK.png │ │ ├── PeriodicTable_3D.png │ │ ├── PeriodicTable_3D_BLACK.png │ │ ├── PeriodicTable_by_covalent_radius.png │ │ ├── PeriodicTable_by_electronegativity.png │ │ ├── PeriodicTable_by_first_ionization_energy.png │ │ ├── PeriodicTable_by_mass.png │ │ ├── PeriodicTable_by_second_ionization_energy.png │ │ └── PeriodicTable_by_third_ionization_energy.png ├── QSort │ └── QSort.py ├── SandpileModel │ ├── SandpileModel.py │ ├── sand-100w.txt │ ├── sand-1w.txt │ └── sand-50w.txt ├── loading.py ├── logo.py └── rate_funcs.py ├── render.py └── tony_useful ├── Arc_group.py ├── Boxes.py ├── MyText.py ├── RandomAnim.py ├── Subtitle.py ├── Title2.py ├── VideoCover.py ├── VideoStart.py ├── bilibili.py ├── code.py ├── debugTeX.py ├── imports.py └── sector.py /.github/workflows/renderer.yml: -------------------------------------------------------------------------------- 1 | name: Render videos 2 | 3 | on: push 4 | 5 | jobs: 6 | render: 7 | if: "contains(github.event.head_commit.message, '[render]')" 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | 13 | - name: Render videos 14 | uses: manim-kindergarten/manim_action_renderer@master 15 | id: renderer 16 | with: 17 | source_file: render.py 18 | args: "--high_quality" 19 | scene_names: SquareToCircle 20 | # extra_repos: | 21 | # https://github.com/Tony031218/manim_projects 22 | # https://github.com/manim-kindergarten/manim_sandbox 23 | - name: Save output as artifacts 24 | uses: actions/upload-artifact@v2 25 | with: 26 | name: Videos 27 | path: ${{ steps.renderer.outputs.video_path }} 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.pyc 3 | audio/ 4 | *.aux 5 | *.log 6 | *.synctex.gz 7 | # *.tex 8 | *.toc 9 | *.out -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

6 | 7 | [![MIT License](https://img.shields.io/github/license/TonyCrane/manim_projects)](https://choosealicense.com/licenses/apache-2.0/) 8 | [![mk](https://img.shields.io/badge/org-manim__kindergarten-blue)](https://github.com/manim-kindergarten/) 9 | [![manim_sandbox](https://img.shields.io/badge/mk-manim__sandbox-brightgreen.svg)](https://github.com/manim-kindergarten/manim_sandbox/) 10 | [![manim](https://img.shields.io/badge/manim-ver.MK-orange.svg)](https://github.com/manim-kindergarten/manim) 11 | 12 | 运行该项目中的代码需配置好[manim](https://github.com/3b1b/manim)才能运行
13 | 如果想要交流manim的话,欢迎加入QQ群:862671480
14 | [鹤翔万里的b站主页](https://space.bilibili.com/171431343 '求关注求三连ღ( ´・ᴗ・` )') 15 | 16 | 其中一些素材和地址等由于某些文件的移动path可能有点不对,`old`中的文件对应的manim版本较老(需要改改才能运行)
17 | 此外,由于编程水平有限,加上对Grant的代码理解有限,代码有时会出现不太好的实现方式,敬请谅解 18 | 19 | ## 视频地址: 20 | __均投放在B站上__,mk团队稿件没算在内 21 | |视频内容|文件夹名称|视频链接| 22 | |:---|:---:|:---| 23 | |动态规划-01背包问题|DP|[BV1Eb411r7dJ](https://www.bilibili.com/video/BV1Eb411r7dJ)| 24 | |快速排序-演示、优化|QSort|[BV1L4411s7Tv](https://www.bilibili.com/video/BV1L4411s7Tv)| 25 | |傅里叶级数画小电视|BiliBili_Fourier|[BV1U4411X79S](https://www.bilibili.com/video/BV1U4411X79S)| 26 | |莫比乌斯反演|Mobius|[BV1H4411D7qo](https://www.bilibili.com/video/BV1H4411D7qo)| 27 | |树状数组|BinaryIndexedTree|[BV1pE41197Qj](https://www.bilibili.com/video/BV1pE41197Qj)| 28 | |快速傅里叶变换|FastFourierTransform|[BV1Y7411W73U](https://www.bilibili.com/video/BV1Y7411W73U)| 29 | |可视化元素周期表|PeriodicTable|[BV1CE411n7yT](https://www.bilibili.com/video/BV1CE411n7yT)| 30 | |三维利萨茹图形|Lissajous|[BV1WE411x7cV](https://www.bilibili.com/video/BV1WE411x7cV)| 31 | |贝塞尔曲线原理|Bezier|[BV18E411L71V](https://www.bilibili.com/video/BV18E411L71V)| 32 | [更多视频...](https://space.bilibili.com/171431343/video '更多视频等着你哟') 33 | 34 | ## 关于代码使用的相关声明 35 | 本存储库使用Apache-2.0开源协议,希望您能够遵守 36 | 37 | 1. 代码主要用作大家交流学习使用,欢迎大家对齐进行修改和补充 38 | 2. 如果你是B站或其他平台的视频作者,想使用部分代码进行视频创作,默认的情况下都不用征求我的意见(如果使用代码较多请注明下出处) 39 | 3. 禁止直接将该项目中的代码做简单无脑修改甚至不修改而做成视频 40 | 4. 禁止未经允许将本项目的代码用作其他商业行为 41 | 42 | 43 | 最后,祝大家好运ღ( ´・ᴗ・` ) 44 | ---- 45 | 46 | ### 关于up主[鹤翔万里](https://space.bilibili.com/171431343) 47 | 最近忙于学业,github这个库和B站视频都已经停更了
48 | 具体通知在B站专栏 [一期manim视频是如何制作出来的 | 当up主的历程 | 停更通知](https://www.bilibili.com/read/cv4754226)
49 | 谢谢大家对我的支持啦,等我回来哦O(∩_∩)O 50 | 51 | ### 相关链接 52 | - [B站up主:cigar666](https://space.bilibili.com/66806831) 53 | - [cigar666的github](https://github.com/cigar666) 54 | - [manim-kindergarten中整理的一些代码](https://github.com/manim-kindergarten/manim_sandbox 'manim sandbox')
55 | - [mk整理的manim版本](https://github.com/manim-kindergarten/manim) 56 | - [manim中文文档](https://manim.ml/) 57 | - [一个在GitHub服务器上渲染视频的action](https://github.com/manim-kindergarten/manim_action_renderer) -------------------------------------------------------------------------------- /StudyEx.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_projects.tony_useful.imports import * 3 | 4 | class RateFunctions(Scene): 5 | def construct(self): 6 | title = VGroup( 7 | Text("linear", font="Monaco for Powerline").scale(0.5), 8 | Text("smooth", font="Monaco for Powerline").scale(0.5), 9 | Text("rush_into", font="Monaco for Powerline").scale(0.5), 10 | Text("rush_from", font="Monaco for Powerline").scale(0.5), 11 | Text("slow_into", font="Monaco for Powerline").scale(0.5), 12 | Text("double_smooth", font="Monaco for Powerline").scale(0.5), 13 | Text("there_and_back", font="Monaco for Powerline").scale(0.5) 14 | ).arrange_submobjects( 15 | DOWN, aligned_edge=RIGHT, buff=0.55 16 | ).move_to(LEFT*7, aligned_edge=LEFT) 17 | dots = VGroup( 18 | *[ 19 | Dot(color=BLUE).move_to([-2.5, i, 0]) 20 | for i in range(3, -4, -1) 21 | ] 22 | ) 23 | transform_dots = VGroup( 24 | *[ 25 | Dot(color=BLUE).move_to([6, i, 0], aligned_edge=DOWN) 26 | for i in range(3, -4, -1) 27 | ] 28 | ) 29 | self.add(title, dots) 30 | self.wait(2) 31 | self.play(TransformFromCopy(dots[0], transform_dots[0], rate_func=linear)) 32 | self.play(TransformFromCopy(dots[1], transform_dots[1], rate_func=smooth)) 33 | self.play(TransformFromCopy(dots[2], transform_dots[2], rate_func=rush_into)) 34 | self.play(TransformFromCopy(dots[3], transform_dots[3], rate_func=rush_from)) 35 | self.play(TransformFromCopy(dots[4], transform_dots[4], rate_func=slow_into)) 36 | self.play(TransformFromCopy(dots[5], transform_dots[5], rate_func=double_smooth)) 37 | self.play(TransformFromCopy(dots[6], transform_dots[6], rate_func=there_and_back)) 38 | self.wait(2) 39 | self.play( 40 | ReplacementTransform(dots[0], transform_dots[0], rate_func=linear), 41 | ReplacementTransform(dots[1], transform_dots[1], rate_func=smooth), 42 | ReplacementTransform(dots[2], transform_dots[2], rate_func=rush_into), 43 | ReplacementTransform(dots[3], transform_dots[3], rate_func=rush_from), 44 | ReplacementTransform(dots[4], transform_dots[4], rate_func=slow_into), 45 | ReplacementTransform(dots[5], transform_dots[5], rate_func=double_smooth), 46 | ReplacementTransform(dots[6], transform_dots[6], rate_func=there_and_back), 47 | run_time=3 48 | ) 49 | self.wait(2) 50 | 51 | 52 | class RateFunctions2(Scene): 53 | def construct(self): 54 | title = VGroup( 55 | Text("there_and_back_with_pause", font="Monaco for Powerline").scale(0.3), 56 | Text("running_start", font="Monaco for Powerline").scale(0.3), 57 | Text("wiggle", font="Monaco for Powerline").scale(0.3), 58 | Text("lingering", font="Monaco for Powerline").scale(0.3), 59 | Text("exponential_decay", font="Monaco for Powerline").scale(0.3) 60 | ).arrange_submobjects( 61 | DOWN, aligned_edge=RIGHT, buff=0.65 62 | ).move_to(LEFT*7, aligned_edge=LEFT) 63 | dots = VGroup( 64 | *[ 65 | Dot(color=BLUE).move_to([-2, i, 0]) 66 | for i in range(2, -3, -1) 67 | ] 68 | ) 69 | transform_dots = VGroup( 70 | *[ 71 | Dot(color=BLUE).move_to([6, i, 0], aligned_edge=DOWN) 72 | for i in range(2, -3, -1) 73 | ] 74 | ) 75 | self.add(title, dots) 76 | self.wait(2) 77 | self.play( 78 | Transform(dots[0], transform_dots[0], rate_func=there_and_back_with_pause), 79 | Transform(dots[1], transform_dots[1], rate_func=running_start), 80 | Transform(dots[2], transform_dots[2], rate_func=wiggle), 81 | Transform(dots[3], transform_dots[3], rate_func=lingering), 82 | Transform(dots[4], transform_dots[4], rate_func=exponential_decay), 83 | run_time=3 84 | ) 85 | self.wait(2) 86 | 87 | 88 | class RateFunctions3(Scene): 89 | def construct(self): 90 | mover = Dot(color=BLUE).move_to(UR) 91 | targets = [ 92 | Dot(color=BLUE).move_to(DR), 93 | Dot(color=BLUE).move_to(DL), 94 | Dot(color=BLUE).move_to(UL) 95 | ] 96 | self.wait() 97 | self.add(mover) 98 | self.wait(2) 99 | self.play(Succession( 100 | *[ 101 | Transform(mover, target, rate_func=linear) 102 | for target in targets 103 | ], 104 | run_time = 5 105 | )) 106 | self.wait(2) 107 | 108 | 109 | class RotateAndRotating(Scene): 110 | def construct(self): 111 | title = TextMobject("Rotate").scale(2).to_corner(UL) 112 | dot = Dot(color=BLUE).scale(2).move_to(RIGHT * 2.5) 113 | self.wait() 114 | self.play(Write(title), ShowCreation(dot)) 115 | self.wait(2) 116 | self.play(Rotate(dot, 2 * PI, about_point=ORIGIN), run_time=2) 117 | self.wait(2) 118 | title2 = TextMobject("Rotating").scale(2).to_corner(UL) 119 | self.play(Transform(title, title2)) 120 | self.wait(2) 121 | self.play(Rotating(dot, about_point=ORIGIN), run_time=2) 122 | self.wait(2) 123 | title3 = TextMobject("Rotate", "(rate\_func=linear)").scale(2).to_corner(UL) 124 | title3[1].scale(0.4).next_to(title3[0], RIGHT, aligned_edge=DOWN) 125 | self.play(Transform(title, title3)) 126 | self.wait(2) 127 | self.play(Rotate(dot, 2 * PI, about_point=ORIGIN, rate_func=linear), run_time=2) 128 | self.wait(3) 129 | 130 | 131 | class Changing(Scene): 132 | def construct(self): 133 | sq = Square() 134 | test = AnimatedBoundary(sq) 135 | self.add(sq, test) 136 | self.wait(10) 137 | self.remove(sq, test) 138 | self.wait(2) 139 | point = Dot(color=BLUE) 140 | point.move_to(RIGHT*3) 141 | point.add_updater(lambda m, dt: m.rotate(dt * 20 * DEGREES, about_point=ORIGIN)) 142 | test2 = TracedPath(point.get_center, stroke_width=4, stroke_color=RED) 143 | angle = Angle(RIGHT * 3, ORIGIN, point.get_center()) 144 | angle.add_updater(lambda m: m.become(Angle(RIGHT * 3, ORIGIN, point.get_center()))) 145 | line1 = Line(ORIGIN, RIGHT * 3) 146 | line2 = Line(ORIGIN, point.get_center()) 147 | line2.add_updater(lambda m: m.put_start_and_end_on(ORIGIN, point.get_center())) 148 | degree = DecimalNumber(0, edge_to_fix=RIGHT).scale(2).to_corner(UR) 149 | degree.add_updater(lambda m: m.set_value(line2.get_angle() * 180 / PI)) 150 | self.add(test2, angle, degree, line1, line2) 151 | self.add(point) 152 | self.wait(9.19) 153 | 154 | 155 | class ParaFunction(Scene): 156 | def construct(self): 157 | grid = NumberPlane() 158 | grid.add_coordinates() 159 | func1 = ParametricFunction( 160 | lambda t: [t - 1, t, 0], 161 | t_min = -7, 162 | t_max = 7, 163 | color = RED 164 | ) 165 | func2 = ParametricFunction( 166 | lambda t: [4 * np.cos(t), 2 * np.sin(t), 0], 167 | t_min = 0, 168 | t_max = 2 * PI, 169 | color = ORANGE 170 | ) 171 | points2 = func2.points 172 | points3 = [] 173 | for point in points2: 174 | d = abs(point[0] - point[1] + 1) / np.sqrt(2) 175 | if d < 0.005: 176 | points3.append(point) 177 | for point in points3: 178 | self.add(Dot(point)) 179 | self.add(grid, func1, func2) 180 | 181 | 182 | class AlwaysMove(Scene): 183 | def construct(self): 184 | text = VGroup( 185 | Text("cigar666", font="Source Han Sans CN").scale(0.5), 186 | Text("pdcxs", font="Source Han Sans CN").scale(0.5), 187 | Text("鹤翔万里", font="Source Han Sans CN").scale(0.5), 188 | Text("有一种悲伤叫颓废", font="Source Han Sans CN").scale(0.5), 189 | ).arrange(DOWN, aligned_edge=LEFT) 190 | self.add(text) 191 | always_shift(text, UP, 0.5) 192 | self.wait(5) 193 | 194 | 195 | class TryThreeD(ThreeDScene): 196 | def construct(self): 197 | self.set_camera_orientation(phi=30 * DEGREES, theta=PI / 3) 198 | cube = Cube() 199 | self.add(cube) 200 | 201 | 202 | class SurfacesAnimation(ThreeDScene): 203 | def construct(self): 204 | axes = ThreeDAxes() 205 | cylinder = ParametricSurface( 206 | lambda u, v: np.array([ 207 | np.cos(TAU * v), 208 | np.sin(TAU * v), 209 | 2 * (1 - u) 210 | ]), 211 | resolution=(6, 32)).fade(0.5) #Resolution of the surfaces 212 | 213 | paraboloid = ParametricSurface( 214 | lambda u, v: np.array([ 215 | np.cos(v)*u, 216 | np.sin(v)*u, 217 | u**2 218 | ]),v_max=TAU, 219 | checkerboard_colors=[PURPLE_D, PURPLE_E], 220 | resolution=(10, 32)).scale(2) 221 | 222 | para_hyp = ParametricSurface( 223 | lambda u, v: np.array([ 224 | u, 225 | v, 226 | u**2-v**2 227 | ]),v_min=-2,v_max=2,u_min=-2,u_max=2,checkerboard_colors=[BLUE_D, BLUE_E], 228 | resolution=(15, 32)).scale(1) 229 | 230 | cone = ParametricSurface( 231 | lambda u, v: np.array([ 232 | u*np.cos(v), 233 | u*np.sin(v), 234 | u 235 | ]),v_min=0,v_max=TAU,u_min=-2,u_max=2,checkerboard_colors=[GREEN_D, GREEN_E], 236 | resolution=(15, 32)).scale(1) 237 | 238 | hip_one_side = ParametricSurface( 239 | lambda u, v: np.array([ 240 | np.cosh(u)*np.cos(v), 241 | np.cosh(u)*np.sin(v), 242 | np.sinh(u) 243 | ]),v_min=0,v_max=TAU,u_min=-2,u_max=2,checkerboard_colors=[YELLOW_D, YELLOW_E], 244 | resolution=(15, 32)) 245 | 246 | ellipsoid=ParametricSurface( 247 | lambda u, v: np.array([ 248 | 1*np.cos(u)*np.cos(v), 249 | 2*np.cos(u)*np.sin(v), 250 | 0.5*np.sin(u) 251 | ]),v_min=0,v_max=TAU,u_min=-PI/2,u_max=PI/2,checkerboard_colors=[TEAL_D, TEAL_E], 252 | resolution=(15, 32)).scale(2) 253 | 254 | sphere = ParametricSurface( 255 | lambda u, v: np.array([ 256 | 1.5*np.cos(u)*np.cos(v), 257 | 1.5*np.cos(u)*np.sin(v), 258 | 1.5*np.sin(u) 259 | ]),v_min=0,v_max=TAU,u_min=-PI/2,u_max=PI/2,checkerboard_colors=[RED_D, RED_E], 260 | resolution=(15, 32)).scale(2) 261 | 262 | 263 | self.set_camera_orientation(phi=75 * DEGREES) 264 | self.begin_ambient_camera_rotation(rate=0.2) 265 | 266 | 267 | self.add(axes) 268 | self.play(Write(sphere)) 269 | self.wait() 270 | self.play(ReplacementTransform(sphere,ellipsoid)) 271 | self.wait() 272 | self.play(ReplacementTransform(ellipsoid,cone)) 273 | self.wait() 274 | self.play(ReplacementTransform(cone,hip_one_side)) 275 | self.wait() 276 | self.play(ReplacementTransform(hip_one_side,para_hyp)) 277 | self.wait() 278 | self.play(ReplacementTransform(para_hyp,paraboloid)) 279 | self.wait() 280 | self.play(ReplacementTransform(paraboloid,cylinder)) 281 | self.wait() 282 | self.play(FadeOut(cylinder)) 283 | 284 | 285 | class MoveCamera(ThreeDScene): 286 | def construct(self): 287 | axes = ThreeDAxes() 288 | circle=Circle() 289 | self.set_camera_orientation(phi=80 * DEGREES) 290 | self.play(ShowCreation(circle),ShowCreation(axes)) 291 | #Start move camera 292 | self.begin_ambient_camera_rotation(rate=0.1) 293 | self.wait(5) 294 | #Stop move camera 295 | self.stop_ambient_camera_rotation() 296 | #Return the position of the camera 297 | self.move_camera(phi=80*DEGREES,theta=-PI/2) 298 | self.wait() 299 | 300 | 301 | -------------------------------------------------------------------------------- /StudyManim.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : StudyManim.py 3 | > Author : Tony 4 | > Created Time : 2019/01/26 16:19:55 5 | ''' 6 | 7 | from manimlib.imports import * 8 | from manim_projects.tony_useful.imports import * 9 | 10 | class Polygon(Scene): 11 | def construct(self): 12 | circle = Circle(radius=2.0) 13 | square = Square() 14 | 15 | self.play(ShowCreation(circle)) 16 | self.play(Transform(circle, square)) 17 | self.play(FadeOut(square)) 18 | 19 | class TextTransform(Scene): 20 | def construct(self): 21 | text = TextMobject( 22 | "this is a text", 23 | tex_to_color_map={"text": YELLOW} 24 | ) 25 | trans_text = TextMobject( 26 | "this is another text", 27 | tex_to_color_map={"text": RED} 28 | ) 29 | self.play(Write(text)) 30 | self.play(Transform(text, trans_text)) 31 | self.wait() 32 | 33 | class TexTransform(Scene): 34 | def construct(self): 35 | tex = TexMobject( 36 | "\\sum_{n=1010a}^\\infty " 37 | "\\frac{1}{n^2} = \\frac{\\tau^2}{6}" 38 | ) 39 | trans_tex = TexMobject( 40 | "\\sum_{n=1}^\\infty " 41 | "\\frac{1}{n^2} = \\frac{\\pi^2}{6}" 42 | ) 43 | self.play(Write(tex)) 44 | self.play(Transform(tex, trans_tex)) 45 | self.wait() 46 | 47 | class MoveText(Scene): 48 | def construct(self): 49 | title = TextMobject( 50 | "Tony is trying manim", 51 | tex_to_color_map={"manim": RED} 52 | ) 53 | trans_title = TextMobject( 54 | "Tony is learning manim", 55 | tex_to_color_map={"manim": YELLOW} 56 | ) 57 | trans_title.to_corner(UP) 58 | transform_title = TextMobject( 59 | "Tony is learning manim", 60 | tex_to_color_map={"manim": ORANGE} 61 | ) 62 | transform_title.to_corner(UP + LEFT) 63 | 64 | self.play(Write(title)) 65 | self.play(Transform(title, trans_title)) 66 | self.wait() 67 | self.play(Transform(title, transform_title)) 68 | self.wait() 69 | 70 | class GaussLaw(Scene): 71 | def construct(self): 72 | example_text = TextMobject( 73 | "Gauss's Law 高斯定理", 74 | tex_to_color_map={"Law": RED} 75 | ) 76 | example_tex = TexMobject( 77 | "\\def\\ooint{{\\bigcirc}\\kern-12.5pt{\\int}\\kern-6.5pt{\\int}}" 78 | "\\ooint_S{E\\cdot dS} = {1\\over{\\epsilon_0}}\\times{{\\int}\\kern-6.5pt{\\int}\\kern-6.5pt{\\int}_V{\\rho \\cdot dV}}", 79 | ) 80 | group = VGroup(example_text, example_tex) 81 | group.arrange_submobjects(DOWN) 82 | group.set_width(FRAME_WIDTH - 2 * LARGE_BUFF) 83 | 84 | self.play(Write(example_text)) 85 | self.play(Write(example_tex)) 86 | self.wait() 87 | 88 | class PrintAuthor(Scene): 89 | def construct(self): 90 | author = TextMobject( 91 | "@Tony鹤翔万里", 92 | tex_to_color_map={"@Tony鹤翔万里": [BLUE, YELLOW, ORANGE, RED]} 93 | ) 94 | author.scale(1.5) 95 | author.to_corner(LEFT + DOWN) 96 | self.add(author) 97 | 98 | class NumberPlaneTest(Scene): 99 | def construct(self): 100 | grid = NumberPlane() 101 | grid_title = TextMobject("空间坐标系") 102 | grid_title.scale(1.5) 103 | grid_title.to_corner(UP) 104 | 105 | self.play( 106 | Write(grid), 107 | FadeInFromDown(grid_title), 108 | ) 109 | self.wait() 110 | grid_transform_title = TextMobject("放大") 111 | grid_transform_title.to_corner(UP) 112 | grid_transform_title.scale(1.5) 113 | grid.prepare_for_nonlinear_transform() 114 | self.play( 115 | Transform(grid_title, grid_transform_title), 116 | grid.apply_function, 117 | lambda p: p * np.array([ 2, 2, 0, ]), 118 | run_time=3, 119 | ) 120 | self.wait() 121 | grid.prepare_for_nonlinear_transform() 122 | grid_transform_title = TextMobject("平移") 123 | grid_transform_title.to_corner(UP) 124 | grid_transform_title.scale(1.5) 125 | self.play( 126 | Transform(grid_title, grid_transform_title), 127 | grid.apply_function, 128 | lambda p: p + np.array([2, 1, 0, ]), 129 | run_time=3, 130 | ) 131 | self.wait() 132 | grid.prepare_for_nonlinear_transform() 133 | grid_transform_title = TextMobject("线性变换") 134 | grid_transform_title.to_corner(UP) 135 | grid_transform_title.scale(1.5) 136 | self.play( 137 | Transform(grid_title, grid_transform_title), 138 | grid.apply_function, 139 | lambda p: p + np.array([ p[1] , 0, 0,]), 140 | run_time=3, 141 | ) 142 | self.wait() 143 | grid.prepare_for_nonlinear_transform() 144 | grid_transform_title = TextMobject("非线性变换") 145 | grid_transform_title.to_corner(UP) 146 | grid_transform_title.scale(1.5) 147 | self.play( 148 | Transform(grid_title, grid_transform_title), 149 | grid.apply_function, 150 | lambda p: p + np.array([ np.sin(p[1]) , np.sin(p[0]) , 0,]), 151 | run_time=3, 152 | ) 153 | 154 | class VideoStart(Scene): 155 | CONFIG = { 156 | "Author" : "@鹤翔万里", 157 | "title_name" : "测试", 158 | "svg_filename" : "TonySVG", 159 | "author_colors" : [BLUE, YELLOW, ORANGE, RED], 160 | } 161 | def construct(self): 162 | author = TextMobject( 163 | self.Author, 164 | tex_to_color_map={self.Author : self.author_colors} 165 | ) 166 | svg_file = SVGMobject(file_name = self.svg_filename) 167 | svg_file.to_corner(UP) 168 | 169 | title = TextMobject(self.title_name) 170 | title.to_corner((BOTTOM + ORIGIN)) 171 | self.play( 172 | FadeInFromDown(svg_file), 173 | Write(author) 174 | ) 175 | self.play( 176 | Write(title) 177 | ) 178 | self.wait() 179 | self.play( 180 | LaggedStart(FadeOutAndShiftDown, author), 181 | FadeOut(title), 182 | run_time = 0.5, 183 | ) 184 | 185 | class TrySurroundingRectangle(Scene): 186 | def construct(self): 187 | text = TextMobject( 188 | "Here is a ", "text", 189 | ) 190 | text.to_edge(TOP) 191 | text_rect = SurroundingRectangle(text[1]) 192 | another_text = TextMobject( 193 | "That ", "text", " is created by Tony" 194 | ) 195 | another_text_rect = SurroundingRectangle(another_text[1]) 196 | text_arrow = Arrow( 197 | another_text[1].get_top(), text[1].get_bottom(), 198 | tip_length = 0.1 199 | ) 200 | 201 | trans_text_1 = TextMobject("TEXT", tex_to_color_map={"TEXT": BLUE}) 202 | trans_text_2 = TextMobject("TEXT", tex_to_color_map={"TEXT": BLUE}) 203 | trans_text_1.move_to(text[1]) 204 | trans_text_2.move_to(another_text[1]) 205 | 206 | self.play(Write(text)) 207 | self.play(ShowCreation(text_rect)) 208 | self.wait() 209 | self.play(Write(another_text), run_time=1) 210 | self.play(ShowCreation(another_text_rect)) 211 | self.play(ShowCreation(text_arrow), run_time=1.5) 212 | self.wait() 213 | self.play( 214 | Transform(text[1], trans_text_1), 215 | Transform(another_text[1], trans_text_2) 216 | ) 217 | self.wait() 218 | 219 | class TryMatrix(Scene): 220 | def construct(self): 221 | matrix = Matrix( 222 | [["0", 0, 0, 1, 0, 1, 0, 1], 223 | [1, 0, 1, 1, 0, 1, 0, 1], 224 | [1, 1, 0, 0, 1, 0, 1, 0]] 225 | ) 226 | self.play(Write(matrix), run_time = 3) 227 | trans = TextMobject("1").move_to(matrix[0][9]) 228 | self.play( 229 | Transform(matrix[0][9], trans) 230 | ) 231 | self.wait() 232 | 233 | class TransformPartOfTex(Scene): 234 | def construct(self): 235 | gauss = TexMobject( 236 | "\\def\\ooint{{\\bigcirc}\\kern-12.5pt{\\int}\\kern-6.5pt{\\int}}" 237 | "\\ooint_S{E\\cdot dS} = {1\\over{\\epsilon_0}}\\times{{\\int}\\kern-6.5pt{\\int}\\kern-6.5pt{\\int}", "_{Sh}", "{\\rho \\cdot dV}}", 238 | ) 239 | self.play(Write(gauss)) 240 | trans_tex = TexMobject("_{V}") 241 | trans_tex.move_to(gauss[1]) 242 | self.play( 243 | Transform(gauss[1], trans_tex) 244 | ) 245 | self.wait() 246 | text = TextMobject("V", tex_to_color_map={"V": BLUE}) 247 | text.next_to(gauss[1], direction=UP, buff=2) 248 | self.play( 249 | Transform(trans_tex, text) 250 | ) 251 | text_rect = SurroundingRectangle(text) 252 | self.play(ShowCreation(text_rect)) 253 | self.wait() 254 | 255 | class TryVideoSeries(Scene): 256 | def construct(self): 257 | series = VideoSeries(num_videos=6) 258 | series.scale(0.8) 259 | series.arrange_submobjects(RIGHT, aligned_edge=LEFT, buff=1.6) 260 | series.to_edge(UP, buff=1) 261 | this_video = series[0] 262 | this_video.set_color(YELLOW) 263 | this_video.save_state() 264 | this_video.set_fill(opacity = 0) 265 | this_video.center() 266 | this_video.set_height(FRAME_HEIGHT) 267 | 268 | self.play( 269 | FadeIn( 270 | series, 271 | lag_ratio = 0.5, 272 | run_time = 2 273 | ) 274 | ) 275 | self.wait() 276 | self.play( 277 | this_video.restore, run_time=3 278 | ) 279 | self.wait(2) 280 | 281 | class TryOmega(Scene): 282 | def construct(self): 283 | omega = SVGMobject("OmegaCreatures_plain") 284 | omega.set_width(3).set_color(BLUE) 285 | self.add(omega) 286 | 287 | class TryOmegaCreature(TeacherStudentsScene): 288 | def construct(self): 289 | self.student_says( 290 | "尝试一下$\omega$酱", 291 | run_time = 2 292 | ) 293 | # self.play(self.get_teacher().change_mode, "happy") 294 | self.wait() 295 | self.teacher_says( 296 | "还可以吧 \\\\", 297 | "虽然没有$\pi$酱好看", 298 | # target_mode = "well" 299 | ) 300 | self.wait() 301 | 302 | class TryFont(Scene): 303 | def construct(self): 304 | # text = Text("test fonts", font='Consolas').shift(UP*2) 305 | # text2 = Text("test blanks", font='Consolas').next_to(text, DOWN) 306 | # text3 = Text("test \n test", font='Consolas').next_to(text2, DOWN) 307 | text = Text( 308 | "line1\n" 309 | "line3", 310 | font='Consolas' 311 | ) 312 | self.add(text) 313 | 314 | class TryCode(Scene): 315 | def construct(self): 316 | code = Code( 317 | "#include ", 318 | "using namespace std; ", 319 | ) 320 | self.play(Write(code)) 321 | 322 | class TryLinedCode(Scene): 323 | def construct(self): 324 | code = LinedCode( 325 | "#include ", 326 | "using namespace std;", 327 | "", 328 | "int main() {", 329 | " printf(\"Hello World\\n\");", 330 | " return 1;", 331 | "}", 332 | t2c={ 333 | '#include <' : BLUE, 334 | '>' : BLUE, 335 | 'std' : YELLOW, 336 | 'bits/stdc++.h' : GREEN, 337 | 'using' : ORANGE, 338 | 'namespace' : PURPLE, 339 | ';' : BLUE, 340 | 'for' : BLUE, 341 | 'if' : BLUE, 342 | 'int' : PURPLE, 343 | '(' : BLUE, 344 | ')' : BLUE, 345 | '{' : BLUE, 346 | '}' : BLUE, 347 | 'return' : BLUE, 348 | '0' : ORANGE, 349 | 'main' : '#214FB7', 350 | 'printf' : '#214FB7', 351 | '\"' : BLUE, 352 | 'Hello World' : GREEN, 353 | '\\n' : BLUE, 354 | } 355 | ) 356 | self.play(Write(code)) 357 | 358 | class TryNumberPlane(Scene): 359 | def construct(self): 360 | grid = ComplexPlane().add_coordinates() 361 | self.add(grid) 362 | 363 | class TryText(Scene): 364 | def construct(self): 365 | text = Text("0100101101", font="Consolas").scale(0.8) 366 | self.add(text) 367 | debugTeX(self, text) -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | - [ ] __学习、高考__ 2 |
3 |
4 |
5 | 6 | - [x] 调试`Code`,`LinedCode`类 7 | - [x] 试运行单位根相关场景 8 | - [x] 快速傅里叶变换 9 | - [x] 尝试三维 10 | - [ ] 调试`Graph`类 11 |
12 | 13 | - [ ] 数据结构系列 -------------------------------------------------------------------------------- /active/DataStructure/Data_structure.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/active/DataStructure/Data_structure.pdf -------------------------------------------------------------------------------- /active/DataStructure/chapter1.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter1.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:11:47 5 | > Content : 数据结构简介及视频索引 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/chapter2.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter2.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:12:59 5 | > Content : 基础数据结构(栈,队列,链表) 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/chapter3.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter3.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:13:36 5 | > Content : ST表 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/chapter5.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter5.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:14:05 5 | > Content : 线段树 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/chapter6.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter6.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:14:21 5 | > Content : 分块 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/chapter7.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : chapter7.py 3 | > Author : Tony 4 | > Created Time : 2019/10/15 17:12:40 5 | > Content : 并查集 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /active/DataStructure/数据结构.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/active/DataStructure/数据结构.pdf -------------------------------------------------------------------------------- /active/FFTsp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : FFTsp.py 3 | > Author : Tony_Wong 4 | > Created Time : 2020/02/12 11:31:49 5 | ''' 6 | 7 | from manimlib.imports import * 8 | from manim_projects.tony_useful.imports import * 9 | 10 | class VideoTitle(VideoStart): 11 | CONFIG = { 12 | "title_name": "三次变两次优化 多项式乘法", 13 | } 14 | 15 | 16 | class VideoCover(Scene): 17 | def construct(self): 18 | pass 19 | 20 | 21 | class ThreeTimesFFT(Scene): 22 | def construct(self): 23 | title = Text("多项式乘法(卷积)", font="Source Han Sans CN", t2c={"多项式乘法": BLUE, "(卷积)": YELLOW}) 24 | title.scale(0.6).to_corner(UL) 25 | self.wait() 26 | self.play(Write(title)) 27 | self.wait() -------------------------------------------------------------------------------- /active/Haskell/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/active/Haskell/.DS_Store -------------------------------------------------------------------------------- /active/Haskell/Functor_Applicative_Monad_oldpart.py: -------------------------------------------------------------------------------- 1 | from manimlib_cairo.imports import * 2 | 3 | class Logo(VGroup): 4 | 5 | CONFIG = { 6 | 'color_1': [WHITE, BLUE_B, BLUE_D], 7 | 'color_2': [WHITE, '#C59978', '#8D5630'], 8 | 9 | # 'color_3': [average_color("#CCCCCC", BLUE_C), BLUE_C, BLUE_D], 10 | # 'color_4': [average_color("#CCCCCC", "#C59978"), '#C59978', '#8D5630'], 11 | 12 | 'color_3': [average_color(WHITE, BLUE_C), BLUE_C, BLUE_D], 13 | 'color_4': [average_color(WHITE, "#C59978"), '#C59978', '#8D5630'], 14 | 15 | 'center': ORIGIN, 16 | 'size': 2, 17 | 'shift_out': ORIGIN, 18 | 'black_bg': True, 19 | 'add_bg_square': False, 20 | } 21 | 22 | def __init__(self, **kwargs): 23 | VGroup.__init__(self, **kwargs) 24 | self.create_logo() 25 | 26 | def create_logo(self): 27 | 28 | p1 = Polygon(ORIGIN, RIGHT, 2 * UP, stroke_width=0).set_fill(self.color_1[0], 1) 29 | p2 = Polygon(1.5 * RIGHT, 3 * UR, 3 * UP, stroke_width=0).set_fill(self.color_1[1], 1) 30 | p3 = Polygon(2 * RIGHT, 3 * RIGHT, 3 * RIGHT + 2 * UP, stroke_width=0).set_fill(self.color_1[2], 1) 31 | if not self.black_bg: 32 | p1.set_fill(self.color_3[0], 1), p2.set_fill(self.color_3[1], 1), p3.set_fill(self.color_3[2], 1) 33 | 34 | self.bg = Square(stroke_width=0, fill_color=BLACK if self.black_bg else WHITE, fill_opacity=1).set_height(self.size * 2.5) 35 | if self.add_bg_square: 36 | self.add(self.bg) 37 | 38 | self.part_ur = VGroup(p1, p2, p3).move_to([2.5, 1., 0] + self.shift_out) 39 | self.part_ul = self.part_ur.copy().rotate(PI / 2, about_point=ORIGIN) 40 | self.part_dl = self.part_ur.copy().rotate(PI, about_point=ORIGIN) 41 | self.part_dr = self.part_ur.copy().rotate(3 * PI / 2, about_point=ORIGIN) 42 | 43 | self.add(self.part_ur, self.part_ul, self.part_dl, self.part_dr) 44 | self.set_height(self.size).move_to(self.center) 45 | if self.black_bg: 46 | self.part_ur[0].set_fill(self.color_2[0], 1), self.part_ur[1].set_fill(self.color_2[1], 1), self.part_ur[2].set_fill(self.color_2[2], 1) 47 | else: 48 | self.part_ur[0].set_fill(self.color_4[0], 1), self.part_ur[1].set_fill(self.color_4[1], 1), self.part_ur[2].set_fill(self.color_4[2], 1) 49 | 50 | self.inner_triangles = VGroup(self.part_ur[0], self.part_ul[0], self.part_dl[0], self.part_dr[0]) 51 | self.mid_triangles = VGroup(self.part_ur[1], self.part_ul[1], self.part_dl[1], self.part_dr[1]) 52 | self.outer_triangles = VGroup(self.part_ur[2], self.part_ul[2], self.part_dl[2], self.part_dr[2]) 53 | 54 | 55 | class OpeningScene(Scene): 56 | CONFIG = { 57 | "camera_config": { 58 | "background_color": "#333333", 59 | }, 60 | "enable_caching": False, 61 | } 62 | 63 | def construct(self): 64 | logo = Logo(size=8/3) 65 | squares = VGroup(*[Polygon(ORIGIN, UR, UL), Polygon(ORIGIN, UL, DL), Polygon(ORIGIN, DL, DR), Polygon(ORIGIN, DR, UR),]) 66 | squares.set_fill(WHITE, 1).set_stroke(width=0.5, color=WHITE).rotate(np.arctan(0.5)).set_height(logo.inner_triangles.get_height()) 67 | for s in squares: 68 | s.scale(0.8) 69 | 70 | img = ImageMobject("Tony.png").set_height(2) 71 | Group(logo, img).arrange(RIGHT, buff=1.5).center() 72 | line = Line(UP, DOWN, stroke_width=8, color=WHITE).move_to(mid(logo.get_right(), img.get_left())) 73 | line.set_length(1.4) 74 | text = VGroup( 75 | Text("Manim-Kindergarten", font="Orbitron bold", color=GREY_B), 76 | Text("鹤翔万里", font="PangMenZhengDao", color=WHITE, size=2.2) 77 | ).arrange(DOWN, aligned_edge=LEFT, buff=0.1).next_to(img, buff=0.5) 78 | text[0][0].set_color(logo.color_2[2]) 79 | text[0][6].set_color(logo.color_1[2]) 80 | all_logo = Group(logo, text, line, img).center() 81 | text = Group(text, line, img) 82 | 83 | bg = Rectangle(height=10, width=10, fill_color="#333333", fill_opacity=1, stroke_width=0) 84 | bg.add_updater(lambda m: m.move_to(logo, aligned_edge=RIGHT).shift(RIGHT*0.2)) 85 | 86 | text.save_state() 87 | text.shift((text.get_right()[0]-bg.get_right()[0]+0.2)*LEFT) 88 | logo.save_state() 89 | logo.move_to(ORIGIN) 90 | logo.scale(1.5) 91 | 92 | tris = logo.inner_triangles.copy().rotate(-PI) 93 | self.add(text, bg) 94 | 95 | self.wait(0.3) 96 | self.add(tris) 97 | self.wait(0.3) 98 | self.remove(tris) 99 | 100 | self.wait(0.2) 101 | self.add(tris) 102 | self.wait(0.15) 103 | self.remove(tris) 104 | 105 | self.wait(0.1) 106 | self.add(tris) 107 | self.wait(0.1) 108 | self.remove(tris) 109 | 110 | self.wait(0.075) 111 | self.add(tris) 112 | self.wait(0.075) 113 | self.remove(tris) 114 | 115 | self.wait(0.05) 116 | self.add(tris) 117 | self.wait(0.05) 118 | self.remove(tris) 119 | # square = Square().set_height(tris.get_height()).set_stroke(width=0.5, color=WHITE) 120 | # self.play(ReplacementTransform(square, tris), run_time=1) 121 | self.wait(0.2) 122 | self.play(ShowSubmobjectsOneByOne(tris), rate_func=linear, run_time=0.4) 123 | for i in tris: 124 | self.add(i) 125 | self.wait(0.1) 126 | self.play(*[ReplacementTransform(tris[i], squares[i]) for i in range(4)], 127 | rate_func=rush_from, run_time=0.6) 128 | #self.play(ReplacementTransform(tris, squares), rate_func=linear, run_time=0.8) 129 | self.wait(0.1) 130 | self.play(*[ReplacementTransform(squares[i], logo[i]) for i in range(4)], 131 | rate_func=rush_from, run_time=0.6) 132 | #self.play(ReplacementTransform(squares, logo), rate_func=linear, run_time=1.5) 133 | self.wait(0.1) 134 | self.play( 135 | text.restore, logo.restore, 136 | rate_func=rush_from, run_time=0.8 137 | ) 138 | self.wait(1) 139 | self.remove(bg) 140 | self.play(FadeOut(Group(*self.mobjects))) -------------------------------------------------------------------------------- /active/Haskell/code.hs: -------------------------------------------------------------------------------- 1 | main = do 2 | putStrLn "" 3 | getLine >>= readFile >>= putStrLn 4 | putStrLn "" -------------------------------------------------------------------------------- /active/Haskell/file.txt: -------------------------------------------------------------------------------- 1 | Here is the content of the file: file.txt 2 | This is the second line 3 | DZTBSC 4 | _(:з」∠)_ -------------------------------------------------------------------------------- /active/Haskell/text.txt: -------------------------------------------------------------------------------- 1 | 「直观理解Haskell中的Functor、Applicative与Monad」 2 | 3 | 从范畴论而来的Functor、Applicative与Monad等类型类一直是Haskell学习中的重点与难点 4 | 这期视频就从一个不太学术、不太严谨的角度来直观理解一下Haskell中的函子等类型类的作用 5 | 画面: 6 | 本期视频只是一个试验性视频 7 | 面向人群: 8 | 有一点Haskell基础 9 | 且对于Functor等概念感到困惑 10 | 如果效果好的话,可以考虑做一系列Haskell入门的视频(挖坑) 11 | 12 | 首先来回顾一下Haskell中的函数与几个类型 13 | Haskell中的函数都是柯里化的,也就是说,它们都可以看成接收一个值返回另一个值的函数,返回的值也可以是函数 14 | 比如二元函数(+),在接受了参数1后会返回一个新的函数(+1),而函数(+1)接收了参数2后会返回一个值3 15 | 而且函数的接收值和返回值也可以是不同的类型,比如show函数,接收一个Show的实例,返回一个字符串 16 | 所以函数f接收x,返回f(x),它的类型签名也就可以写成a -> b 17 | 18 | 再回顾一下Maybe、[]、IO等类型构造器,它们都是接收一个类型,返回一个新的具体类型 19 | 比如Just 1就是一个Maybe Int类型的值 20 | Just也可以看成接收一个值,然后把这个值放在了一个盒子里,Just 1就相当于把1放在了一个盒子里 21 | Nothing也可以看成一个Maybe Int类型的值,它相当于一个什么都没放的空盒子 22 | 如果把Maybe这个类型构造器的类型签名写成f,那么Just 1等这种装着值的盒子的类型签名就可以写成f a 23 | 24 | 但是这是如果我们有一个函数,和一个盒子,怎么将这个函数应用在这个盒子中的值上? 25 | 这个函数的输入是一个值,它并不能接收一个盒子,因此也就不能直接将这个函数应用在盒子上 26 | 但是Functor的fmap函数就可以很方便地帮我们达到这一个需要 27 | 前面说到的那些可以看作盒子的类型构造器就是函子(Functor)的实例 28 | fmap接收一个函数,和一个装在盒子里的值,它将函数应用在盒子中的值上,并返回包含结果的盒子 29 | 所以对于这个操作,可以看作,将盒子中的值1取了出来,然后传入给了函数(+3),返回了4,又装进了盒子中 30 | 而且对于列表这种会包含很多值的盒子,fmap也会将盒子中的值逐一取出,传入给函数,然后逐一放回盒子 31 | 再来看如果传入的是一个空盒子呢,比如Nothing 32 | 这时无法从盒子中取出值,也就不会应用函数,从而直接返回了一个空盒子 33 | 对于后面要讲的也一样,只要有盒子是空的,那么就都会直接返回空盒子 34 | 35 | 但是如果我们不小心将一个二元函数作为第一个参数传入给了fmap,那么得到的结果就会是装在盒子中的函数 36 | 所以现在问题又来了:怎么将一个装在盒子里的函数应用在装在盒子中的值上? 37 | 装有盒子的函数本质上还是一个盒子,它不可能直接接收一个值或者一个装有值的盒子 38 | 因此fmap已经无法达到这个需求,这时就需要应用函子(Applicative)的apply(<*>)函数 39 | 此时看作盒子的类型构造器上升成为了应用函子 40 | apply函数接收一个装有函数的盒子,和一个装有值的盒子,将函数和值全部取出,应用后再把返回的结果放回盒子中 41 | 对于这个例子,盒子中的(+3)函数被取了出来,然后第二个盒子中的值1也被取了出来,应用后得到结果4,又装回了盒子中 42 | 对于列表,盒子中也会装着多个函数,这是就会先取出第一个函数,然后应用在第二个盒子的所有值上,再去第二个函数,应用在第二个盒子的所有值上 43 | 最后将得到的所有结果平铺着装到盒子中 44 | 45 | 但是如果我们的要求更刁钻一点,给出的函数是接收一个普通的值,返回一个盒子的函数 46 | 怎么将这个函数应用在一个盒子上,并得到一个单独的盒子? 47 | 如果是使用fmap将这个函数应用在盒子上,那么得到的结果将会是套有两层盒子的值 48 | 并且我们也没有一个单独的去掉一层盒子的函数 49 | 这时就需要了单子(Monad)的bind(>>=)函数,可以使用bind函数的盒子也就升级为了单子 50 | 和我们的需求一样,但是和fmap以及apply的方向相反,它先接收一个装有值的盒子,然后是一个特殊的接收值返回盒子的函数,返回一个盒子 51 | 同样,对于这个例子,它将盒子中的值取出来,然后传入给这个函数,直接得到作为结果的盒子 52 | 也就达到了我们的需求 53 | 54 | 那Monad又有什么实际用途呢? 55 | 比如想要从输入中获取一个文件名,然后读取这个文件,并将其中内容输出 56 | 我们知道,在Haskell中,有副作用的函数的返回值都被包装在了IO这个类型类中,也就相当于包在了一个盒子中 57 | 用getLine从输入中获取文件名,得到的就是一个包在盒子中的字符串 58 | 然后需要用readFile读取文件,但它输入的是一个字符串,输出的是一个装有文件内容字符串的盒子 59 | 所以就可以使用bind函数直接将readFile函数应用在getLine的结果上 60 | 而输出呢,要用到putStrLn函数,它也是一个接收字符串,返回一个盒子的函数,只不过会将字符串输出,然后返回一个装有空元组的盒子 61 | 因此也可以将上面得到的装有文件内容的盒子直接使用bind函数传入给putStrLn函数输出 62 | 这样整个操作就是getLine >>= readFile >>= putStrLn,非常的简便清晰 63 | 64 | 关于Functor、Applicative、Monad的直观盒子比喻的理解就到这里了 65 | 其实它们简单的用法上不过就是把一些古怪类型的函数应用在盒子中的值上,然后再返回一个盒子 66 | 67 | 那么这期视频你觉得怎么样呢?如果效果可以的话,不妨点个三连告诉我一下 68 | 如果反馈好的话,我会尝试做一系列Haskell入门的视频 69 | 那么我们下期再见了(如果有的话) -------------------------------------------------------------------------------- /active/TODO.md: -------------------------------------------------------------------------------- 1 | - [x] 快速傅里叶变换 2 | - [ ] brainfuck简介(类科普) 3 | - 数据结构系列(1/7) 4 | - [ ] 数据结构引入及视频简介 5 | - [ ] 基础数据结构: 栈 队列 链表 6 | - [ ] ST表 7 | - [ ] 树状数组 8 | - [ ] 线段树 9 | - [ ] 分块 10 | - [ ] 并查集 -------------------------------------------------------------------------------- /active/brainfuck/Brainfuck.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/active/brainfuck/Brainfuck.pdf -------------------------------------------------------------------------------- /active/brainfuck/P′′.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/active/brainfuck/P′′.pdf -------------------------------------------------------------------------------- /active/brainfuck/brainfuck.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_sandbox.utils.imports import * 3 | 4 | 5 | class BFMemory(VGroup): 6 | CONFIG = { 7 | "num_cells": 5, 8 | "cell_config": { 9 | "stroke_color": GRAY, 10 | "fill_opacity": 0, 11 | "buff": 0.2 12 | }, 13 | } 14 | 15 | def __init__(self, **kwargs): 16 | super().__init__(**kwargs) 17 | self.pointer = 0 18 | self.values = [0 for i in range(self.num_cells)] 19 | self.get_single_cell() 20 | self.get_cells() 21 | self.numbers = self.get_numbers() 22 | self.add(self.numbers) 23 | self.add_updater(lambda m: m.update_numbers()) 24 | 25 | def get_single_cell(self): 26 | max_num = Integer( 27 | 255, 28 | edge_to_fix=ORIGIN, 29 | ) 30 | self.basic_cell = SurroundingRectangle( 31 | max_num, 32 | **self.cell_config, 33 | ) 34 | 35 | def get_cells(self): 36 | self.cells = VGroup() 37 | for _ in range(self.num_cells): 38 | self.cells.add(self.basic_cell.copy()) 39 | self.cells.arrange(RIGHT, buff=0.25) 40 | self.add(self.cells) 41 | 42 | def get_numbers(self): 43 | basic_number = Integer( 44 | 0, 45 | edge_to_fix=ORIGIN, 46 | ).set_stroke(color=WHITE, width=1.5, background=True) 47 | numbers = VGroup() 48 | for i in range(self.num_cells): 49 | numbers.add(basic_number.copy().set_value(self.values[i]).move_to(self[0][i])) 50 | return numbers 51 | 52 | def update_numbers(self): 53 | self[1].become(self.get_numbers()) 54 | 55 | def increment(self, pos): 56 | self.values[pos] += 1 57 | if self.values[pos] == 256: 58 | self.values[pos] = 0 59 | 60 | def decrement(self, pos): 61 | self.values[pos] -= 1 62 | if self.values[pos] == -1: 63 | self.values[pos] = 255 64 | 65 | def copy(self): 66 | return self.deepcopy() 67 | 68 | def get_char(self, pos): 69 | text = TextMobject( 70 | chr(self.values[pos]), 71 | color=RED, 72 | background_stroke_color=RED, 73 | background_stroke_width=2 74 | ).scale(1.2) 75 | text.next_to(self.cells[pos], UP, buff=0.1) 76 | return text 77 | 78 | 79 | class BFPointer(VGroup): 80 | CONFIG = { 81 | "tick_config": { 82 | "fill_opacity": 1, 83 | "stroke_width": 0, 84 | }, 85 | "pointer_color": GOLD, 86 | "read_color": RED, 87 | } 88 | 89 | def __init__(self, cells, **kwargs): 90 | super().__init__(**kwargs) 91 | self.cells = cells 92 | self.vect = cells[0][1].get_center() - cells[0][0].get_center() 93 | self.get_rect() 94 | self.get_tick() 95 | 96 | def get_rect(self): 97 | self.rect = self.cells[0][0].copy().set_color(self.pointer_color) 98 | self.add(self.rect) 99 | 100 | def get_tick(self): 101 | self.tick = Triangle(**self.tick_config).scale(0.2) 102 | self.tick.add_updater(lambda m: m.next_to(self.rect, DOWN, buff=0)) 103 | self.tick.add_updater(lambda m: m.match_color(self.rect)) 104 | self.add(self.tick) 105 | 106 | def move(self, delta): 107 | self.rect.shift(self.vect * delta) 108 | return self 109 | 110 | def move_left(self): 111 | return self.move(-1) 112 | 113 | def move_right(self): 114 | return self.move(1) 115 | 116 | def read_number(self): 117 | self.rect.set_color(self.read_color) 118 | return self 119 | 120 | def finish_reading(self): 121 | self.rect.set_color(self.pointer_color) 122 | return self 123 | 124 | def copy(self): 125 | return self.deepcopy() 126 | 127 | 128 | class BFOutput(VGroup): 129 | CONFIG = { 130 | "rect_config": { 131 | "stroke_width": 1.5, 132 | "stroke_color": WHITE, 133 | "fill_opacity": 0, 134 | "stroke_opacity": 1, 135 | "corner_radius": 0.2 136 | }, 137 | "buff": 0.15, 138 | } 139 | 140 | def __init__(self, **kwargs): 141 | super().__init__(**kwargs) 142 | self.get_rect() 143 | self.init_chars() 144 | 145 | def get_rect(self): 146 | output = TextMobject( 147 | "A" * 15, 148 | ) 149 | self.rect = RoundedRectangle( 150 | width=output.get_width()+2*self.buff, 151 | height=output.get_height()+2*self.buff, 152 | **self.rect_config 153 | ) 154 | self.add(self.rect) 155 | 156 | def init_chars(self): 157 | self.chars = VGroup() 158 | self.add(self.chars) 159 | 160 | def append_char(self, text): 161 | text.generate_target() 162 | text.target.set_color(WHITE).set_stroke(color=WHITE, background=True) 163 | text.target.scale(5/6) 164 | if self.chars: 165 | text.target.next_to(self.chars, RIGHT, buff=0.06, aligned_edge=DOWN) 166 | else: 167 | text.target.next_to(self.rect.get_left(), RIGHT, buff=self.buff) 168 | self.chars.add(text) 169 | return MoveToTarget(text) 170 | 171 | def copy(self): 172 | return self.deepcopy() 173 | 174 | 175 | class BFCode(Text): 176 | CONFIG = { 177 | "code": "", 178 | "font": "Consolas", 179 | "size": 0.58, 180 | "color": WHITE, 181 | "t2c": { 182 | "[": RED, 183 | "]": RED, 184 | "<": BLUE, 185 | ">": BLUE, 186 | ".": GREEN, 187 | } 188 | } 189 | 190 | def __init__(self, code=None, **kwargs): 191 | digest_config(self, kwargs) 192 | self.code = code if code else self.code 193 | Text.__init__( 194 | self, 195 | self.code, 196 | **kwargs 197 | ) 198 | for each in self: 199 | if isinstance(each, Dot): 200 | self.remove(each) 201 | self.text = ''.join(filter(lambda x: x in ['.', '[', ']', '<', '>', '+', '-'], self.code)) 202 | 203 | def copy(self): 204 | return self.deepcopy() 205 | 206 | 207 | class BFCodePointer(RoundedRectangle): 208 | CONFIG = { 209 | "stroke_width": 2, 210 | "stroke_color": YELLOW, 211 | "fill_opacity": 0, 212 | "stroke_opacity": 1, 213 | "corner_radius": 0.05, 214 | "text_config": { 215 | "font": "Consolas", 216 | "size": 0.58, 217 | "color": WHITE, 218 | }, 219 | } 220 | 221 | def __init__(self, code, **kwargs): 222 | digest_config(self, kwargs) 223 | base_char = Text( 224 | "[", **self.text_config 225 | ) 226 | RoundedRectangle.__init__( 227 | self, 228 | width=base_char.get_width()+0.1, 229 | height=base_char.get_height()+0.1, 230 | **kwargs 231 | ) 232 | self.code = code 233 | self.move_to(self.code[0]) 234 | 235 | def move(self, pos): 236 | if self.code.text[pos] == '.': 237 | self.move_to(self.code[pos], coor_mask=np.array([1, 0, 0])) 238 | else: 239 | self.move_to(self.code[pos]) 240 | return self 241 | 242 | def copy(self): 243 | return self.deepcopy() 244 | 245 | 246 | def buildbracemap(code): 247 | temp_bracestack, bracemap = [], {} 248 | 249 | for position, command in enumerate(code): 250 | if command == "[": temp_bracestack.append(position) 251 | if command == "]": 252 | start = temp_bracestack.pop() 253 | bracemap[start] = position 254 | bracemap[position] = start 255 | return bracemap 256 | 257 | # do not support input (",") 258 | class BFScene(Scene): 259 | CONFIG = { 260 | "code": "", 261 | } 262 | 263 | def setup(self): 264 | self.memory = BFMemory() 265 | self.code = BFCode(self.code) 266 | self.output = BFOutput() 267 | self.static = VGroup(self.memory, self.code, self.output).arrange(DOWN, aligned_edge=LEFT, buff=0.55) 268 | self.memorypointer = BFPointer(self.memory) 269 | self.codepointer = BFCodePointer(self.code) 270 | self.titles = VGroup( 271 | TextMobject("Cells", color=ORANGE, background_stroke_color=ORANGE, background_stroke_width=1.5), 272 | TextMobject("Code", color=ORANGE, background_stroke_color=ORANGE, background_stroke_width=1.5), 273 | TextMobject("Output", color=ORANGE, background_stroke_color=ORANGE, background_stroke_width=1.5), 274 | ) 275 | for i in range(3): 276 | self.titles[i].next_to(self.static[i], LEFT, buff=0.8) 277 | self.ptr = 0 278 | self.codeptr = 0 279 | self.bracemap = buildbracemap(self.code.text) 280 | 281 | def construct(self): 282 | self.add(self.static, self.titles) 283 | self.wait() 284 | self.play(FadeIn(self.codepointer), FadeIn(self.memorypointer)) 285 | while self.codeptr < len(self.code.text): 286 | self.exe() 287 | self.wait() 288 | self.play(FadeOut(self.codepointer)) 289 | self.wait(3) 290 | 291 | def exe(self): 292 | command = self.code.text[self.codeptr] 293 | if command == '>': 294 | self.play(self.memorypointer.move_right) 295 | self.ptr += 1 296 | elif command == '<': 297 | self.play(self.memorypointer.move_left) 298 | self.ptr -= 1 299 | elif command == '+': 300 | self.wait(0.1) 301 | self.memory.increment(self.ptr) 302 | self.wait(0.1) 303 | self.codeptr += 1 304 | self.play(self.codepointer.move, self.codeptr, run_time=0.2) 305 | return 306 | elif command == '-': 307 | self.wait(0.1) 308 | self.memory.decrement(self.ptr) 309 | self.wait(0.1) 310 | self.codeptr += 1 311 | self.play(self.codepointer.move, self.codeptr, run_time=0.2) 312 | return 313 | elif command == "[" and self.memory.values[self.ptr] == 0: 314 | self.codeptr = self.bracemap[self.codeptr] 315 | self.play(self.codepointer.move, self.codeptr, run_time=0.2) 316 | elif command == "]" and self.memory.values[self.ptr] != 0: 317 | self.codeptr = self.bracemap[self.codeptr] 318 | self.play(self.codepointer.move, self.codeptr, run_time=0.2) 319 | elif command == ".": 320 | text = self.memory.get_char(self.ptr) 321 | self.play( 322 | self.memorypointer.read_number, 323 | FadeInFromDown(text), 324 | run_time=0.5 325 | ) 326 | self.wait(0.5) 327 | self.play( 328 | self.memorypointer.finish_reading, 329 | self.output.append_char(text), 330 | run_time=0.5 331 | ) 332 | self.wait(0.5) 333 | 334 | self.codeptr += 1 335 | if self.codeptr == len(self.code.text): 336 | return 337 | self.play(self.codepointer.move, self.codeptr, run_time=0.2) 338 | 339 | 340 | 341 | class BrainFuckExample(BFScene): 342 | CONFIG = { 343 | "code": """+++++ +++++ + 344 | [ 345 | > +++++ + 346 | < - 347 | ] 348 | > . 349 | ++++ .""", 350 | } 351 | 352 | 353 | class HelloWorld(BFScene): 354 | CONFIG = { 355 | "code": """+++++ +++++ 356 | [ 357 | > +++++ ++ 358 | > +++++ +++++ 359 | > +++ 360 | <<< - 361 | ] 362 | > ++ . > + . +++++ ++ . . 363 | +++ . < +++++ +++++ +++++ . 364 | > . +++ . ----- - . ----- --- . > +++ .""", 365 | } -------------------------------------------------------------------------------- /active/brainfuck/gugugu.bf: -------------------------------------------------------------------------------- 1 | +++++ +++++ 2 | [ 3 | > +++++ ++ 4 | > +++++ +++++ + 5 | > +++ 6 | <<< - 7 | ] 8 | > + . 9 | > +++++ ++ . 10 | < . > . < . > . 11 | > +++ . -------------------------------------------------------------------------------- /active/brainfuck/helloworld.bf: -------------------------------------------------------------------------------- 1 | +++++ +++++ 2 | [ 3 | > +++++ ++ 4 | > +++++ +++++ 5 | > +++ 6 | <<< - 7 | ] 8 | > ++ . > + . +++++ ++ . . 9 | +++ . < +++++ +++++ +++++ . 10 | > . +++ . ----- - . ----- --- . > +++ . -------------------------------------------------------------------------------- /active/brainfuck/part1.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_sandbox.utils.imports import * 3 | from manim_projects.active_projects.brainfuck.brainfuck import * 4 | 5 | 6 | class OpeningSceneHelloWorld(BFScene): 7 | CONFIG = { 8 | "code": """+++++ +++++ 9 | [ 10 | > +++++ ++ 11 | > +++++ +++++ 12 | > +++ 13 | <<< - 14 | ] 15 | > ++ . > + . +++++ ++ . . 16 | +++ . < +++++ +++++ +++++ . 17 | > . +++ . ----- - . ----- --- . > +++ .""" 18 | } 19 | 20 | def construct(self): 21 | # self.add(self.static, self.titles) 22 | raw = BFCode("""++++++++++[>+++++++>++++++++++>+++<<<-] 23 | >++.>+.+++++++..+++.<+++++++++++++++. 24 | >.+++.------.--------.>+++.""" 25 | ).scale(2) 26 | self.wait() 27 | self.play(Write(raw)) 28 | self.wait(3) 29 | self.play(ReplacementTransform(raw, self.code)) 30 | self.wait() 31 | self.play(FadeIn(self.memory[1]), FadeIn(self.memory[0]), FadeIn(self.output), FadeIn(self.titles)) 32 | self.play(FadeIn(self.codepointer), FadeIn(self.memorypointer)) 33 | while self.codeptr < len(self.code.text): 34 | self.exe() 35 | self.wait() 36 | self.play(FadeOut(self.codepointer)) 37 | self.wait(2) 38 | self.output[1].generate_target() 39 | self.output[1].target.scale(2.5).center() 40 | self.play( 41 | FadeOut(VGroup(self.titles, self.memorypointer, self.output[0])), 42 | FadeOut(self.memory[0]), FadeOut(self.memory[1]), 43 | FadeOut(self.code), 44 | MoveToTarget(self.output[1]) 45 | ) 46 | self.wait(2) 47 | -------------------------------------------------------------------------------- /active/ncov.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_projects.tony_useful.imports import * 3 | 4 | class Test_MySectors(Scene): 5 | CONFIG = { 6 | 'camera_config':{ 7 | 'background_color': WHITE, 8 | "use_plot_depth": True, 9 | }, 10 | } 11 | 12 | def add_comment(self): 13 | rect_1 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 14 | text_11 = Text('数据为3月14日前无新增确诊病例的27个省(市,区)', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_1, RIGHT * 0.32).align_to(rect_1, DOWN) 15 | text_11.set_color_by_t2c({'3月14日': BLUE}) 16 | text_line_01 = VGroup(rect_1, text_11).to_corner(LEFT * 16 + UP * 1.) 17 | rect_2 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 18 | text_12 = Text('数据来源:@央视新闻', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_2, RIGHT * 0.32).align_to(rect_2, DOWN) 19 | text_12.set_color_by_t2c({'@央视新闻': ORANGE}) 20 | text_line_02 = VGroup(rect_2, text_12).to_corner(LEFT * 16 + UP * 1.75) 21 | rect_3 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 22 | text_13 = Text('作者:@cigar666', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_3, RIGHT * 0.32).align_to(rect_3, DOWN) 23 | text_13.set_color_by_t2c({'@cigar666': PINK}) 24 | text_line_03 = VGroup(rect_3, text_13).to_corner(LEFT * 16 + UP * 2.5) 25 | self.add(text_line_01, text_line_02, text_line_03) 26 | 27 | 28 | def construct(self): 29 | values = [2, 2, 2, 3, 9, 9, 10, 11, 14, 15, 15, 15, 15, 16, 18, 18, 18, 30 | 19, 22, 23, 23, 24, 24, 25, 26, 37, 44] 31 | labels = ['广东', '山东', '河南', '黑龙江', '四川', '浙江', '宁夏', '辽宁', 32 | '湖南', '天津', '河北', '江西', '安徽', '福建', '山西', '广西', '重庆', 33 | '吉林', '云南', '海南', '陕西', '内蒙古', '江苏', '新疆', '贵州', '青海', '西藏'] 34 | 35 | center = UP * 0.5 + LEFT * 2.25 36 | 37 | graph_01 = MySectors(inner_radius=1.5, values=values, labels=labels, start_direction=RIGHT, 38 | unit='天', center=center) 39 | color = average_color(BLUE_C, BLACK, BLACK) 40 | graph_01.create_cicles(color) 41 | graph_01.create_circle_shadow(color=color) 42 | graph_01.circles.set_plot_depth(5) 43 | graph_01.shadow.set_plot_depth(5) 44 | 45 | font='思源宋体 CN Heavy' 46 | text_01 = Text('多个省市区', font=font, color=color, size=0.32) 47 | text_02 = Text('确诊病例连续多日', font=font, color=color, size=0.32).next_to(text_01, DOWN * 0.25) 48 | text_03 = Text('零新增', font=font, color=color, size=0.75).next_to(text_02, DOWN * 0.4) 49 | texts = VGroup(text_01, text_02, text_03).move_to(center) 50 | 51 | # self.add_comment() 52 | 53 | start_mobjects = VGroup() 54 | value_trackers = [] 55 | angle_trackers = [] 56 | start_a = np.angle(complex(*RIGHT[0:2])) 57 | for i in range(len(values)): 58 | start_mobjects.add(graph_01[0][0].copy().set_plot_depth(-100+2*(len(values)-1-i))) 59 | value_trackers.append(ValueTracker(graph_01[0][0].outer_radius)) 60 | angle_trackers.append(ValueTracker(start_a+0*TAU/len(values))) 61 | def updater(obj): 62 | for index in range(len(values)): 63 | r = value_trackers[index].get_value() 64 | size = TAU * r / len(values) * 0.2 65 | angle = TAU / len(values) 66 | angle_ = angle_trackers[index].get_value() 67 | start_a = np.angle(complex(*RIGHT[0:2])) 68 | obj[index].set_height(2 * size) 69 | obj[index].move_to(center + complex_to_R3((r-size*1.2-r*0.05)*np.exp(1j*(angle_+0.5*angle)))) 70 | graph_01[1].add_updater(updater) 71 | self.add(start_mobjects, *graph_01[1], graph_01[2:], texts) 72 | self.wait(1) 73 | self.play( 74 | *[ 75 | MyRotating(start_mobjects[i], graph_01[0][-1-i], value_trackers[-1-i], angle_trackers[-1-i], len(values)-1-i, radians=TAU-(i+1)*TAU/len(values), 76 | about_point=center, len=len(values), rate_func=smooth) 77 | for i in range(len(values)) 78 | ] 79 | ) 80 | self.wait(2) 81 | 82 | class Test_MySectors_0315(Scene): 83 | 84 | CONFIG = { 85 | 'camera_config':{ 86 | 'background_color': WHITE, 87 | }, 88 | } 89 | 90 | def construct(self): 91 | 92 | values = [3, 3, 4, 10, 11, 12, 15, 16, 16, 16, 16, 17, 19, 19, 19, 93 | 20, 23, 24, 24, 25, 25, 26, 27, 38, 45] 94 | labels = ['山东', '河南', '黑龙江', '四川', '宁夏', '辽宁', 95 | '湖南', '天津', '河北', '江西', '安徽', '福建', '山西', '广西', '重庆', 96 | '吉林', '云南', '海南', '陕西', '内蒙古', '江苏', '新疆', '贵州', '青海', '西藏'] 97 | 98 | center = UP * 0.5 + LEFT * 2.25 99 | 100 | graph_01 = MySectors(inner_radius=1.5, values=values, labels=labels, start_direction=RIGHT, 101 | unit='天', center=center) 102 | color = average_color(BLUE_B, BLACK, BLACK) 103 | graph_01.create_cicles(color) 104 | graph_01.create_circle_shadow(color=color) 105 | 106 | font='思源宋体 CN' 107 | text_01 = Text('多个省市区', font=font, color=color, size=0.32) 108 | text_02 = Text('确诊病例连续多日', font=font, color=color, size=0.32).next_to(text_01, DOWN * 0.25) 109 | text_03 = Text('零新增', font=font, color=color, size=0.75).next_to(text_02, DOWN * 0.4) 110 | texts = VGroup(text_01, text_02, text_03).move_to(center) 111 | 112 | rect_1 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 113 | text_11 = Text('数据为3月15日前无新增确诊病例的25个省(市,区)', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_1, RIGHT * 0.32).align_to(rect_1, DOWN) 114 | text_11.set_color_by_t2c({'3月15日': BLUE}) 115 | text_line_01 = VGroup(rect_1, text_11).to_corner(LEFT * 16 + UP * 1.) 116 | rect_2 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 117 | text_12 = Text('数据来源:@央视新闻', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_2, RIGHT * 0.32).align_to(rect_2, DOWN) 118 | text_12.set_color_by_t2c({'@央视新闻': ORANGE}) 119 | text_line_02 = VGroup(rect_2, text_12).to_corner(LEFT * 16 + UP * 1.75) 120 | rect_3 = Rectangle(width=0.1, height=0.24, stroke_width=0, fill_color=color, fill_opacity=1) 121 | text_13 = Text('作者:@cigar666', font='思源黑体 CN Bold', color=color).set_height(0.24).next_to(rect_3, RIGHT * 0.32).align_to(rect_3, DOWN) 122 | text_13.set_color_by_t2c({'@cigar666': PINK}) 123 | text_line_03 = VGroup(rect_3, text_13).to_corner(LEFT * 16 + UP * 2.5) 124 | 125 | self.add(graph_01, texts, text_line_01, text_line_02, text_line_03) 126 | self.wait(5) -------------------------------------------------------------------------------- /assets/OmegaCreature/omega_class.py: -------------------------------------------------------------------------------- 1 | from manimlib.constants import * 2 | from manim_projects.OmegaCreature.omega_creature import OmegaCreature 3 | from manimlib.mobject.types.vectorized_mobject import VGroup 4 | 5 | 6 | class OmegaCreatureClass(VGroup): 7 | CONFIG = { 8 | "width": 3, 9 | "height": 2 10 | } 11 | 12 | def __init__(self, **kwargs): 13 | VGroup.__init__(self, **kwargs) 14 | for i in range(self.width): 15 | for j in range(self.height): 16 | omega = OmegaCreature().scale(0.3) 17 | omega.move_to(i * DOWN + j * RIGHT) 18 | self.add(omega) 19 | -------------------------------------------------------------------------------- /assets/OmegaCreature/omega_creature_animations.py: -------------------------------------------------------------------------------- 1 | from manimlib.animation.animation import Animation 2 | from manimlib.animation.composition import AnimationGroup 3 | from manimlib.animation.fading import FadeOut 4 | from manimlib.animation.creation import ShowCreation 5 | from manimlib.animation.creation import Write 6 | from manimlib.animation.transform import ApplyMethod 7 | from manimlib.animation.transform import MoveToTarget 8 | from manimlib.constants import * 9 | from manim_projects.OmegaCreature.omega_class import OmegaCreatureClass 10 | from manimlib.mobject.mobject import Group 11 | from manimlib.mobject.svg.drawings import SpeechBubble 12 | from manimlib.utils.config_ops import digest_config 13 | from manimlib.utils.rate_functions import squish_rate_func 14 | from manimlib.utils.rate_functions import there_and_back 15 | 16 | 17 | class Blink(ApplyMethod): 18 | CONFIG = { 19 | "rate_func": squish_rate_func(there_and_back) 20 | } 21 | 22 | def __init__(self, omega_creature, **kwargs): 23 | ApplyMethod.__init__(self, omega_creature.blink, **kwargs) 24 | 25 | 26 | class OmegaCreatureBubbleIntroduction(AnimationGroup): 27 | CONFIG = { 28 | "target_mode": "speaking", 29 | "bubble_class": SpeechBubble, 30 | "change_mode_kwargs": {}, 31 | "bubble_creation_class": ShowCreation, 32 | "bubble_creation_kwargs": {}, 33 | "bubble_kwargs": {}, 34 | "content_introduction_class": Write, 35 | "content_introduction_kwargs": {}, 36 | "look_at_arg": None, 37 | } 38 | 39 | def __init__(self, omega_creature, *content, **kwargs): 40 | digest_config(self, kwargs) 41 | bubble = omega_creature.get_bubble( 42 | *content, 43 | bubble_class=self.bubble_class, 44 | **self.bubble_kwargs 45 | ) 46 | Group(bubble, bubble.content).shift_onto_screen() 47 | 48 | omega_creature.generate_target() 49 | omega_creature.target.change_mode(self.target_mode) 50 | if self.look_at_arg is not None: 51 | omega_creature.target.look_at(self.look_at_arg) 52 | 53 | change_mode = MoveToTarget(omega_creature, **self.change_mode_kwargs) 54 | bubble_creation = self.bubble_creation_class( 55 | bubble, **self.bubble_creation_kwargs 56 | ) 57 | content_introduction = self.content_introduction_class( 58 | bubble.content, **self.content_introduction_kwargs 59 | ) 60 | AnimationGroup.__init__( 61 | self, change_mode, bubble_creation, content_introduction, 62 | **kwargs 63 | ) 64 | 65 | 66 | class OmegaCreatureSays(OmegaCreatureBubbleIntroduction): 67 | CONFIG = { 68 | "target_mode": "speaking", 69 | "bubble_class": SpeechBubble, 70 | } 71 | 72 | 73 | class RemoveOmegaCreatureBubble(AnimationGroup): 74 | CONFIG = { 75 | "target_mode": "plain", 76 | "look_at_arg": None, 77 | "remover": True, 78 | } 79 | 80 | def __init__(self, omega_creature, **kwargs): 81 | assert hasattr(omega_creature, "bubble") 82 | digest_config(self, kwargs, locals()) 83 | 84 | omega_creature.generate_target() 85 | omega_creature.target.change_mode(self.target_mode) 86 | if self.look_at_arg is not None: 87 | omega_creature.target.look_at(self.look_at_arg) 88 | 89 | AnimationGroup.__init__( 90 | self, 91 | MoveToTarget(omega_creature), 92 | FadeOut(omega_creature.bubble), 93 | FadeOut(omega_creature.bubble.content), 94 | ) 95 | 96 | def clean_up_from_scene(self, scene=None): 97 | AnimationGroup.clean_up_from_scene(self, scene) 98 | self.omega_creature.bubble = None 99 | if scene is not None: 100 | scene.add(self.omega_creature) 101 | 102 | 103 | class FlashThroughClass(Animation): 104 | CONFIG = { 105 | "highlight_color": GREEN, 106 | } 107 | 108 | def __init__(self, mobject, mode="linear", **kwargs): 109 | if not isinstance(mobject, OmegaCreatureClass): 110 | raise Exception("FlashThroughClass mobject must be a OmegaCreatureClass") 111 | digest_config(self, kwargs) 112 | self.indices = list(range(mobject.height * mobject.width)) 113 | if mode == "random": 114 | np.random.shuffle(self.indices) 115 | Animation.__init__(self, mobject, **kwargs) 116 | 117 | def interpolate_mobject(self, alpha): 118 | index = int(np.floor(alpha * self.mobject.height * self.mobject.width)) 119 | for omega in self.mobject: 120 | omega.set_color(BLUE_E) 121 | if index < self.mobject.height * self.mobject.width: 122 | self.mobject[self.indices[index]].set_color(self.highlight_color) 123 | -------------------------------------------------------------------------------- /assets/fonts/FZQKBYSJW.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/FZQKBYSJW.TTF -------------------------------------------------------------------------------- /assets/fonts/Monaco_Powerline.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/Monaco_Powerline.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Bold.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-ExtraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-ExtraLight.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Heavy.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Heavy.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Light.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Medium.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Normal.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Normal.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSansCN-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSansCN-Regular.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-Bold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-Bold.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-ExtraLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-ExtraLight.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-Heavy.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-Heavy.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-Light.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-Light.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-Medium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-Medium.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-Regular.otf -------------------------------------------------------------------------------- /assets/fonts/SourceHanSerifCN-SemiBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/SourceHanSerifCN-SemiBold.otf -------------------------------------------------------------------------------- /assets/fonts/consola.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/consola.ttf -------------------------------------------------------------------------------- /assets/fonts/consolab.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/consolab.ttf -------------------------------------------------------------------------------- /assets/fonts/consolai.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/consolai.ttf -------------------------------------------------------------------------------- /assets/fonts/consolaz.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/fonts/consolaz.ttf -------------------------------------------------------------------------------- /assets/raster_images/title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/assets/raster_images/title.png -------------------------------------------------------------------------------- /assets/svg_images/OmegaCreatures_plain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 7 | 9 | 11 | 13 | 24 | 26 | 27 | -------------------------------------------------------------------------------- /assets/svg_images/__old_OmegaCreatures_plain.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 12 | 14 | 17 | 20 | 38 | 40 | -------------------------------------------------------------------------------- /assets/svg_images/coin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | -------------------------------------------------------------------------------- /assets/svg_images/favo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | -------------------------------------------------------------------------------- /assets/svg_images/good.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | -------------------------------------------------------------------------------- /assets/svg_images/video_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 23 | 24 | -------------------------------------------------------------------------------- /old/BiliBili_Fourier/BilibiliFourier.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : BilibiliFourier.py 3 | > Author : Tony 4 | > Created Time : 2019/08/10 12:46:11 5 | ''' 6 | 7 | from manimlib.imports import * 8 | 9 | from active_projects.diffyq.part2.fourier_series import FourierOfTrebleClef 10 | 11 | 12 | class ComplexFourierSeriesExample(FourierOfTrebleClef): 13 | CONFIG = { 14 | "file_name": "EighthNote", 15 | "run_time": 10, 16 | "n_vectors": 200, 17 | "n_cycles": 2, 18 | "max_circle_stroke_width": 0.75, 19 | "drawing_height": 5, 20 | "center_point": DOWN, 21 | "top_row_center": 3 * UP, 22 | "top_row_label_y": 2, 23 | "top_row_x_spacing": 1.75, 24 | "top_row_copy_scale_factor": 0.9, 25 | "start_drawn": False, 26 | "plane_config": { 27 | "axis_config": {"unit_size": 2}, 28 | "y_min": -1.25, 29 | "y_max": 1.25, 30 | "x_min": -2.5, 31 | "x_max": 2.5, 32 | "background_line_style": { 33 | "stroke_width": 1, 34 | "stroke_color": LIGHT_GREY, 35 | }, 36 | }, 37 | "top_rect_height": 2.5, 38 | } 39 | 40 | def construct(self): 41 | self.add_vectors_circles_path() 42 | self.add_top_row(self.vectors, self.circles) 43 | self.write_title() 44 | self.highlight_vectors_one_by_one() 45 | self.change_shape() 46 | 47 | def write_title(self): 48 | title = TextMobject("Complex\\\\Fourier series") 49 | title.scale(1.5) 50 | title.to_edge(LEFT) 51 | title.match_y(self.path) 52 | 53 | self.wait(11) 54 | self.play(FadeInFromDown(title)) 55 | self.wait(2) 56 | self.title = title 57 | 58 | def highlight_vectors_one_by_one(self): 59 | # Don't know why these vectors can't get copied. 60 | # That seems like a problem that will come up again. 61 | labels = self.top_row[-1] 62 | next_anims = [] 63 | for vector, circle, label in zip(self.vectors, self.circles, labels): 64 | # v_color = vector.get_color() 65 | c_color = circle.get_color() 66 | c_stroke_width = circle.get_stroke_width() 67 | 68 | rect = SurroundingRectangle(label, color=PINK) 69 | self.play( 70 | # vector.set_color, PINK, 71 | circle.set_stroke, RED, 3, 72 | FadeIn(rect), 73 | *next_anims 74 | ) 75 | self.wait() 76 | next_anims = [ 77 | # vector.set_color, v_color, 78 | circle.set_stroke, c_color, c_stroke_width, 79 | FadeOut(rect), 80 | ] 81 | self.play(*next_anims) 82 | 83 | def change_shape(self): 84 | # path_mob = TexMobject("\\pi") 85 | path_mob = SVGMobject("Nail_And_Gear") 86 | new_path = path_mob.family_members_with_points()[0] 87 | new_path.set_height(4) 88 | new_path.move_to(self.path, DOWN) 89 | new_path.shift(0.5 * UP) 90 | 91 | self.transition_to_alt_path(new_path) 92 | for n in range(self.n_cycles): 93 | self.run_one_cycle() 94 | 95 | def transition_to_alt_path(self, new_path, morph_path=False): 96 | new_coefs = self.get_coefficients_of_path(new_path) 97 | new_vectors = self.get_rotating_vectors( 98 | coefficients=new_coefs 99 | ) 100 | new_drawn_path = self.get_drawn_path(new_vectors) 101 | 102 | self.vector_clock.suspend_updating() 103 | 104 | vectors = self.vectors 105 | anims = [] 106 | 107 | for vect, new_vect in zip(vectors, new_vectors): 108 | new_vect.update() 109 | new_vect.clear_updaters() 110 | 111 | line = Line(stroke_width=0) 112 | line.put_start_and_end_on(*vect.get_start_and_end()) 113 | anims.append(ApplyMethod( 114 | line.put_start_and_end_on, 115 | *new_vect.get_start_and_end() 116 | )) 117 | vect.freq = new_vect.freq 118 | vect.coefficient = new_vect.coefficient 119 | 120 | vect.line = line 121 | vect.add_updater( 122 | lambda v: v.put_start_and_end_on( 123 | *v.line.get_start_and_end() 124 | ) 125 | ) 126 | if morph_path: 127 | anims.append( 128 | ReplacementTransform( 129 | self.drawn_path, 130 | new_drawn_path 131 | ) 132 | ) 133 | else: 134 | anims.append( 135 | FadeOut(self.drawn_path) 136 | ) 137 | 138 | self.play(*anims, run_time=3) 139 | for vect in self.vectors: 140 | vect.remove_updater(vect.updaters[-1]) 141 | 142 | if not morph_path: 143 | self.add(new_drawn_path) 144 | self.vector_clock.set_value(0) 145 | 146 | self.vector_clock.resume_updating() 147 | self.drawn_path = new_drawn_path 148 | 149 | # 150 | def get_path(self): 151 | path = super().get_path() 152 | path.set_height(self.drawing_height) 153 | path.to_edge(DOWN) 154 | return path 155 | 156 | def add_top_row(self, vectors, circles, max_freq=3): 157 | self.top_row = self.get_top_row( 158 | vectors, circles, max_freq 159 | ) 160 | self.add(self.top_row) 161 | 162 | def get_top_row(self, vectors, circles, max_freq=3): 163 | vector_copies = VGroup() 164 | circle_copies = VGroup() 165 | for vector, circle in zip(vectors, circles): 166 | if vector.freq > max_freq: 167 | break 168 | vcopy = vector.copy() 169 | vcopy.clear_updaters() 170 | ccopy = circle.copy() 171 | ccopy.clear_updaters() 172 | ccopy.original = circle 173 | vcopy.original = vector 174 | 175 | vcopy.center_point = op.add( 176 | self.top_row_center, 177 | vector.freq * self.top_row_x_spacing * RIGHT, 178 | ) 179 | ccopy.center_point = vcopy.center_point 180 | vcopy.add_updater(self.update_top_row_vector_copy) 181 | ccopy.add_updater(self.update_top_row_circle_copy) 182 | vector_copies.add(vcopy) 183 | circle_copies.add(ccopy) 184 | 185 | dots = VGroup(*[ 186 | TexMobject("\\dots").next_to( 187 | circle_copies, direction, 188 | MED_LARGE_BUFF, 189 | ) 190 | for direction in [LEFT, RIGHT] 191 | ]) 192 | labels = self.get_top_row_labels(vector_copies) 193 | return VGroup( 194 | vector_copies, 195 | circle_copies, 196 | dots, 197 | labels, 198 | ) 199 | 200 | def update_top_row_vector_copy(self, vcopy): 201 | vcopy.become(vcopy.original) 202 | vcopy.scale(self.top_row_copy_scale_factor) 203 | vcopy.shift(vcopy.center_point - vcopy.get_start()) 204 | return vcopy 205 | 206 | def update_top_row_circle_copy(self, ccopy): 207 | ccopy.become(ccopy.original) 208 | ccopy.scale(self.top_row_copy_scale_factor) 209 | ccopy.move_to(ccopy.center_point) 210 | return ccopy 211 | 212 | def get_top_row_labels(self, vector_copies): 213 | labels = VGroup() 214 | for vector_copy in vector_copies: 215 | freq = vector_copy.freq 216 | label = Integer(freq) 217 | label.move_to(np.array([ 218 | freq * self.top_row_x_spacing, 219 | self.top_row_label_y, 220 | 0 221 | ])) 222 | labels.add(label) 223 | return labels 224 | 225 | def setup_plane(self): 226 | plane = ComplexPlane(**self.plane_config) 227 | plane.shift(self.center_point) 228 | plane.add_coordinates() 229 | 230 | top_rect = Rectangle( 231 | width=FRAME_WIDTH, 232 | fill_color=BLACK, 233 | fill_opacity=1, 234 | stroke_width=0, 235 | height=self.top_rect_height, 236 | ) 237 | top_rect.to_edge(UP, buff=0) 238 | 239 | self.plane = plane 240 | self.add(plane) 241 | self.add(top_rect) 242 | 243 | def get_path_end(self, vectors, stroke_width=None, **kwargs): 244 | if stroke_width is None: 245 | stroke_width = self.drawn_path_st 246 | full_path = self.get_vector_sum_path(vectors, **kwargs) 247 | path = VMobject() 248 | path.set_stroke( 249 | self.drawn_path_color, 250 | stroke_width 251 | ) 252 | 253 | def update_path(p): 254 | alpha = self.get_vector_time() % 1 255 | p.pointwise_become_partial( 256 | full_path, 257 | np.clip(alpha - 0.01, 0, 1), 258 | np.clip(alpha, 0, 1), 259 | ) 260 | p.points[-1] = vectors[-1].get_end() 261 | 262 | path.add_updater(update_path) 263 | return path 264 | 265 | def get_drawn_path_alpha(self): 266 | return super().get_drawn_path_alpha() - 0.002 267 | 268 | def get_drawn_path(self, vectors, stroke_width=2, **kwargs): 269 | odp = super().get_drawn_path(vectors, stroke_width, **kwargs) 270 | return VGroup( 271 | odp, 272 | self.get_path_end(vectors, stroke_width, **kwargs), 273 | ) 274 | 275 | def get_vertically_falling_tracing(self, vector, color, stroke_width=3, rate=0.25): 276 | path = VMobject() 277 | path.set_stroke(color, stroke_width) 278 | path.start_new_path(vector.get_end()) 279 | path.vector = vector 280 | 281 | def update_path(p, dt): 282 | p.shift(rate * dt * DOWN) 283 | p.add_smooth_curve_to(p.vector.get_end()) 284 | path.add_updater(update_path) 285 | return path 286 | 287 | class Bilibili10(ComplexFourierSeriesExample): 288 | CONFIG = { 289 | "file_name": "bilibili", 290 | "n_vectors": 10, 291 | "text": "10", 292 | "path_height": 3.5, 293 | "max_circle_stroke_width": 1, 294 | "top_row_copy_scale_factor": 0.6, 295 | } 296 | 297 | def construct(self): 298 | text = TextMobject("n = ", self.text).scale(1.5).to_corner(DL) 299 | text[1].set_color(GREEN) 300 | self.add(text) 301 | self.setup_plane() 302 | self.add_vectors_circles_path() 303 | self.add_top_row(self.vectors, self.circles) 304 | 305 | for n in range(self.n_cycles): 306 | self.run_one_cycle() 307 | 308 | def get_shape(self): 309 | path = VMobject() 310 | shape = SVGMobject(self.file_name) 311 | for sp in shape.family_members_with_points(): 312 | path.append_points(sp.points) 313 | return path 314 | 315 | def get_path(self): 316 | shape = self.get_shape() 317 | shape.set_height(4) 318 | path = shape.family_members_with_points()[0] 319 | path.set_fill(opacity=0.05) 320 | path.set_stroke(WHITE, 0.3) 321 | return path 322 | 323 | class Bilibili50(Bilibili10): 324 | CONFIG = { 325 | "n_vectors": 50, 326 | "text": "50", 327 | } 328 | 329 | class Bilibili100(Bilibili10): 330 | CONFIG = { 331 | "n_vectors": 100, 332 | "text": "100", 333 | } 334 | 335 | class Bilibili500(Bilibili10): 336 | CONFIG = { 337 | "n_vectors": 500, 338 | "text": "500", 339 | } -------------------------------------------------------------------------------- /old/BinaryIndexedTree/Fenwick_tree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/BinaryIndexedTree/Fenwick_tree.pdf -------------------------------------------------------------------------------- /old/BinaryIndexedTree/text.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/BinaryIndexedTree/text.txt -------------------------------------------------------------------------------- /old/BinaryIndexedTree/树状数组.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/BinaryIndexedTree/树状数组.pdf -------------------------------------------------------------------------------- /old/FastFourierTransform/FFT1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int maxn = 2100010; 5 | const double PI = acos(-1.0); 6 | 7 | struct Complex { 8 | double r, i; 9 | Complex() { r = 0, i = 0; } 10 | Complex(double real, double imag): r(real), i(imag) {} 11 | }F[maxn], G[maxn]; 12 | Complex operator + (Complex a, Complex b) { return Complex(a.r + b.r, a.i + b.i); } 13 | Complex operator - (Complex a, Complex b) { return Complex(a.r - b.r, a.i - b.i); } 14 | Complex operator * (Complex a, Complex b) { return Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); } 15 | 16 | void FFT(int lim, Complex* a) { 17 | if (lim == 1) return; 18 | Complex a0[lim >> 1], a1[lim >> 1]; 19 | for (int i = 0; i < lim; i += 2) 20 | a0[i >> 1] = a[i], a1[i >> 1] = a[i + 1]; 21 | FFT(lim >> 1, a0); 22 | FFT(lim >> 1, a1); 23 | Complex wn = Complex(cos(2.0 * PI / lim), sin(2.0 * PI / lim)); 24 | Complex w = Complex(1, 0); 25 | for (int k = 0; k < (lim >> 1); ++k) { 26 | a[k] = a0[k] + w * a1[k]; 27 | a[k + (lim >> 1)] = a0[k] - w * a1[k]; 28 | w = w * wn; 29 | } 30 | } -------------------------------------------------------------------------------- /old/FastFourierTransform/FFT2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | inline int read() { 5 | int x = 0; int f = 1; char ch = getchar(); 6 | while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} 7 | while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();} 8 | return x * f; 9 | } 10 | 11 | const int maxn = 2100010; 12 | const double PI = acos(-1.0); 13 | 14 | struct Complex { 15 | double r, i; 16 | Complex() { r = 0, i = 0; } 17 | Complex(double real, double imag): r(real), i(imag) {} 18 | }F[maxn], G[maxn]; 19 | Complex operator + (Complex a, Complex b) { return Complex(a.r + b.r, a.i + b.i); } 20 | Complex operator - (Complex a, Complex b) { return Complex(a.r - b.r, a.i - b.i); } 21 | Complex operator * (Complex a, Complex b) { return Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); } 22 | 23 | int len, rev[maxn], lim = 1; 24 | 25 | void FFT(Complex* a) { 26 | for (int i = 0; i < lim; ++i) if (i < rev[i]) swap(a[i], a[rev[i]]); 27 | for (int dep = 1; dep <= log2(lim); ++dep) { 28 | int m = 1 << dep; 29 | Complex wn = Complex(cos(2 * PI / m), sin(2 * PI / m)); 30 | for (int k = 0; k < lim; k += m) { 31 | Complex w = Complex(1, 0); 32 | for (int j = 0; j < m / 2; ++j) { 33 | Complex t = w * a[k + j + m / 2]; 34 | Complex u = a[k + j]; 35 | a[k + j] = u + t; 36 | a[k + j + m / 2] = u - t; 37 | w = w * wn; 38 | } 39 | } 40 | } 41 | } 42 | 43 | int main() { 44 | int n = read(); 45 | while (lim <= n) lim <<= 1, len++; 46 | for (int i = 0; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1)); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /old/FastFourierTransform/IFFT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | inline int read() { 5 | int x = 0; int f = 1; char ch = getchar(); 6 | while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} 7 | while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();} 8 | return x * f; 9 | } 10 | 11 | const int maxn = 2100010; 12 | const double PI = acos(-1.0); 13 | 14 | struct Complex { 15 | double r, i; 16 | Complex() { r = 0, i = 0; } 17 | Complex(double real, double imag): r(real), i(imag) {} 18 | }F[maxn], G[maxn]; 19 | Complex operator + (Complex a, Complex b) { return Complex(a.r + b.r, a.i + b.i); } 20 | Complex operator - (Complex a, Complex b) { return Complex(a.r - b.r, a.i - b.i); } 21 | Complex operator * (Complex a, Complex b) { return Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); } 22 | 23 | int len, rev[maxn], lim = 1; 24 | 25 | void FFT(Complex* a, int opt) { 26 | for (int i = 0; i < lim; ++i) if (i < rev[i]) swap(a[i], a[rev[i]]); 27 | for (int dep = 1; dep <= log2(lim); ++dep) { 28 | int m = 1 << dep; 29 | Complex wn = Complex(cos(2 * PI / m), opt * sin(2 * PI / m)); 30 | for (int k = 0; k < lim; k += m) { 31 | Complex w = Complex(1, 0); 32 | for (int j = 0; j < m / 2; ++j) { 33 | Complex t = w * a[k + j + m / 2]; 34 | Complex u = a[k + j]; 35 | a[k + j] = u + t; 36 | a[k + j + m / 2] = u - t; 37 | w = w * wn; 38 | } 39 | } 40 | } 41 | if (opt == -1) for (int i = 0; i < lim; ++i) F[i].r /= lim; 42 | } 43 | 44 | int main() { 45 | int n = read(); 46 | while (lim <= n) lim <<= 1, len++; 47 | for (int i = 0; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1)); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /old/FastFourierTransform/Polynomial.cpp: -------------------------------------------------------------------------------- 1 | /************************************************************* 2 | * > File Name : P3803_FFT.cpp 3 | * > author : Tony_Wong 4 | * > Created Time : 2019/12/12 12:18:32 5 | * > algorithm : FFT 6 | **************************************************************/ 7 | 8 | #include 9 | using namespace std; 10 | 11 | inline int read() { 12 | int x = 0; int f = 1; char ch = getchar(); 13 | while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} 14 | while (isdigit(ch)) {x = x * 10 + ch - 48; ch = getchar();} 15 | return x * f; 16 | } 17 | 18 | const int maxn = 2100010; 19 | const double PI = acos(-1.0); 20 | 21 | int cnt, rev[maxn], lim = 1; 22 | 23 | struct Complex { 24 | double r, i; 25 | Complex() { r = 0, i = 0; } 26 | Complex(double real, double imag): r(real), i(imag) {} 27 | }F[maxn], G[maxn]; 28 | Complex operator + (Complex a, Complex b) { return Complex(a.r + b.r, a.i + b.i); } 29 | Complex operator - (Complex a, Complex b) { return Complex(a.r - b.r, a.i - b.i); } 30 | Complex operator * (Complex a, Complex b) { return Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); } 31 | 32 | void FFT(Complex* a, int opt) { 33 | for (int i = 0; i < lim; ++i) if (i < rev[i]) swap(a[i], a[rev[i]]); 34 | for (int s = 1; s <= log2(lim); ++s) { 35 | int m = 1 << s; 36 | Complex wn = Complex(cos(2 * PI / m), opt * sin(2 * PI / m)); 37 | for (int k = 0; k < lim; k += m) { 38 | Complex w = Complex(1, 0); 39 | for (int j = 0; j < m / 2; ++j) { 40 | Complex t = w * a[k + j + m / 2]; 41 | Complex u = a[k + j]; 42 | a[k + j] = u + t; 43 | a[k + j + m / 2] = u - t; 44 | w = w * wn; 45 | } 46 | } 47 | } 48 | if (opt == -1) for (int i = 0; i < lim; ++i) F[i].r /= lim; 49 | } 50 | 51 | int main() { 52 | int n = read(), m = read(); 53 | for (int i = 0; i <= n; ++i) F[i].r = read(); 54 | for (int i = 0; i <= m; ++i) G[i].r = read(); 55 | while (lim <= n + m) lim <<= 1, cnt++; 56 | for (int i = 0; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (cnt - 1)); 57 | FFT(F, 1); FFT(G, 1); 58 | for (int i = 0; i <= lim; ++i) F[i] = F[i] * G[i]; 59 | FFT(F, -1); 60 | for (int i = 0; i <= n + m; ++i) { 61 | printf("%d ", (int)(F[i].r + 0.5)); 62 | } 63 | return 0; 64 | } -------------------------------------------------------------------------------- /old/FastFourierTransform/Rotate_by_complex.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Angle(VGroup): 4 | 5 | CONFIG = { 6 | 'radius': 1, 7 | 'color': RED, 8 | 'opacity': 0.4, 9 | 'stroke_width': 10, 10 | # 'below_180': True, 11 | } 12 | 13 | def __init__(self, A, O, B, **kwargs): 14 | 15 | VMobject.__init__(self, **kwargs) 16 | OA, OB = A-O, B-O 17 | theta = np.angle(complex(*OA[:2])/complex(*OB[:2])) # angle of OB to OA 18 | 19 | self.add(Arc(start_angle=Line(O, B).get_angle(), angle=theta, radius=self.radius/2, 20 | stroke_width=100 * self.radius, color=self.color).set_stroke(opacity=self.opacity).move_arc_center_to(O)) 21 | self.add(Arc(start_angle=Line(O, B).get_angle(), angle=theta, radius=self.radius, 22 | stroke_width=self.stroke_width, color=self.color).move_arc_center_to(O)) 23 | 24 | class Unit_root(Scene): 25 | 26 | def construct(self): 27 | 28 | ## Create ComplexPlane ## 29 | cp_scale = 1.75 30 | cp = ComplexPlane().scale(cp_scale) 31 | cp.add_coordinates(0, 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4, -5) 32 | cp.add_coordinates(1j, 2j, 3j, -1j, -2j, -3j) 33 | 34 | ### about z^n ### 35 | color_dict = {'z': PINK, 'x': BLUE, 'y': YELLOW, 'i': RED, '\\cos': BLUE, '\\sin': YELLOW, '\\theta}': BLUE, 36 | 'r': PINK, 'e': GREEN, 'n': YELLOW, 'k': YELLOW, '\\omega': PINK, '\\pi': BLUE} 37 | complex_z = 0.9+0.6j 38 | vect_z = Arrow(cp.n2p(0), cp.n2p(complex_z), buff=0, color=ORANGE) 39 | dot_z = Dot(cp.n2p(complex_z), color=PINK) 40 | angle_z = Angle(cp.n2p(1), cp.n2p(0), cp.n2p(complex_z), radius=0.6, color=BLUE) 41 | 42 | ## 3 forms of complex num 43 | xy_form = TexMobject('z', '=', 'x', '+', 'y', 'i').set_color_by_tex_to_color_map(color_dict) 44 | cs_form = TexMobject('z', '=', 'r', '(', '\\cos{', '\\theta}', '+', 'i', '\\sin{', '\\theta}', ')').set_color_by_tex_to_color_map(color_dict) 45 | exp_form = TexMobject('z', '=', 'r', 'e^{', 'i', '\\theta}', color=WHITE).set_color_by_tex_to_color_map(color_dict).scale(1.2) 46 | exp_form[-1].set_color(BLUE) 47 | xy_form.next_to(dot_z, RIGHT * 0.6) 48 | cs_form.next_to(dot_z, RIGHT * 0.6) 49 | exp_form.next_to(dot_z, RIGHT * 0.6).shift(UP * 0.25) 50 | 51 | ## vgroup for z_i 52 | vect_group = VGroup(vect_z) 53 | dot_group = VGroup(dot_z) 54 | text_group = VGroup(exp_form) 55 | angle_group = VGroup(angle_z) 56 | line_group = VGroup(Line(cp.n2p(1), cp.n2p(complex_z), color=PINK)) 57 | 58 | n = 10 59 | for i in range(n-1): 60 | zn_1 = complex_z ** (i+2-1) 61 | zn = complex_z ** (i+2) 62 | dot_i = Dot(cp.n2p(zn), color=PINK) 63 | vect_i = Arrow(cp.n2p(0), cp.n2p(zn), buff=0, color=ORANGE) 64 | text_i = TexMobject('z^{', '%d}' % (i+2), color=PINK).shift(cp.n2p(zn)/abs(zn) * (abs(zn) + 0.25)) 65 | angle_i = Angle(cp.n2p(zn_1), cp.n2p(0), cp.n2p(zn), radius=0.6, color=BLUE) 66 | vect_group.add(vect_i) 67 | dot_group.add(dot_i) 68 | text_group.add(text_i) 69 | angle_group.add(angle_i) 70 | line_group.add(VGroup(Line(cp.n2p(zn_1), cp.n2p(zn), color=PINK))) 71 | 72 | ### conclusions from z^n =1 ### 73 | text_zn = TexMobject('z^', 'n', '=', 'r^', 'n', 'e^{', 'n', '\\theta', 'i}', '=', '1').set_color_by_tex_to_color_map(color_dict) 74 | text_zn[7].set_color(BLUE) 75 | text_zn.scale(1.2).to_corner(RIGHT * 3.25 + UP * 1.2) 76 | 77 | right_arrow = TexMobject('\\Rightarrow').next_to(text_zn, DOWN * 3.75).align_to(text_zn, LEFT) 78 | 79 | text_01 = TexMobject('r', '=', '1').set_color_by_tex_to_color_map(color_dict).next_to(right_arrow, RIGHT * 2.4).shift(UP * 0.5) 80 | text_02 = TexMobject('n', '\\theta', '=', '2', 'k', '\\pi').set_color_by_tex_to_color_map(color_dict).next_to(right_arrow, RIGHT * 2.4).shift(DOWN * 0.5) 81 | text_12 = VGroup(text_01, text_02) 82 | brace = Brace(text_12, LEFT) 83 | 84 | text_03 = TexMobject('\\therefore', '\\omega^', 'n', '=', '1', '\\text{的}', 'n', '\\text{个根为:}',)\ 85 | .set_color_by_tex_to_color_map(color_dict).next_to(text_02, DOWN * 1.4).align_to(text_zn, LEFT) 86 | 87 | text_wi_01 = TexMobject('\\omega', '_k', '=', 'e^{', 'i', '{2', 'k', '\\pi', '\\over', 'n}}', 88 | ).set_color_by_tex_to_color_map(color_dict) 89 | text_wi_01.next_to(text_03, DOWN * 1.5).align_to(text_zn, LEFT) 90 | text_wi_02 = TexMobject('=', '\\cos{', '2', 'k', '\\pi', '\\over', 'n}', '+', 'i', '\\sin{', 91 | '2', 'k', '\\pi', '\\over', 'n}').set_color_by_tex_to_color_map(color_dict) 92 | text_wi_02.next_to(text_wi_01, DOWN * 1.5).align_to(text_zn, LEFT) 93 | text_wi_02[1:].scale(0.9) 94 | text_k = TexMobject('(', 'k', '=', '0', ',', '1', ',', '2', ',','\\cdots', ',', 'n-1', ')').set_color_by_tex_to_color_map(color_dict) 95 | text_k.scale(0.75).next_to(text_wi_02, DOWN * 1.5).align_to(text_zn, LEFT) 96 | 97 | ### display w_i in unit circle ### 98 | # moved to animation part 3 # 99 | 100 | ### animation part 1 ### 101 | 102 | self.play(ShowCreation(cp)) 103 | self.wait(1) 104 | 105 | self.play(ShowCreation(vect_z)) 106 | self.wait(0.5) 107 | self.play(ShowCreation(dot_z)) 108 | self.play(Write(xy_form)) 109 | self.wait(1) 110 | self.play(ReplacementTransform(xy_form, cs_form)) 111 | self.wait(1) 112 | self.play(ReplacementTransform(cs_form, exp_form)) 113 | self.wait() 114 | self.play(ShowCreation(angle_z)) 115 | 116 | # self.add(vect_group, text_group, dot_group, angle_group, line_group) 117 | for i in range(1, n): 118 | self.play(ShowCreation(vect_group[i]), run_time=0.8) 119 | self.play(ShowCreation(dot_group[i]), run_time=0.4) 120 | self.play(Write(text_group[i]), run_time=0.6) 121 | self.wait(0.2) 122 | self.play(ShowCreation(angle_group[i]), run_time=0.6) 123 | self.wait(0.4) 124 | self.wait() 125 | for i in range(0, n): 126 | self.play(ShowCreation(line_group[i]), run_time=0.4) 127 | self.wait(0.1) 128 | self.wait() 129 | 130 | all_exist = VGroup(cp, vect_group, text_group, dot_group, angle_group, line_group) 131 | self.play(all_exist.shift, cp.n2p(-2), run_time=1.5) 132 | self.wait() 133 | 134 | ### part 2 ### 135 | text_bg = Polygon(cp.n2p(2.6+2.2j), cp.n2p(5.8+2.2j), cp.n2p(5.8-2.2j), cp.n2p(2.6-2.2j), 136 | stroke_width=0, fill_color=BLACK, fill_opacity=0.75) 137 | self.play(FadeIn(text_bg), run_time=1.2) 138 | self.wait(0.5) 139 | self.play(TransformFromCopy(text_group, text_zn[0:9]), run_time=1.2) 140 | self.wait() 141 | self.play(Write(text_zn[9:11])) 142 | self.wait() 143 | self.play(Write(right_arrow)) 144 | self.play(ShowCreation(brace)) 145 | 146 | self.play(TransformFromCopy(text_zn[3:5], text_01)) 147 | self.wait() 148 | 149 | self.play(TransformFromCopy(text_zn[6:8], text_02[0:2])) 150 | self.play(Write(text_02[2:6])) 151 | self.wait() 152 | 153 | self.play(Write(text_03), run_time=2) 154 | self.wait(0.5) 155 | self.play(Write(text_wi_01), run_time=2) 156 | self.wait() 157 | self.play(Write(text_wi_02), run_time=3) 158 | self.wait() 159 | self.play(Write(text_k), run_time=2) 160 | self.wait(2) 161 | 162 | ### part 3 ### 163 | unit_circle = Circle(radius=cp.n2p(1)[0], color=BLUE_B).move_to(cp.n2p(0)) 164 | self.play(ShowCreation(unit_circle)) 165 | self.wait(0.5) 166 | z_new = np.exp(1j * TAU/11) 167 | w_1 = TexMobject('\\omega', '_1', '=', 'e^{', 'i', '{2', '\\pi', '\\over', 'n}}',).scale(0.9)\ 168 | .set_color_by_tex_to_color_map(color_dict).move_to(cp.n2p(0)).shift((cp.n2p(z_new)-cp.n2p(0))*1.2+RIGHT*1.2) 169 | dot_1 = Dot(cp.n2p(z_new), color=PINK) 170 | vect_1 = Arrow(cp.n2p(0), cp.n2p(z_new), buff=0, color=ORANGE) 171 | line_1 = Line(cp.n2p(1), cp.n2p(z_new), color=PINK) 172 | dot_0 = Dot(cp.n2p(1), color=PINK) 173 | vect_0 = Arrow(cp.n2p(0), cp.n2p(1), buff=0, color=ORANGE) 174 | w_0 = TexMobject('\\omega', '_0', color=PINK).scale(0.8).move_to(cp.n2p(1.2)) 175 | self.play(ShowCreation(vect_0)) 176 | self.play(ShowCreation(dot_0), Write(w_0)) 177 | self.play(ReplacementTransform(vect_group[0], vect_1), run_time=0.3) 178 | self.play(ReplacementTransform(dot_group[0], dot_1), run_time=0.3) 179 | self.play(ReplacementTransform(text_group[0], w_1), run_time=0.3) 180 | self.play(ReplacementTransform(line_group[0], line_1), run_time=0.3) 181 | vect_new, dot_new, line_new, text_new = VGroup(vect_1), VGroup(dot_1), VGroup(line_1), VGroup(w_1) 182 | 183 | for i in range(1, n): 184 | zn_1 = z_new ** (i+1-1) 185 | zn = z_new ** (i+1) 186 | dot_i = Dot(cp.n2p(zn), color=PINK) 187 | vect_i = Arrow(cp.n2p(0), cp.n2p(zn), buff=0, color=ORANGE) 188 | text_i = TexMobject('\\omega_{', '%d}' % (i+1), color=PINK).scale(0.8).move_to(cp.n2p(0)).shift((cp.n2p(zn)-cp.n2p(0))/abs(zn) * (abs(zn) + 0.2)) 189 | line_i = Line(cp.n2p(zn_1), cp.n2p(zn), color=PINK) 190 | angle_i = Angle(cp.n2p(zn_1), cp.n2p(0), cp.n2p(zn), radius=0.6, color=BLUE) 191 | vect_new.add(vect_i), dot_new.add(dot_i), line_new.add(line_i), text_new.add(text_i) 192 | # vect_group[i].become(vect_i) 193 | # self.wait(dt) 194 | self.play(ReplacementTransform(vect_group[i], vect_i), run_time=0.32-0.08*np.sqrt(i)) 195 | self.play(ReplacementTransform(angle_group[i], angle_i), run_time=0.32-0.08*np.sqrt(i)) 196 | self.play(ReplacementTransform(dot_group[i], dot_i), run_time=0.32-0.08*np.sqrt(i)) 197 | self.play(ReplacementTransform(text_group[i], text_i), run_time=0.32-0.08*np.sqrt(i)) 198 | self.play(ReplacementTransform(line_group[i], line_i), run_time=0.32-0.08*np.sqrt(i)) 199 | 200 | angle_11 = Angle(cp.n2p(1), cp.n2p(0), cp.n2p(np.exp(-1j * TAU/11)), radius=0.6, color=BLUE) 201 | line_11 = Line(cp.n2p(np.exp(-1j * TAU/11)), cp.n2p(1), color=PINK) 202 | self.play(ShowCreation(angle_11)) 203 | self.play(ShowCreation(line_11)) 204 | 205 | self.wait(5) 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /old/FastFourierTransform/help.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | #TODO, improve this scene 4 | class ComplexNumberex(Scene): 5 | def construct(self): 6 | plane = ComplexPlane() 7 | plane.add_coordinates() 8 | self.play(ShowCreation(plane, run_time=3, lag_ratio=0.1)) 9 | self.wait(1) 10 | t2c = { 11 | "a" : BLUE_B, 12 | "b" : BLUE_E, 13 | "i" : GOLD, 14 | "e" : BLUE, 15 | "\\theta" : YELLOW, 16 | "r" : GREEN 17 | } 18 | point = Dot([2.75, 2.25, 0]).set_color(RED) 19 | label_p = TexMobject("a", "+", "b", "i").set_color_by_tex_to_color_map(t2c) 20 | label_p.add_updater(lambda m: m.next_to(point, UP)) 21 | self.play(ShowCreation(point)) 22 | self.play(Write(label_p)) 23 | self.wait() 24 | dl_a = DashedLine() 25 | dl_a.add_updater(lambda m: m.put_start_and_end_on(point.get_center(), [point.get_center()[0], 0, 0])) 26 | dl_bi= DashedLine() 27 | dl_bi.add_updater(lambda m: m.put_start_and_end_on(point.get_center(), [0, point.get_center()[1], 0])) 28 | label_a = TexMobject("a").set_color_by_tex_to_color_map(t2c) 29 | label_a.add_updater(lambda m: m.next_to(dl_a, DOWN)) 30 | label_bi= TexMobject("b","i").set_color_by_tex_to_color_map(t2c) 31 | label_bi.add_updater(lambda m: m.next_to(dl_bi, LEFT)) 32 | self.play(ShowCreation(dl_a), ShowCreation(dl_bi)) 33 | self.play(Write(label_a), Write(label_bi)) 34 | self.play(point.shift, LEFT * 4.5 + DOWN * 2, run_time=3) 35 | self.play(MoveAlongPath(point, ArcBetweenPoints(point.get_center(), [2.75, 2.25, 0])), run_time=3) 36 | self.wait(2) 37 | r = Line(ORIGIN, point.get_center()) 38 | label_r = TexMobject("r").set_color(GREEN).next_to(r.get_center(), UP) 39 | self.play(ShowCreation(r)) 40 | self.play(Write(label_r)) 41 | angle = Angle([point.get_center()[0], 0, 0], ORIGIN, point.get_center(), color=YELLOW) 42 | label_theta = TexMobject("\\theta").set_color(YELLOW).next_to(angle, RIGHT) 43 | self.play(ShowCreation(angle)) 44 | self.play(Write(label_theta)) 45 | self.wait(2) 46 | zeq = TexMobject("=", "r", "e", "^{i", "\\theta}").set_color_by_tex_to_color_map(t2c).next_to(label_p, RIGHT) 47 | self.play(Write(zeq)) 48 | self.wait(2) -------------------------------------------------------------------------------- /old/FastFourierTransform/recordingcpp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int maxn = 2000010; 5 | const double PI = acos(-1); 6 | 7 | struct Complex { 8 | double r, i; 9 | Complex() { r = 0, i = 0; } 10 | Complex(double real, double imag): r(real), i(imag) {} 11 | }F[maxn], G[maxn]; 12 | Complex operator + (Complex a, Complex b) { return Complex(a.r + b.r, a.i + b.i); } 13 | Complex operator - (Complex a, Complex b) { return Complex(a.r - b.r, a.i - b.i); } 14 | Complex operator * (Complex a, Complex b) { return Complex(a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r); } 15 | 16 | int rev[maxn], len, lim = 1; 17 | 18 | void FFT(Complex* a, int opt) { 19 | for (int i = 0; i < lim; ++i) if (i < rev[i]) swap(a[i], a[rev[i]]); 20 | for (int dep = 1; dep <= log2(lim); ++dep) { 21 | int m = 1 << dep; 22 | Complex wn = Complex(cos(2.0 * PI / m), opt * sin(2.0 * PI / m)); 23 | for (int k = 0; k < lim; k += m) { 24 | Complex w = Complex(1, 0); 25 | for (int j = 0; j < m / 2; ++j) { 26 | Complex t = w * a[k + j + m / 2]; 27 | Complex u = a[k + j]; 28 | a[k + j] = u + t; 29 | a[k + j + m / 2] = u - t; 30 | w = w * wn; 31 | } 32 | } 33 | } 34 | if (opt == -1) for (int i = 0; i < lim; ++i) a[i].r /= lim; 35 | } 36 | 37 | int main() { 38 | int n, m; scanf("%d %d", &n, &m); 39 | for (int i = 0; i <= n; ++i) scanf("%d", &F[i].r); 40 | for (int i = 0; i <= m; ++i) scanf("%d", &G[i].r); 41 | while (lim <= n + m) lim <<= 1, len++; 42 | for (int i = 0; i < lim; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (len - 1)); 43 | FFT(F, 1); FFT(G, 1); 44 | for (int i = 0; i <= m; ++i) F[i] = F[i] * G[i]; 45 | FFT(F, -1); 46 | for (int i = 0; i <= n + m; ++i) { 47 | printf("%d ", (int)(F[i].r + 0.5)); 48 | } 49 | return 0; 50 | } -------------------------------------------------------------------------------- /old/FastFourierTransform/旁白.txt: -------------------------------------------------------------------------------- 1 | 2 | Hello,大家好 3 | 这一期视频我来讲解一下快速傅里叶变换 4 | 由于这一期视频的内容比较多 而且并不适合全部观看 5 | 所以我选择了将这期视频做成了互动视频 6 | 以便观众根据需要选择观看的方式 7 | 观看本视频最短路径需要 min 最长需要 min 8 | 由于这是我第一次做这样的视频 经验还不够 9 | 所以看完后不妨在评论区留下些反馈吧 10 | 11 | 12 | 那么首先 我们来看一下学习快速傅里叶变换算法需要哪些前置知识 13 | FFT的核心算法是基于复数和单位根的 14 | 所以 我们当然需要先了解复数的相关运算法则 15 | 而且需要了解单位根的一些独特性质 16 | 来学习快速傅里叶变换背后的原理 17 | 最后 在算法竞赛中 FFT的最普遍应用是求多项式乘法 或者说卷积 18 | 所以 如果需要学习用FFT求多项式乘法的话 也需要有多项式的相关知识 19 | 那么现在 做出你的选择吧 20 | 21 | 22 | 23 | 形如z=a+bi的数被称为复数 24 | 其中a、b为实数 i为根号-1 称为虚数单位 25 | 就如同1为实数单位一样 26 | 在复数中 a被称为实部 b被称为虚部 27 | 复数的加法运算也十分简单 28 | 只要将i看做一个字母 对原式运用分配律结合律 就能得到最后的法则 29 | 即结果的实部为两加数实部的和 30 | 结果的虚部为两加数虚部的和 31 | 如果是进行减法的话 只需将黄色符号变成减号即可 32 | 对于两复数的乘法也是同理 将i看作字母 33 | 将原式拆开 再根据i等于根号-1 i方等于-1 进行化简就能得到结果 34 | 对于除法 FFT中并没有涉及 但这里还是简要地给出 35 | 其主要思想是分数上下同乘分母的共轭复数 即c-di 36 | 使分母变为实数 再进行化简 这里直接给出公式 37 | 对于复数 还有一个很重要的定理 即欧拉定理 38 | 它可以将一个负数表示成e指数的形式 方便运算 39 | 所以一个负数也可以写成 r乘e的iθ次方 40 | 其中r为它的模 θ为它的辐角 41 | 42 | 43 | 任意一个复数a+bi对应了复平面上的一个点(a,b) 44 | 其横坐标为实部 纵坐标为虚部 45 | 通过复平面我们可以更好地理解复数 46 | 前面我们所说的模 即为它在复平面上对应的点到原点的距离 47 | 辐角即为它在复平面上对应的点到原点连线与x轴的夹角 48 | 知道了复数的运算法则 我们就能用代码来实现它了 49 | 50 | 51 | 52 | FFT的核心是用单位根的某些独特性质来快速实现的 53 | 我们知道 每个复数都可以表示为模乘以e的(i辐角)次方 54 | 所以两个复数相乘的结果即为 两复数模相乘再乘以e的(i辐角的和)次方 55 | 而单位根 是方程z^n=1在复数范围内的n个根 56 | 因为单位根的n次方为1 所以单位根的模一定为1 57 | 因此单位根乘其自身就相当于辐角加一倍 58 | 由于每个单位根的n次方都落在复平面上(1,0)这个点 59 | 所以每个单位根的辐角的n倍都是2π的倍数 60 | 那我们就可以轻松地找到这些点 61 | 并使用欧拉定理 将其写成实部加i乘虚部的形式 62 | 我们也可以发现 单位根都均匀地落在单位圆上 63 | 每个单位根都可以看成 这个 单位根的幂 64 | 所以我们将这个根称为主n次单位根 记为w_n 65 | 66 | 67 | 下面我们来探寻一下单位根的三个重要引理 68 | 首先是消去引理 即w_{dn}^{dk}=w_n^k 69 | 我们用定义可以轻松地推出这个结论 70 | 在复平面上 我们可以更简单地理解这个结论 71 | 在图上可以看出 主dn次单位根的dk次幂 72 | 恰好与主n次单位根的k次幂相重合 73 | 第二个是折半引理 也是FFT的核心 74 | 同理 我们先用计算来推出这个结论 75 | 然后在复平面上 我们以8次单位根为例 76 | 将主8次单位根平方 即辐角加倍 77 | 再将主8次单位根的(1+4)次幂平方 78 | 也可以发现 这两个点重合了 79 | 同时 这两个点也和主4次单位根重合 80 | 这也就用复平面解释了这个引理 81 | 第三个是求和引理 将在逆FFT中用到 82 | 我们将任意一个单位根求其几何级数 83 | 根据等比数列求和公式 就可以计算出 84 | 这个值恒等于0 85 | 86 | 87 | 88 | 在算法竞赛中FFT经常用来处理多项式乘法的内容 89 | 那么我们现在来了解一下关于多项式的前置知识 90 | 首先多项式是指由未知数和系数通过有限次加减法 91 | 乘法以及自然数幂次的乘方运算得到的代数表达式 92 | 如下F(x)就是一个n次多项式 93 | 在算法竞赛中 经常处理的就是这样的一元多项式 94 | 对于这个多项式 我们还可以用Σ来简单表示 95 | 其中多项式的次数 就是最高次的次数 96 | 记为degree(F)=n 97 | 多项式的次数界 指任何一个严格大于多项式次数的整数 98 | 由于FFT只能处理2的幂次的长度 所以要引入次数界的概念来将多项式扩展次数 99 | 下面我们来看多项式的运算法则 100 | 首先多项式的加法 101 | 现有两个多项式A(x)和B(x) 将其相加 102 | 可以将AB中x的次数相等的两项加在一起 103 | 最后就得到了结果的多项式C(x) 104 | 当然 我们可以用∑来简写 105 | 其中的系数c_i 即为对应相等x次数的项的系数之和a_i加b_i 106 | 107 | 108 | 再来看一下多项式的乘法 109 | 我们先以一个具体的例子为例 110 | 将这两个多项式相乘 可以用第二个多项式的每一项 111 | 乘以第一个多项式 得到三个多项式 112 | 再对三个多项式进行加法运算 得到最终的结果 113 | 通过结果可以发现 结果的次数为两多项式次数的和 114 | 再推广到两同次多项式相乘的情况 给出两个n次多项式AB求其乘积C 115 | 根据刚刚的结论 可以知道结果的次数为2n 116 | 它的系数根据前面的计算方法可以稍加演算推导出来 117 | 而这个系数向量c又被称为向量ab的卷积 118 | 再一般的情况为了计算简便 119 | 可以将两个多项式的次数用添加0系数的方法升至次数界中的同一次数n 120 | 那么其乘积也是次数为2n的多项式 121 | 122 | 123 | 多项式有两种表示方法 124 | 第一种是系数表示 也是平时最常用最直观的表示方法 125 | 它将一个多项式表示成由其系数构成的向量的形式 126 | 用系数表示进行运算时 127 | 加法直接将对应项相加 时间复杂度O(n) 128 | 乘法则计算两多项式系数向量的卷积 复杂度O(n^2) 129 | 已知系数 给出一个x值并求A(x)的过程叫求值 130 | 可以直接使用霍纳法则即秦九韶算法 复杂度O(n) 131 | 第二种表示方法是点值表示 即用至少n个多项式上的点来表示 132 | 使用点值表示进行运算时 一般要保证两多项式在同一位置取值 即x_i相同 133 | 进行加法运算 直接依次将两点纵坐标相加 复杂度O(n) 134 | 进行乘法运算 只需将两点纵坐标相乘 135 | 复杂度也是O(n) 远好于系数表式的O(n^2) 136 | 已知点值 给出一个x值并求A(x)的过程叫插值 137 | 一般的 我们可以根据拉格朗日插值公式来进行计算 复杂度O(n^2) 138 | 139 | 140 | 141 | 那么现在我们步入正题 什么是快速傅里叶变换 142 | 首先我们要了解离散傅里叶变换(discrete fourier transform) 143 | 离散傅里叶变换是对于一个向量进行的变换 144 | 可以将这个向量看成一个n-1次多项式 145 | 并在每个单位根处求值 得出向量y 就是离散傅里叶变换后的结果 146 | 记为y=DFT_n(a) 也可以记为y=花体F(a) 147 | 直接使用霍纳法则求值的话 一次求值复杂度O(n) 148 | 求n个值的总复杂度就是O(n^2) 149 | 而快速傅里叶变换(Fast Fourier Transform) 150 | 是一种快速进行离散傅里叶变换的方法 151 | 它可以通过单位根的性质 将n次求值的复杂度降为O(nlog n) 152 | 153 | 154 | 首先对于这个n-1次多项式 它的系数向量为a 155 | 我们将其分为偶数项和奇数项两个向量 记为a^[0]和a^[1] 156 | 它们对应的两个多项式为A^[0]和A^[1] 157 | 现在将x代入 写出的A(x)的表达式是这样的 158 | A^[0](x)和A^[1](x)的表达式是这样的 159 | 我们来想想办法把这三个表达式关联起来 160 | 把后两个表达式的自变量x换成x^2 161 | 我们会发现第二个表达式的项在第一个表达式中全部出现 162 | 而第三个表达式中的每一项都差了一个x 163 | 所以我们在它的前面乘以一个x 164 | 最后我们可以发现 A(x)=A^0(x^2)+xA^1(x^2) 165 | 这是我们就将原问题求A(x)在每个单位根上的值转化为 166 | 求次数界为n/2的两个多项式A^0(x)和A^1(x)在每个单位根平方上的值 再合并 167 | 我们代入两个具体单位根来看一看情况 168 | 169 | 170 | 根据我们之前提过的折半引理和消去引理 可以写出如下表达式 171 | 所以w_n^k方和w_n^{k+n/2}方均可以写成w_{n/2}^k 172 | 而A^0(x)和A^1(x)恰好均为次数界为n/2的多项式 173 | 所以问题又转化为了求 174 | 次数界为n/2的多项式A^0和A^1在各个n/2次单位根上的值 175 | 这两个问题和原问题的描述类似 只是原问题的次数界为n 176 | 所以 这两个问题是范围缩小一半的两个子问题 177 | 我们可以用同样方式求解这两个子问题(也就是递归解决) 178 | 再根据折半引理 就可以快速地合并结果 179 | 根据这个思想 我们可以写出运行时间T(n)的递归式 180 | 总的时间等于2倍的子问题时间加O(n)的合并时间 181 | 再根据主定理或者递归树 均可以推算出这个算法的时间复杂度为O(nlog n) 182 | 比代入公式求解的O(n^2)快了很多很多 183 | 184 | 185 | 了解了算法原理之后 我们来实现以下FFT算法 186 | 在本段视频内将以伪代码方式呈现 187 | 由于目前FFT是递归操作 所以我们要先设置递归边界 188 | 当输入向量的长度是1的时候 我们不需要处理 189 | 因为只有一个元素的向量FFT后的结果还是其本身 190 | 所以我们直接返回即可 191 | 如果没有到达边界 则需要将原向量按下标分成奇偶两个向量 192 | 再分别执行相同的FFT操作 193 | 注意次数界要除以二 也就相当于右移一位 194 | 在两个子问题解决完之后 我们要进行合并 195 | 根据之前推导的结论 可以发现 196 | 合并到第k组值的时候 需要主n次单位根的k次方来乘奇数项的值 197 | 我们通常将这个主n次单位根的k次方称为旋转因子 198 | 所以我们不妨设一个常量作为主n次单位根 199 | 再设一个变量来作为旋转因子 200 | 并且当k为0时其值为1 所以设w=1 201 | 然后执行主合并操作 一共n/2次 202 | 首先在这个循环末尾 我们每次要将旋转因子乘以w_n 203 | 来保证第k次执行的时候 w=w_n^k 204 | 然后根据前面推导过的公式 就可以执行合并了 205 | 这样 对一个数组执行FFT之后的结果就覆盖了原来的值 也节省了空间 206 | 但需要注意的一点是 输入的lim一定要保证是2的幂 207 | 而且a数组不能比lim小 208 | 这样就可以做到将a数组扩大到2的幂 并且补位的高次项系数为0 不干扰i结果 209 | 210 | 211 | 这里我将针对在算法竞赛中常用的C++语言来具体实现这个伪代码 212 | 首先我们要定义常数PI 也就是acos(-1) 213 | 复数模板在前面已经介绍过了 这里不再赘述 214 | 对于FFT函数 我们要传入两个参数 一个是复数数组a 另一个是次数界lim 215 | 当lim=1的时候 什么都不做 直接返回 216 | 其余情况 先对原数组进行分组 217 | 创建两个新复数数组 a0 a1 218 | 然后对下标的奇偶进行分类 写入这两个新数组中 219 | 之后对两个数组执行FFT 传入的次数界为lim的一半也就是右移一位 220 | 合并时先定义两个变量 一个是主n次单位根 另一个是旋转因子 221 | 进行循环 从0开始到小于lim的一半 222 | 根据公式或者伪代码 可以写出这一段 223 | 在循环的结尾 将旋转因子乘以主n次单位根 224 | 这样我们就实现了这个算法 225 | 226 | 227 | 228 | 现在我们来考虑一下如何能使这个算法更高效 229 | 首先 我们可以发现伪代码的第9、10行含有一个公共子表达式 230 | 由于复数乘法运算比较慢 所以不妨将其计算一次存在变量t中 231 | 在合并时用a0加t和减t 可以使运算更快一点 232 | 这样的一次操作 叫做 一次蝴蝶操作 233 | 然后 我们来考虑如何不使用递归 而是使用迭代来实现 234 | 我们可以观察一下每次递归传给FFT函数的a数组的内容 235 | 每次都把当前数组的奇数位和偶数位分开 236 | 最后得到的结果就是这样 237 | 我们如果能知道递归最终的顺序 并按照顺序重新排列 238 | 那么只需要合并就可以解决 不需要向下递归的时间 239 | 也节省了递归所需要的空间 240 | 现在我们假定可以实现数组的重新排列 241 | 来考虑一下如何实现合并 242 | 先来标记一下合并的层数 243 | 根据前面 我们知道每次合并时都需要一个旋转因子 244 | 而通过观察 我们可以发现 245 | 每次合并时需要的主n次单位根的n取决于合并后的数组有多少个元素 246 | 而有多少个元素有可以根据当前合并的层数来确定 247 | 现在我们来尝试实现这个算法的伪代码 248 | 先对原数组重新排列 249 | 再用一个循环来确定当前合并的层数 从1到次数界的对数 250 | 然后定义两个常量 表示合并后序列的长度m 和主m次单位根 251 | 再用一个循环对每隔m的一组执行蝴蝶操作 252 | 定义一个变量作为旋转因子 253 | 然后再用一个循环对每组内对应的数进行操作 254 | 和之前同理 在循环的结尾要对旋转因子进行更新 255 | 剩下的就是蝴蝶操作了 256 | 257 | 258 | 现在再来思考一下如何求出需要的顺序 这个操作被称为位逆序置换 259 | 先分析一下最后下标的规律 260 | 将下标分离出来 再化为二进制 261 | 不难发现 需要的下标的二进制和当前位置的二进制恰好互为倒序 262 | 所以这个操作被称为位逆序置换 263 | 执行位逆序置换 我们可以用nlogn的复杂度直接模拟 264 | 但效率不是很高 我们也可以在O(n)的复杂度内实现预处理 265 | 还是来探究一下位逆序置换的规律 266 | 第一个规律 不难发现偶数位上的二进制数首位为0 267 | 奇数位上的二进制数首位为1 268 | 第二个规律也不难发现 每两个二进制数除了首位之外的每一位都相同 269 | 那么这些相同的位有有什么规律呢 270 | 进一步观察可以发现 它们是上一级子问题的解 271 | 也就是只含2位的二进制数的位逆序置换 272 | 有了这个经验我们也可以发现第四个规律 273 | 前一半结果的二进制数除最后一位外也是上一级子问题的解 274 | 所以我们可以写出一个递推公式来推出第i位上需要的下标 275 | 先找到子问题的解 也就是i/2位置上的二进制数右移一位 276 | 即 取它的前n-1位 277 | 然后确定首位是0还是1 278 | 将i和1做按位与运算 若i是奇数则结果为1 反之为0 279 | 在左移总位数-1位将其移动到首位 280 | 将两部分做按位或运算 就可以将首位和其他位合并在一起 281 | 这样在O(n)时间内就能完成对最终顺序的预处理 282 | 283 | 根据这个算法流程 我们可以画出这样一个图 284 | 输入一个数组a 先对它进行位逆序置换操作 285 | 然后每层每组执行蝴蝶操作 286 | 最后输出结果数组y 287 | 288 | 289 | 290 | 在实现这个算法时 首先需要预处理出一个rev数组 291 | 设n表示a数组的原长度 292 | 定义一个变量lim表示次数界 293 | 将lim从1左移至大于n 并记录下左移的次数 也就是二进制数的位数 294 | 根据前面推导的递推式 可以预处理出rev数组 295 | 在FFT函数的开始 需要按照rev中的编号对a数组排序 296 | 排序后根据前面的伪代码 就可以一点一点完成这个函数了 297 | 298 | 299 | 300 | 现在我们再来讨论一下快速傅里叶变换逆变换 301 | --2x 302 | FFT求的离散傅里叶变换的公式是这样 303 | 我们可以把它写成矩阵与向量相乘的形式 304 | 其中的Vn是一个范德蒙德矩阵 305 | 它的第i行第j列的元素为主n次单位根的ij次方 306 | 离散傅里叶变换给出a求y 而离散傅里叶逆变换给出y求a 307 | 所以要用Vn的逆矩阵乘向量y 308 | 这里给出 Vn的逆矩阵的第i行第j列元素为n分之主n次单位根的-ij次方 309 | 我们可以用Vn与这个矩阵相乘来验证结论 310 | 将这两个矩阵相乘 对第i行第j列的元素进行化简 311 | 根据最后的结果和前面所说的求和引理可以发现 312 | 只有当i=j也就是处于对角线上时 这个值为1 313 | 其余情况下全为0 所以结果是一个单位矩阵 314 | 所以我们给出的矩阵确实是Vn的逆矩阵 315 | 我们再将这个逆矩阵代入 316 | 再进行化简 提出分母的n 317 | 我们可以发现 逆变换的公式和傅里叶变换的公式十分类似 318 | 除了逆变换结果需要乘以1/n之外 逆变换中是主n次单位根的-i次方 319 | 所以我们可以使用和傅里叶变换的同样方法 320 | 仅仅将程序中的主n次单位根改为主n次单位根的-1次方 321 | 就可以使用相同的程序解决了 322 | 2x-- 323 | 324 | 325 | 根据前面快速傅里叶逆变换的思想 326 | 可以仅仅在FFT的代码基础上稍作更改 来同时实现两个变换 327 | 由于两个变换不同的地方仅仅是主n次单位根虚部的正负 328 | 所以可以向FFT函数中传入一个参数来确定是哪一个变换 329 | 在定义主n次单位根时 用opt乘虚部 330 | 此时 若opt为1则表示为离散傅里叶变换 若opt为-1则表示为逆变换 331 | 在函数的结尾 我们还需要判断一下opt是否为-1 332 | 若是-1 则还需要将每个元素除以元素个数 也就是lim 333 | 334 | 335 | 336 | 最后我们来实现FFT在算法竞赛中最常见的应用 337 | 也就是求多项式乘积 即两向量的卷积 338 | 求两个向量的卷积 可以用O(nlogn)的时间求出两个向量的离散傅里叶变换 339 | 即将系数表式转化为点值表示 340 | 然后 在O(n)时间内对两个结果逐元素相乘 也就是点值表示中的乘法 341 | 最后再用O(nlogn)的时间求出乘法结果的逆傅里叶变换 342 | 也就是将点值表示转化为系数表式 343 | 这样就可以在O(nlogn)的时间复杂度内算出卷积 344 | 其中需要注意 两个向量的长度需要统一到同一2的幂 345 | 并且输入时的长度应扩大1倍 否则不足以进行最后的逆变换 346 | 在实现时 我们同时完成这两个目标 直接将lim左移至大于两数组的长度和 347 | 先输入两个多项式的次数n和m 348 | 然后输入各项系数 将他们存在F和G数组的实部中 349 | 再预处理出lim和rev数组 350 | 分别对F和G进行快速傅里叶变换 351 | 再逐项相乘 保存在F数组中 352 | 再对F数组进行快速傅里叶逆变换 353 | 就可以得到最后的卷积了 354 | 355 | 356 | 357 | 那么这就是这一期视频的全部内容了 358 | 这一期视频中 我们学习了快速傅里叶变换的原理和具体的代码实现 359 | 并了解了快速傅里叶逆变换的原理 并进行了简单的卷积运算 360 | 感谢您观看到这里 希望您能在评论区里给出反馈 361 | 制作这一期视频非常不易 点击三连支持一下up主吧 362 | 想看到更多关于算法的讲解呢 不妨点一下关注 363 | 那么我们下一期再见 364 | -------------------------------------------------------------------------------- /old/HomeworkV2.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_projects.tony_useful.imports import * 3 | from manim_sandbox.utils.imports import * 4 | 5 | class Homework_02(Scene): 6 | def construct(self): 7 | self.intro_problem() 8 | self.main_proof() 9 | 10 | def intro_problem(self): 11 | problem = TexMobject("1^3+2^3+3^3+\\cdots +n^3=?") 12 | VGroup(problem[0][1], problem[0][4], problem[0][7], problem[0][14]).set_color(GOLD) 13 | self.wait() 14 | self.play(Write(problem[0][:15])) 15 | self.wait() 16 | self.play(Write(problem[0][15:])) 17 | self.wait(3) 18 | self.play(problem.to_edge, UP) 19 | self.wait() 20 | self.problem = problem 21 | 22 | def main_proof(self): 23 | unit = 0.4 24 | sq = VGroup() 25 | sq.add(Square(side_length=unit).move_to(np.array([-5.2, 2.6, 0]))) 26 | for num in range(2, 6): 27 | sq.add(VGroup( 28 | *[ 29 | Square(side_length=unit*num) 30 | for i in range(num) 31 | ] 32 | ).arrange(RIGHT, buff=0).next_to(sq[-1], DOWN, aligned_edge=LEFT, buff=0)) 33 | # self.add(sq) 34 | ver1 = sq[0].get_vertices() 35 | ver2 = sq[1][-1].get_vertices() 36 | ver3 = sq[2][-1].get_vertices() 37 | ver4 = sq[3][-1].get_vertices() 38 | ver5 = sq[4][-1].get_vertices() 39 | line = Line(ver1[0], ver5[2]+RIGHT*unit*5) 40 | line2 = Line(ver5[2]+RIGHT*unit*5, ver5[2]) 41 | # self.add(line, line2) 42 | 43 | area = VGroup( 44 | VGroup( 45 | Polygon(ver1[0], mid(ver1[1], ver1[2]), ver1[2], ver1[3], ver1[0]), 46 | Polygon(ver1[0], mid(ver1[1], ver1[2]), ver1[1], ver1[0]) 47 | ), 48 | VGroup( 49 | sq[1][0].copy(), 50 | Polygon(ver2[0], mid(ver2[1], ver2[2]), ver2[2], ver2[3], ver2[0]), 51 | Polygon(ver2[0], mid(ver2[1], ver2[2]), ver2[1], ver2[0]) 52 | ), 53 | VGroup( 54 | sq[2][0].copy(), sq[2][1].copy(), 55 | Polygon(ver3[0], mid(ver3[1], ver3[2]), ver3[2], ver3[3], ver3[0]), 56 | Polygon(ver3[0], mid(ver3[1], ver3[2]), ver3[1], ver3[0]) 57 | ), 58 | VGroup( 59 | sq[3][0].copy(), sq[3][1].copy(), sq[3][2].copy(), 60 | Polygon(ver4[0], mid(ver4[1], ver4[2]), ver4[2], ver4[3], ver4[0]), 61 | Polygon(ver4[0], mid(ver4[1], ver4[2]), ver4[1], ver4[0]) 62 | ), 63 | VGroup( 64 | sq[4][0].copy(), sq[4][1].copy(), sq[4][2].copy(), sq[4][3].copy(), 65 | Polygon(ver5[0], mid(ver5[1], ver5[2]), ver5[2], ver5[3], ver5[0]), 66 | Polygon(ver5[0], mid(ver5[1], ver5[2]), ver5[1], ver5[0]) 67 | ) 68 | ) 69 | colors = color_gradient([BLUE, YELLOW], 5) 70 | for i, mob in enumerate(area): 71 | mob.set_fill(colors[i], 0.5) 72 | mob.set_stroke(color=colors[i]) 73 | # for i in range(5): 74 | # area[i][-1].rotate(PI, axis=IN, about_point=area[i][-2].get_vertices()[1]) 75 | 76 | text = VGroup( 77 | *[ 78 | TexMobject("{}\\times {}^2".format(i, i)).scale(0.8) 79 | for i in range(1, 6) 80 | ] 81 | ) 82 | text2 = VGroup( 83 | *[ 84 | TexMobject("{}^3".format(i)).scale(0.8) 85 | for i in range(1, 6) 86 | ] 87 | ) 88 | text3 = VGroup( 89 | *[ 90 | TexMobject("{}".format(i)).scale(0.8) 91 | for i in range(1, 6) 92 | ] 93 | ) 94 | for i, mob in enumerate(text): 95 | mob.next_to(sq[i][0], LEFT) 96 | for i, mob in enumerate(text2): 97 | mob.next_to(sq[i][0], LEFT) 98 | for i, mob in enumerate(text3): 99 | mob.next_to(sq[i][0], LEFT) 100 | text4 = TexMobject("\\frac{1}{2}n(n+1)").scale(0.6).move_to(text3, aligned_edge=RIGHT) 101 | text5 = TexMobject("n(n+1)").scale(0.6).next_to(sq[-1][2], DOWN) 102 | 103 | areaeq = TextMobject("Area=").set_color(ORANGE).next_to(self.problem, LEFT) 104 | ans = TexMobject("\\left(\\frac{1}{2}n(n+1)\\right)^2").move_to(self.problem[0][-1], aligned_edge=LEFT) 105 | 106 | self.wait() 107 | self.play(ShowCreation(sq), run_time=5, rate_func=linear) 108 | self.wait() 109 | for i in range(5): 110 | self.play(TransformFromCopy(sq[i], text[i])) 111 | self.wait(2) 112 | for i in range(5): 113 | self.play(ReplacementTransform(text[i], text2[i])) 114 | self.wait() 115 | for i in range(5): 116 | self.play(ShowCreation(area[i])) 117 | self.remove(sq) 118 | self.play(Write(areaeq)) 119 | self.wait(3) 120 | for i in range(5): 121 | self.play( 122 | Rotating(area[i][-1], radians=PI, axis=IN, about_point=area[i][-2].get_vertices()[1], 123 | rate_func=smooth, run_time=1) 124 | ) 125 | self.wait(2) 126 | self.play(text2.shift, RIGHT*12) 127 | self.play(Write(text3)) 128 | self.wait() 129 | self.play(ReplacementTransform(text3, text4)) 130 | self.wait() 131 | self.play(Write(text5)) 132 | self.wait(2) 133 | self.play(FadeOut(self.problem[0][-1])) 134 | self.play(TransformFromCopy(VGroup(text4, text5), ans)) 135 | self.wait(2) 136 | target = VGroup( 137 | self.problem[0][:-1].copy(), ans.copy() 138 | ).center().scale(1.2).shift(UP*2) 139 | bg = BackgroundRectangle(target, buff=0.25) 140 | self.play( 141 | FadeOut(VGroup(text2, text4, text5)), 142 | FadeOut(areaeq), 143 | FadeIn(bg), 144 | Transform(VGroup(self.problem[0][:-1], ans), target), 145 | ) 146 | self.wait(4) 147 | 148 | 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /old/HomeworkV3.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Homework_03(Scene): 4 | CONFIG = { 5 | "camera_config": { 6 | "background_color": WHITE, 7 | "use_plot_depth": True, 8 | }, 9 | } 10 | def construct(self): 11 | circle = Circle(radius = 3, color = DARK_BLUE, plot_depth=3).flip() 12 | center = Dot(color=GREEN) 13 | A = Dot(np.array([-2, 0, 0]), color = RED) 14 | alpha = ValueTracker(0.0001) 15 | B = Dot(color=BLUE, radius=0.07, plot_depth=4) 16 | B.add_updater(lambda m: m.move_to(circle.point_from_proportion(alpha.get_value()))) 17 | line1 = DashedLine(A.get_center(), B.get_center(), color=DARK_BROWN) 18 | line1.add_updater(lambda m: m.put_start_and_end_on(A.get_center(), B.get_center())) 19 | C = Dot(color=BLUE, radius=0.07, plot_depth=4) 20 | C.add_updater(lambda m: m.move_to(circle.point_from_proportion(alpha.get_value())).flip(axis=B.get_center()-A.get_center(), about_point=ORIGIN)) 21 | line2 = Line(B.get_center(), C.get_center(), color=ORANGE, stroke_width=3) 22 | line2.add_updater(lambda m: m.put_start_and_end_on(B.get_center(), C.get_center())) 23 | 24 | trace = VGroup() 25 | self.i = 0 26 | def update_trace(m): 27 | self.i += 1 28 | if self.i % 4 == 0: 29 | m.add(line2.copy().clear_updaters()) 30 | 31 | self.wait(3) 32 | self.play(ShowCreation(circle), ShowCreation(center)) 33 | self.wait() 34 | self.play(ShowCreation(A)) 35 | alpha.set_value(0.2) 36 | self.play(ShowCreation(B)) 37 | self.play(alpha.increment_value, 0.6, run_time=1.5) 38 | self.play(alpha.increment_value, -0.6, run_time=1.6) 39 | self.play(ShowCreation(line1)) 40 | self.wait() 41 | self.play(ShowCreation(C), ShowCreation(line2)) 42 | self.wait() 43 | self.play(alpha.increment_value, 0.6, run_time=1.5) 44 | self.play(alpha.increment_value, -0.7999, run_time=2, rate_func=linear) 45 | self.wait() 46 | self.add(trace) 47 | line2.set_stroke(width=2) 48 | self.wait(2) 49 | trace.add_updater(update_trace) 50 | alpha.set_value(0) 51 | anim = ApplyMethod(alpha.increment_value, 1, run_time=8, rate_func=linear) 52 | self.play(anim) 53 | self.wait(2) 54 | 55 | ellipse = Ellipse(width=6, height=2*np.sqrt(5), color=GREEN, plot_depth=10, run_time=2.5) 56 | self.play(ShowCreationThenDestruction(ellipse)) 57 | self.wait(5) 58 | -------------------------------------------------------------------------------- /old/HowToMakeAVideo/ArticleCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/HowToMakeAVideo/ArticleCover.png -------------------------------------------------------------------------------- /old/HowToMakeAVideo/How.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class ArticleCover(Scene): 4 | def construct(self): 5 | title = VGroup( 6 | Text("如何使用", font="Source Han Serif CN").scale(1), 7 | TextMobject("manim").scale(2.5), 8 | Text("制作一期视频", font="Source Han Serif CN").scale(1) 9 | ) 10 | title[0].set_color(BLUE_D) 11 | title[2][:4].set_color(BLUE_D) 12 | title[2][4:].set_color(RED_D) 13 | title[1][0][0].set_color(BLUE) 14 | title[1][0][1:].set_color(YELLOW) 15 | title[1].next_to(title[0], RIGHT, aligned_edge=DOWN) 16 | title[2].next_to(title[1], DOWN, aligned_edge=RIGHT) 17 | title.move_to(RIGHT * 2 + UP * 0.5) 18 | back = VGroup( 19 | Text("如何使用", font="Source Han Serif CN").set_stroke(width=8, opacity=0.4), 20 | Text("制作一期视频", font="Source Han Serif CN").set_stroke(width=8, opacity=0.4) 21 | ).set_color(BLUE_B) 22 | back[1][4:].set_color(RED_B) 23 | back[0].move_to(title[0]) 24 | back[1].move_to(title[2]) 25 | title2 = Text("& 停 更 通 知", font="Source Han Serif CN").set_stroke(width=2).scale(0.5) 26 | title2.set_color(GOLD).scale(1.2).next_to(title[2], DOWN, aligned_edge=RIGHT) 27 | author = TextMobject("@鹤翔万里").scale(1).set_color([BLUE, YELLOW, ORANGE, RED]).next_to(title, DOWN, buff=1.2) 28 | author.next_to(title2, LEFT, buff=1) 29 | 30 | self.add(back, title, title2, author) 31 | self.wait() -------------------------------------------------------------------------------- /old/HowToMakeAVideo/RL0H1%)%~`ODJ]PPM1D91NC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/HowToMakeAVideo/RL0H1%)%~`ODJ]PPM1D91NC.png -------------------------------------------------------------------------------- /old/Others/Threebody.py: -------------------------------------------------------------------------------- 1 | from big_ol_pile_of_manim_imports import * 2 | from manim_projects.MyUsefulScene.VideoStart import VideoStart 3 | from manim_projects.MyUsefulScene.VideoCover import VideoCover 4 | 5 | class LastVideo(Scene): 6 | def construct(self): 7 | title = TextMobject("硬核模拟三体运动") 8 | title.set_color(YELLOW) 9 | title.scale(1.2) 10 | title.to_edge(UP) 11 | screen_rect = ScreenRectangle(height = 6).set_color(BLACK) 12 | screen_rect.next_to(title, DOWN) 13 | 14 | self.play(Write(title)) 15 | self.play(ShowCreation(screen_rect)) 16 | self.wait(6) 17 | 18 | class Prefix(Scene): 19 | def construct(self): 20 | text = Title("前置知识").set_color(BLACK) 21 | self.play(ShowCreation(text)) 22 | 23 | know1 = TextMobject("万有引力定律").next_to(text, DOWN, buff=1).to_edge(LEFT, buff = 1.5).set_color(BLACK) 24 | detail1 = TexMobject("F=\\frac{G\\times m_1m_2}{r^2}").next_to(know1, DOWN, buff=0.85).set_color(RED) 25 | detail12= TexMobject("G=6.67\\times 10^{-11}Nm^2/kg^2").scale(0.5).next_to(detail1, DOWN).set_color(RED) 26 | self.play(Write(know1), Write(detail1), Write(detail12)) 27 | self.wait(1) 28 | 29 | know2 = TextMobject("匀变速直线运动").next_to(text, DOWN, buff=1).to_edge(RIGHT, buff = 1.5).set_color(BLACK) 30 | detail21 = TextMobject("牛二:$F=ma$").next_to(know2, DOWN, buff=0.85).set_color(RED) 31 | detail22 = TexMobject("v=v_0 + at").next_to(detail21, DOWN, buff=0.65).set_color(RED) 32 | detail23 = TexMobject("x=x_0 + v_0t + \\frac{1}{2}at^2").next_to(detail22, DOWN, buff=0.55).set_color(RED) 33 | self.play(Write(know2), Write(detail21), Write(detail22), Write(detail23)) 34 | self.wait(3) -------------------------------------------------------------------------------- /old/Others/VisualQSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : VisualQSort.py 3 | > Author : Tony 4 | > Created Time : 2019/06/05 20:09:35 5 | ''' 6 | 7 | from big_ol_pile_of_manim_imports import * 8 | from manim_projects.MyUsefulScene.VideoStart import VideoStart 9 | from manim_projects.MyUsefulScene.VideoCover import VideoCover 10 | 11 | 12 | class VideoTitle(VideoStart): 13 | CONFIG = { 14 | "title_name": "快速排序", 15 | "subtitle_name" : "可视化呈现(利用$Processing$)" 16 | } 17 | 18 | class Cover(VideoCover): 19 | CONFIG = { 20 | "en_title_name" : "Quick Sort", 21 | "title_name" : "快速排序", 22 | "subtitle_name" : "可视化呈现(利用$Processing$)" 23 | } 24 | 25 | class Write200(Scene): 26 | def construct(self): 27 | text = TextMobject("$200$个数值").scale(5) 28 | self.play(Write(text)) 29 | self.wait(4) 30 | self.play(FadeOutAndShift(text)) 31 | 32 | class Write500(Scene): 33 | def construct(self): 34 | text = TextMobject("$500$个数值").scale(5) 35 | self.play(Write(text)) 36 | self.wait(4) 37 | self.play(FadeOutAndShift(text)) 38 | 39 | class Write1000(Scene): 40 | def construct(self): 41 | text = TextMobject("$1000$个数值").scale(5) 42 | self.play(Write(text)) 43 | self.wait(4) 44 | self.play(FadeOutAndShift(text)) 45 | 46 | class End(Scene): 47 | def construct(self): 48 | text = TextMobject("本可视化使用","$Processing$","实现") 49 | text[1].set_color(RED) 50 | text2 = TextMobject("需要源码可以私信$up$主").next_to(text,DOWN).scale(0.8) 51 | self.play(Write(text)) 52 | self.play(Write(text2)) 53 | self.wait(4) 54 | self.play( 55 | FadeOut(text), 56 | FadeOut(text2) 57 | ) 58 | self.wait(2) -------------------------------------------------------------------------------- /old/PeriodicTable/data/Atomic_radii_of_the_elements_(data_page).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/data/Atomic_radii_of_the_elements_(data_page).pdf -------------------------------------------------------------------------------- /old/PeriodicTable/data/Covalent_radius.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/data/Covalent_radius.pdf -------------------------------------------------------------------------------- /old/PeriodicTable/data/Electronegativities_of_the_elements_(data_page).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/data/Electronegativities_of_the_elements_(data_page).pdf -------------------------------------------------------------------------------- /old/PeriodicTable/data/Electronegativity.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/data/Electronegativity.pdf -------------------------------------------------------------------------------- /old/PeriodicTable/data/Molar_ionization_energies_of_the_elements.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/data/Molar_ionization_energies_of_the_elements.pdf -------------------------------------------------------------------------------- /old/PeriodicTable/data/第一电离能.csv: -------------------------------------------------------------------------------- 1 | 1312 2 | 2372.3 3 | 520.2 4 | 899.5 5 | 800.6 6 | 1086.5 7 | 1402.3 8 | 1313.9 9 | 1681 10 | 2080.7 11 | 495.8 12 | 737.7 13 | 577.5 14 | 786.5 15 | 1011.8 16 | 999.6 17 | 1251.2 18 | 1520.6 19 | 418.8 20 | 589.8 21 | 633.1 22 | 658.8 23 | 650.9 24 | 652.9 25 | 717.3 26 | 762.5 27 | 760.4 28 | 737.1 29 | 745.5 30 | 906.4 31 | 578.8 32 | 762 33 | 947 34 | 941 35 | 1139.9 36 | 1350.8 37 | 403 38 | 549.5 39 | 600 40 | 640.1 41 | 652.1 42 | 684.3 43 | 702 44 | 710.2 45 | 719.7 46 | 804.4 47 | 731 48 | 867.8 49 | 558.3 50 | 708.6 51 | 834 52 | 869.3 53 | 1008.4 54 | 1170.4 55 | 375.7 56 | 502.9 57 | 538.1 58 | 534.4 59 | 527 60 | 533.1 61 | 540 62 | 544.5 63 | 547.1 64 | 593.4 65 | 565.8 66 | 573 67 | 581 68 | 589.3 69 | 596.7 70 | 603.4 71 | 523.5 72 | 658.5 73 | 761 74 | 770 75 | 760 76 | 840 77 | 880 78 | 870 79 | 890.1 80 | 1007.1 81 | 589.4 82 | 715.6 83 | 703 84 | 812.1 85 | 899.003 86 | 1037 87 | 380 88 | 509.3 89 | 499 90 | 587 91 | 568 92 | 597.6 93 | 604.5 94 | 584.7 95 | 578 96 | 581 97 | 601 98 | 608 99 | 619 100 | 627 101 | 635 102 | 642 103 | 470 104 | 580 105 | 665 106 | 757 107 | 740 108 | 730 109 | 800 110 | 960 111 | 1020 112 | 1155 113 | 707.2 114 | 832.2 115 | 538.3 116 | 663.9 117 | 736.9 118 | 860.1 119 | 462 120 | 563.3 121 | 122 | 300 123 | 540 124 | -------------------------------------------------------------------------------- /old/PeriodicTable/data/第三电离能.csv: -------------------------------------------------------------------------------- 1 | 0, 0, 11815, 14848.70, 3659.7, 4620.5, 4578.1, 5300.5, 6050.4, 6122, 6910.3, 7732.7, 2744.8, 3231.6, 2914.1, 3357, 3822, 3931, 4420, 4912.4, 2388.6, 2652.5, 2830, 2987, 3248, 2957, 3232, 3395, 3555, 3833, 2963, 3302.1, 2735, 2973.7, 3470, 3565, 3860, 4138, 1980, 2218, 2416, 2618, 2850, 2747, 2997, 3177, 3361, 3616, 2704, 2943, 2440, 2698, 3180, 3099.4, 3400, 3600, 1850.3, 1949, 2086, 2130, 2150, 2260, 2404, 1990, 2114, 2200, 2204, 2194, 2285, 2417, 2022.3, 2250, 0, 0, 2510, 0, 0, 0, 0, 3300, 2878, 3081.5, 2466, 0, 0, 0, 0, 0, 1900, 1978, 1814, 1900, 1997, 2084, 2132, 2026, 2152, 2267, 2334, 2363, 2470, 2643, 2228, 2300, 2378, 2484, 2570, 2830, 2900, 3030, 3080, 3160, 3226, 3370, 2650, 2850, 2161.9, 0, -------------------------------------------------------------------------------- /old/PeriodicTable/data/第二电离能.csv: -------------------------------------------------------------------------------- 1 | 0, 5250.5, 7298.1, 1757.1, 2427.1, 2352.6, 2856, 3388.3, 3374.2, 3952.3, 4562, 1450.7, 1816.7, 1577.1, 1907, 2252, 2298, 2665.8, 3052, 1145.4, 1235, 1309.8, 1414, 1590.6, 1509, 1561.9, 1648, 1753, 1957.9, 1733.3, 1979.3, 1537.5, 1798, 2045, 2103, 2350.4, 2633, 1064.2, 1180, 1270, 1380, 1560, 1470, 1620, 1740, 1870, 2070, 1631.4, 1820.7, 1411.8, 1594.9, 1790, 1845.9, 2046.4, 2234.3, 965.2, 1067, 1050, 1020, 1040, 1050, 1070, 1085, 1170, 1110, 1130, 1140, 1150, 1160, 1174.8, 1340, 1440, 1500, 1700, 1260, 1600, 1600, 1791, 1980, 1810, 1971, 1450.5, 1610, 0, 0, 0, 0, 979, 1170, 1110, 1128, 1420, 1128, 1128, 1158, 1196, 1186, 1206, 1216, 1225, 1235, 1254, 1428, 1390, 1547, 1733, 1690, 1760, 1820, 1890, 2070, 2170, 2309, 1600, 1760, 1330, 1435.4, 1560, -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_2D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_2D.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_2D_BLACK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_2D_BLACK.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_3D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_3D.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_3D_BLACK.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_3D_BLACK.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_covalent_radius.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_covalent_radius.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_electronegativity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_electronegativity.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_first_ionization_energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_first_ionization_energy.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_mass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_mass.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_second_ionization_energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_second_ionization_energy.png -------------------------------------------------------------------------------- /old/PeriodicTable/images/PeriodicTable_by_third_ionization_energy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TonyCrane/manim_projects/b243dec0f0a007649a92938e90d60eccb4c7dd15/old/PeriodicTable/images/PeriodicTable_by_third_ionization_energy.png -------------------------------------------------------------------------------- /old/SandpileModel/SandpileModel.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | import time 3 | 4 | class Sandpile(Scene): 5 | CONFIG = { 6 | "d": 10, 7 | "size": 5120 * 1.5, 8 | "num": 500000, 9 | "maxh": 4, 10 | "field_size": 600, 11 | "fromtxt": None, 12 | } 13 | def construct(self): 14 | self.camera.set_frame_height(self.size) 15 | self.camera.set_frame_width(self.size) 16 | points = PMobject(stroke_width=self.d) 17 | 18 | if self.fromtxt is not None: 19 | field = np.loadtxt(self.fromtxt, dtype=int, delimiter=",") 20 | print("load field from file {}".format(self.fromtxt)) 21 | center = self.field_size / 2 22 | else: 23 | field = np.zeros((self.field_size + 10, self.field_size + 10)) 24 | center = self.field_size / 2 25 | field[center, center] += self.num 26 | 27 | iters = 0 28 | t0 = time.time() 29 | dt0 = time.time() 30 | 31 | while np.max(field) >= self.maxh: 32 | toohigh = field >= self.maxh 33 | field[toohigh] -= self.maxh 34 | 35 | field[1:,:][toohigh[:-1,:]] += self.maxh / 4 36 | field[:-1,:][toohigh[1:,:]] += self.maxh / 4 37 | field[:,1:][toohigh[:,:-1]] += self.maxh / 4 38 | field[:,:-1][toohigh[:,1:]] += self.maxh / 4 39 | 40 | field[0:1,:] = 0 41 | field[:,0:1] = 0 42 | 43 | iters += 1 44 | if iters % 1000 == 0: 45 | dt1 = time.time() 46 | print("finish {} iterations - {:.2f}s/1000it".format(iters, dt1 - dt0)) 47 | dt0 = time.time() 48 | 49 | t1 = time.time() 50 | print("{} iterations in {:.2f} seconds".format(iters, t1 - t0)) 51 | np.savetxt("sand-{}.txt".format(self.num), field, fmt="%d", delimiter=",") 52 | 53 | t2 = time.time() 54 | colors = color_gradient([BLACK, GREEN, YELLOW], 4) 55 | for i in range(center * 2 + 3): 56 | dt0 = time.time() 57 | for j in range(center * 2 + 3): 58 | if field[i][j] != 0: 59 | points.add_points( 60 | [np.array([(-center + i) * self.d, (center - j) * self.d, 0])], 61 | color = colors[int(field[i][j])] 62 | ) 63 | dt1 = time.time() 64 | print("finish {} in {:.2f} seconds".format(i, dt1 - dt0)) 65 | t3 = time.time() 66 | if self.fromtxt is None: 67 | print("{} iterations in {:.2f} seconds".format(iters, t1 - t0)) 68 | print("render in {:.2f} seconds".format(t3 - t2)) 69 | 70 | self.add(points) 71 | 72 | 73 | class Test(Scene): 74 | def construct(self): 75 | field = np.loadtxt("sand-100w.txt", dtype=int, delimiter=",") 76 | pixel = np.zeros((field.shape[0], field.shape[1], 4), dtype="uint8") 77 | colors = color_gradient([BLACK, GREEN, YELLOW], 4) 78 | for i in range(field.shape[0]): 79 | for j in range(field.shape[1]): 80 | pixel[i][j] = color_to_int_rgba(colors[field[i][j]]) 81 | img = ImageMobject(pixel, height=8) 82 | self.add(img) 83 | -------------------------------------------------------------------------------- /old/loading.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | 4 | class SingleAnim(Animation): 5 | CONFIG = { 6 | "run_time": 6, 7 | "offset": 0, 8 | "rate_func": linear, 9 | } 10 | def interpolate_mobject(self, alpha): 11 | now_time = alpha * self.run_time 12 | off = self.offset 13 | self.mobject.become(self.starting_mobject) 14 | if now_time <= off: 15 | self.mobject.set_opacity(0) 16 | elif off < now_time <= off + 1: 17 | self.mobject.set_opacity(1) 18 | now_alpha = (self.run_time * alpha - off) / 1 19 | self.mobject.rotate( 20 | rush_from(now_alpha) * 180*DEGREES, 21 | axis=IN, 22 | about_point=ORIGIN, 23 | ) 24 | elif off + 1 < now_time <= off + 2.5: 25 | self.mobject.set_opacity(1) 26 | now_alpha = (self.run_time * alpha - off - 1) / 1.5 27 | self.mobject.rotate( 28 | rush_into(now_alpha) * 180*DEGREES + 180*DEGREES, 29 | axis=IN, 30 | about_point=ORIGIN, 31 | ) 32 | elif off + 2.5 < now_time <= off + 3.5: 33 | self.mobject.set_opacity(1) 34 | now_alpha = (self.run_time * alpha - off - 2.5) / 1 35 | self.mobject.rotate( 36 | rush_from(now_alpha) * 180*DEGREES, 37 | axis=IN, 38 | about_point=ORIGIN, 39 | ) 40 | elif off + 3.5 < now_time <= off + 5: 41 | self.mobject.set_opacity(1) 42 | now_alpha = (self.run_time * alpha - off - 3.5) / 1.5 43 | self.mobject.rotate( 44 | rush_into(now_alpha) * 180*DEGREES + 180*DEGREES, 45 | axis=IN, 46 | about_point=ORIGIN, 47 | ) 48 | else: 49 | self.mobject.set_opacity(0) 50 | 51 | 52 | class OffScene(Animation): 53 | def interpolate_mobject(self, alpha): 54 | if alpha != 1: 55 | self.mobject.set_opacity(0) 56 | else: 57 | self.mobject.set_opacity(1) 58 | 59 | 60 | class Loading(Scene): 61 | def construct(self): 62 | dots = [ 63 | Dot(color=WHITE, radius=0.25).move_to(DOWN*1.5) 64 | for _ in range(5) 65 | ] 66 | total_anims = [] 67 | for i, offset in zip(range(5), [0, 0.26, 0.51, 0.75, 0.99]): 68 | anims = Succession( 69 | OffScene(dots[i], run_time=offset), 70 | Rotating(dots[i], axis=IN, radians=160*DEGREES, about_point=ORIGIN, run_time=0.5, rate_func=rush_from), 71 | Rotating(dots[i], axis=IN, radians= 20*DEGREES, about_point=ORIGIN, run_time=2.0, rate_func=linear), 72 | Rotating(dots[i], axis=IN, radians=180*DEGREES, about_point=ORIGIN, run_time=1.0, rate_func=rush_into), 73 | Rotating(dots[i], axis=IN, radians=160*DEGREES, about_point=ORIGIN, run_time=0.5, rate_func=rush_from), 74 | Rotating(dots[i], axis=IN, radians= 20*DEGREES, about_point=ORIGIN, run_time=2.0, rate_func=linear), 75 | Rotating(dots[i], axis=IN, radians=180*DEGREES, about_point=ORIGIN, run_time=1.0, rate_func=rush_into), 76 | OffScene(dots[i], run_time=1-offset), 77 | ) 78 | # print(*turn_animation_into_updater(anims)) 79 | # self.add(turn_animation_into_updater(anims)) 80 | total_anims.append(anims) 81 | self.add(*dots) 82 | self.wait() 83 | # print(total_anims) 84 | self.play(*total_anims) 85 | self.wait() 86 | 87 | 88 | class Loading2(Scene): 89 | def construct(self): 90 | dots = [ 91 | Dot(color=WHITE, radius=0.25).move_to(DOWN*1) 92 | for _ in range(5) 93 | ] 94 | self.add(dots[0]) 95 | self.wait() 96 | self.play( 97 | SingleAnim(dots[0], offset=0), 98 | SingleAnim(dots[1], offset=0.26), 99 | SingleAnim(dots[2], offset=0.51), 100 | SingleAnim(dots[3], offset=0.74), 101 | SingleAnim(dots[4], offset=0.97), 102 | ) 103 | self.wait(4/15) 104 | self.play( 105 | SingleAnim(dots[0], offset=0), 106 | SingleAnim(dots[1], offset=0.26), 107 | SingleAnim(dots[2], offset=0.51), 108 | SingleAnim(dots[3], offset=0.74), 109 | SingleAnim(dots[4], offset=0.97), 110 | ) 111 | self.wait(4/15) 112 | self.play( 113 | SingleAnim(dots[0], offset=0), 114 | SingleAnim(dots[1], offset=0.26), 115 | SingleAnim(dots[2], offset=0.51), 116 | SingleAnim(dots[3], offset=0.74), 117 | SingleAnim(dots[4], offset=0.97), 118 | ) 119 | self.wait() 120 | -------------------------------------------------------------------------------- /old/logo.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | from manim_sandbox.utils.imports import * 3 | 4 | class LogoStart_white(Scene): 5 | CONFIG = { 6 | "camera_config": { 7 | "background_color": WHITE, 8 | } 9 | } 10 | def construct(self): 11 | logo = Logo(size=8/3, black_bg=False) 12 | squares = VGroup(*[Polygon(ORIGIN, UR, UL), Polygon(ORIGIN, UL, DL), Polygon(ORIGIN, DL, DR), Polygon(ORIGIN, DR, UR),]) 13 | squares.set_fill(BLUE_C, 1).set_stroke(width=0.5, color=BLUE_C).rotate(np.arctan(0.5)).set_height(logo.inner_triangles.get_height()) 14 | squares[0].set_fill('#C59978', 1).set_stroke(width=0.5, color='#C59978') 15 | for s in squares: 16 | s.scale(0.8) 17 | 18 | img = ImageMobject("Tony.png").set_height(2) 19 | Group(logo, img).arrange(RIGHT, buff=1.5).center() 20 | line = Line(UP, DOWN, stroke_width=8, color=BLACK).move_to(mid(logo.get_right(), img.get_left())) 21 | line.set_length(1.4) 22 | text = VGroup( 23 | Text("Manim-Kindergarten", font="Orbitron", color=DARK_GRAY), 24 | Text("鹤翔万里", font="庞门正道标题体", color=BLACK, size=2.3) 25 | ).arrange(DOWN, aligned_edge=LEFT, buff=0.1).next_to(img, buff=0.5) 26 | text[0][0].set_color(logo.color_2[2]) 27 | text[0][6].set_color(logo.color_1[2]) 28 | all_logo = Group(logo, text, line, img).center() 29 | text = Group(text, line, img) 30 | 31 | bg = Rectangle(height=10, width=10, fill_color=WHITE, fill_opacity=1, stroke_width=0) 32 | bg.add_updater(lambda m: m.move_to(logo, aligned_edge=RIGHT).shift(RIGHT*0.2)) 33 | 34 | text.save_state() 35 | text.shift((text.get_right()[0]-bg.get_right()[0]+0.2)*LEFT) 36 | logo.save_state() 37 | logo.move_to(ORIGIN) 38 | logo.scale(1.5) 39 | 40 | tris = logo.inner_triangles.copy().rotate(-PI) 41 | tris.set_color(BLUE_C) 42 | tris[0].set_color('#C59978') 43 | self.add(text, bg) 44 | 45 | self.wait(0.3) 46 | self.add(tris) 47 | self.wait(0.3) 48 | self.remove(tris) 49 | 50 | self.wait(0.2) 51 | self.add(tris) 52 | self.wait(0.15) 53 | self.remove(tris) 54 | 55 | self.wait(0.1) 56 | self.add(tris) 57 | self.wait(0.1) 58 | self.remove(tris) 59 | 60 | self.wait(0.075) 61 | self.add(tris) 62 | self.wait(0.075) 63 | self.remove(tris) 64 | 65 | self.wait(0.05) 66 | self.add(tris) 67 | self.wait(0.05) 68 | self.remove(tris) 69 | 70 | self.wait(0.2) 71 | self.play(ShowSubmobjectsOneByOne(tris), rate_func=linear, run_time=0.4) 72 | for i in tris: 73 | self.add(i) 74 | self.wait(0.1) 75 | self.play(*[ReplacementTransform(tris[i], squares[i]) for i in range(4)], 76 | rate_func=rush_from, run_time=0.6) 77 | self.wait(0.1) 78 | self.play(*[ReplacementTransform(squares[i], logo[i]) for i in range(4)], 79 | rate_func=rush_from, run_time=0.6) 80 | self.wait(0.1) 81 | self.play( 82 | text.restore, logo.restore, 83 | rate_func=rush_from, run_time=0.8 84 | ) 85 | self.wait(1) 86 | self.play(FadeOut(Group(*self.mobjects))) 87 | 88 | 89 | class LogoStart_black(Scene): 90 | def construct(self): 91 | logo = Logo(size=8/3) 92 | squares = VGroup(*[Polygon(ORIGIN, UR, UL), Polygon(ORIGIN, UL, DL), Polygon(ORIGIN, DL, DR), Polygon(ORIGIN, DR, UR),]) 93 | squares.set_fill(WHITE, 1).set_stroke(width=0.5, color=WHITE).rotate(np.arctan(0.5)).set_height(logo.inner_triangles.get_height()) 94 | for s in squares: 95 | s.scale(0.8) 96 | 97 | img = ImageMobject("Tony.png").set_height(2) 98 | Group(logo, img).arrange(RIGHT, buff=1.5).center() 99 | line = Line(UP, DOWN, stroke_width=8, color=WHITE).move_to(mid(logo.get_right(), img.get_left())) 100 | line.set_length(1.4) 101 | text = VGroup( 102 | Text("Manim-Kindergarten", font="Orbitron", color=LIGHT_GRAY), 103 | Text("鹤翔万里", font="庞门正道标题体", color=WHITE, size=2.3) 104 | ).arrange(DOWN, aligned_edge=LEFT, buff=0.1).next_to(img, buff=0.5) 105 | text[0][0].set_color(logo.color_2[2]) 106 | text[0][6].set_color(logo.color_1[2]) 107 | all_logo = Group(logo, text, line, img).center() 108 | text = Group(text, line, img) 109 | 110 | bg = Rectangle(height=10, width=10, fill_color=BLACK, fill_opacity=1, stroke_width=0) 111 | bg.add_updater(lambda m: m.move_to(logo, aligned_edge=RIGHT).shift(RIGHT*0.2)) 112 | 113 | text.save_state() 114 | text.shift((text.get_right()[0]-bg.get_right()[0]+0.2)*LEFT) 115 | logo.save_state() 116 | logo.move_to(ORIGIN) 117 | logo.scale(1.5) 118 | 119 | tris = logo.inner_triangles.copy().rotate(-PI) 120 | self.add(text, bg) 121 | 122 | self.wait(0.3) 123 | self.add(tris) 124 | self.wait(0.3) 125 | self.remove(tris) 126 | 127 | self.wait(0.2) 128 | self.add(tris) 129 | self.wait(0.15) 130 | self.remove(tris) 131 | 132 | self.wait(0.1) 133 | self.add(tris) 134 | self.wait(0.1) 135 | self.remove(tris) 136 | 137 | self.wait(0.075) 138 | self.add(tris) 139 | self.wait(0.075) 140 | self.remove(tris) 141 | 142 | self.wait(0.05) 143 | self.add(tris) 144 | self.wait(0.05) 145 | self.remove(tris) 146 | # square = Square().set_height(tris.get_height()).set_stroke(width=0.5, color=WHITE) 147 | # self.play(ReplacementTransform(square, tris), run_time=1) 148 | self.wait(0.2) 149 | self.play(ShowSubmobjectsOneByOne(tris), rate_func=linear, run_time=0.4) 150 | for i in tris: 151 | self.add(i) 152 | self.wait(0.1) 153 | self.play(*[ReplacementTransform(tris[i], squares[i]) for i in range(4)], 154 | rate_func=rush_from, run_time=0.6) 155 | #self.play(ReplacementTransform(tris, squares), rate_func=linear, run_time=0.8) 156 | self.wait(0.1) 157 | self.play(*[ReplacementTransform(squares[i], logo[i]) for i in range(4)], 158 | rate_func=rush_from, run_time=0.6) 159 | #self.play(ReplacementTransform(squares, logo), rate_func=linear, run_time=1.5) 160 | self.wait(0.1) 161 | self.play( 162 | text.restore, logo.restore, 163 | rate_func=rush_from, run_time=0.8 164 | ) 165 | self.wait(1) 166 | self.play(FadeOut(Group(*self.mobjects))) 167 | 168 | 169 | class DocumentHeader(Scene): 170 | CONFIG = { 171 | "camera_config": { 172 | "background_color": WHITE, 173 | }, 174 | "font": "Orbitron", 175 | } 176 | def construct(self): 177 | logo = Logo(size=8/3, black_bg=False) 178 | text = VGroup( 179 | Text("Manim", font=self.font, color=BLACK, size=2), 180 | Text("Kindergarten", font=self.font, color=BLACK, size=2), 181 | ).arrange(DOWN, aligned_edge=LEFT, buff=0.3).set_height(2.1).next_to(logo, buff=1.5).shift(DOWN*0.2) 182 | text[1][0].set_color(logo.color_1[2]) 183 | text[0][0].set_color(logo.color_2[2]) 184 | all_logo = VGroup(logo, text).center() 185 | line = Line(UP, DOWN, stroke_width=8, color=BLACK).move_to(mid(logo.get_right(), text.get_left())) 186 | line.set_length(1.4) 187 | 188 | mk_logo = VGroup(logo, text, line) 189 | document = VGroup( 190 | Text("中文教程文档", font="庞门正道标题体", size=1.8, color=BLACK), 191 | Text("manim_document_zh", font=self.font, size=1.2, color=GOLD_D), 192 | ).arrange(DOWN, aligned_edge=ORIGIN) 193 | document.next_to(mk_logo, DOWN, coor_mask=np.array([0, 1, 1]), buff=0.6) 194 | self.add(mk_logo, document) 195 | 196 | -------------------------------------------------------------------------------- /old/rate_funcs.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Linear(Scene): 4 | CONFIG = { 5 | "camera_config": { 6 | "background_color": WHITE, 7 | }, 8 | "rate_func": linear, 9 | } 10 | def construct(self): 11 | grid = NumberPlane().scale(3) 12 | text_0 = TexMobject("0", color=BLACK).scale(0.6).next_to(ORIGIN, DL, buff=0.2) 13 | text_1 = TexMobject("1", color=BLACK).scale(0.6).next_to(grid.c2p(1, 0), DOWN, buff=0.2) 14 | tex_1 = TexMobject("1", color=BLACK).scale(0.6).next_to(grid.c2p(0, 1), LEFT, buff=0.2) 15 | func = ParametricFunction( 16 | lambda t: [t, self.rate_func(t), 0], 17 | t_min=0, t_max=1, color=RED 18 | ).scale(3, about_point=ORIGIN) 19 | text = Text(str(self.rate_func.__name__), font="Consolas", size=0.5, color=BLACK) 20 | text.move_to(grid.c2p(0.5, -0.3)) 21 | self.add(grid, func, text, text_0, text_1, tex_1) 22 | 23 | class Smooth(Linear): 24 | CONFIG = { 25 | "rate_func": smooth, 26 | } 27 | 28 | class RushInto(Linear): 29 | CONFIG = { 30 | "rate_func": rush_into, 31 | } 32 | 33 | class RushFrom(Linear): 34 | CONFIG = { 35 | "rate_func": rush_from, 36 | } 37 | 38 | class SlowInto(Linear): 39 | CONFIG = { 40 | "rate_func": slow_into, 41 | } 42 | 43 | class DoubleSmooth(Linear): 44 | CONFIG = { 45 | "rate_func": double_smooth, 46 | } 47 | 48 | class ThereAndBack(Linear): 49 | CONFIG = { 50 | "rate_func": there_and_back, 51 | } 52 | 53 | class ThereAndBackWithPause(Linear): 54 | CONFIG = { 55 | "rate_func": there_and_back_with_pause, 56 | } 57 | 58 | class RunningStart(Linear): 59 | CONFIG = { 60 | "rate_func": running_start, 61 | } 62 | 63 | class NotQuiteThere(Linear): 64 | CONFIG = { 65 | "rate_func": not_quite_there(smooth), 66 | } 67 | 68 | class Wiggle(Linear): 69 | CONFIG = { 70 | "rate_func": wiggle, 71 | } 72 | 73 | class Lingering(Linear): 74 | CONFIG = { 75 | "rate_func": lingering, 76 | } 77 | 78 | class ExponentialDecay(Linear): 79 | CONFIG = { 80 | "rate_func": exponential_decay, 81 | } -------------------------------------------------------------------------------- /render.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class SquareToCircle(Scene): 4 | def construct(self): 5 | circle = Circle(plot_depth=0).set_fill(RED, opacity=1) 6 | square = Square(plot_depth=-1, side_length=1.7).set_fill(BLUE, opacity=1) 7 | 8 | self.play(FadeIn(VGroup(circle, square))) # all good 9 | self.play(ApplyMethod(circle.shift, UP)) # woops! 10 | self.wait(1) 11 | -------------------------------------------------------------------------------- /tony_useful/Arc_group.py: -------------------------------------------------------------------------------- 1 | # from @cigar666 2 | from manimlib.imports import * 3 | 4 | class Arcs(VGroup): 5 | 6 | CONFIG = { 7 | 'colors': [RED, YELLOW, BLUE, PINK], 8 | 'radius': 1, 9 | 'start_angle':0, 10 | 'angle_list': [30 * DEGREES, 60 * DEGREES, 90 * DEGREES], 11 | 'stroke_width': 40, 12 | 13 | } 14 | 15 | def __init__(self, **kwargs): 16 | 17 | VMobject.__init__(self, **kwargs) 18 | self.create_arcs() 19 | 20 | def create_arcs(self, **kwargs): 21 | angle = self.start_angle 22 | colors = color_gradient(self.colors, len(self.angle_list)) 23 | for i in range(len(self.angle_list)): 24 | self.add(Arc(radius=self.radius, start_angle=angle, angle=self.angle_list[i], color=colors[i], stroke_width=self.stroke_width, **kwargs)) 25 | angle += self.angle_list[i] 26 | 27 | class Arcs_Test(Scene): 28 | 29 | def construct(self): 30 | 31 | arcs_01 = Arcs(stroke_width=80).shift(LEFT * 4.5) 32 | arcs_02 = Arcs(angle_list=np.array([10, 20, 30, 40, 50, 60, 70, 80]) * DEGREES, stroke_width=200) 33 | arcs_03 = Arcs(angle_list=np.array([10, 15, 20, 30]) * DEGREES, stroke_width=200).set_stroke(opacity=0.25).shift(RIGHT * 4) 34 | arcs_04 = Arcs(angle_list=np.array([10, 15, 20, 30]) * DEGREES, radius=2, stroke_width=10).shift(RIGHT * 4) 35 | 36 | self.play(ShowCreation(arcs_01)) 37 | self.wait() 38 | self.play(ShowCreation(arcs_02)) 39 | self.wait() 40 | self.play(ShowCreation(VGroup(arcs_03, arcs_04))) 41 | 42 | self.wait(4) 43 | 44 | class Angle(VGroup): 45 | 46 | CONFIG = { 47 | 'radius': 1, 48 | 'color': RED, 49 | 'opacity': 0.4, 50 | 'stroke_width': 10, 51 | # 'below_180': True, 52 | } 53 | 54 | def __init__(self, A, O, B, **kwargs): 55 | 56 | VMobject.__init__(self, **kwargs) 57 | OA, OB = A-O, B-O 58 | theta = np.angle(complex(*OA[:2])/complex(*OB[:2])) # angle of OB to OA 59 | 60 | self.add(Arc(start_angle=Line(O,B).get_angle(), angle=theta, radius=self.radius/2, 61 | stroke_width=100 * self.radius, color=self.color).set_stroke(opacity=self.opacity).move_arc_center_to(O)) 62 | self.add(Arc(start_angle=Line(O,B).get_angle(), angle=theta, radius=self.radius, 63 | stroke_width=self.stroke_width, color=self.color).move_arc_center_to(O)) 64 | 65 | 66 | class Angles_tag(Scene): 67 | 68 | def construct(self): 69 | 70 | A = LEFT * 4.5 + DOWN * 2 71 | B = RIGHT * 6 + DOWN * 1 72 | C = UP * 2 73 | 74 | tri_abc = Polygon(A, B, C, color=WHITE) 75 | 76 | dot_A = Dot(A, color=RED, radius=0.15) 77 | angle_A = Angle(B, A, C, color=RED, radius=1.6) 78 | 79 | dot_B = Dot(B, color=YELLOW, radius=0.15) 80 | angle_B = Angle(A, B, C, color=YELLOW, radius=1.5) 81 | 82 | dot_C = Dot(C, color=BLUE, radius=0.15) 83 | angle_C = Angle(A, C, B, color=BLUE, radius=1.) 84 | 85 | self.add((tri_abc)) 86 | self.wait() 87 | self.play(FadeInFromLarge(dot_A)) 88 | self.play(ShowCreation(angle_A)) 89 | self.wait() 90 | self.play(FadeInFromLarge(dot_B)) 91 | self.play(ShowCreation(angle_B)) 92 | self.wait() 93 | self.play(FadeInFromLarge(dot_C)) 94 | self.play(ShowCreation(angle_C)) 95 | 96 | self.wait(2) 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /tony_useful/Boxes.py: -------------------------------------------------------------------------------- 1 | # from @cigar666 2 | from manimlib.constants import * 3 | from manimlib.mobject.types.vectorized_mobject import VGroup 4 | from manimlib.mobject.three_dimensions import Cube 5 | from manimlib.utils.color import color_gradient 6 | from manimlib.mobject.svg.tex_mobject import TextMobject 7 | 8 | class MyBox(Cube): 9 | CONFIG = { 10 | 'pos': ORIGIN, 11 | 'box_height': 2, 12 | 'bottom_size': [1, 1], 13 | 'fill_opacity': 1, 14 | } 15 | 16 | def __init__(self, **kwargs): 17 | Cube.__init__(self, **kwargs) 18 | self.box_size = np.array([self.bottom_size[0], self.bottom_size[1], self.box_height]) 19 | self.scale(self.box_size/2) 20 | # self.move_to(self.pos + self.box_height * OUT/2) 21 | self.move_to(self.pos) 22 | self.reset_color() 23 | 24 | def update_height(self, new_height): 25 | self.scale(np.array([1, 1, new_height/self.box_height])) #.shift(OUT * (new_height - self.height)/2) 26 | self.box_height = new_height 27 | 28 | def update_top_and_bottom(self, top, bottom): 29 | new_height = abs(top-bottom) 30 | old_center = self.get_center() 31 | self.update_height(new_height) 32 | self.shift(((top+bottom)/2 - old_center[-1]) * OUT) 33 | 34 | def update_top(self, top): 35 | bottom = self.get_center()[-1] - self.box_height/2 36 | self.update_top_and_bottom(top, bottom) 37 | 38 | def update_bottom(self, bottom): 39 | top = self.get_center()[-1] + self.box_height/2 40 | self.update_top_and_bottom(top, bottom) 41 | 42 | def reset_color(self): 43 | colors = color_gradient([WHITE, self.get_color(), BLACK], 11) 44 | self[0].set_fill(color=colors[8]) 45 | self[1].set_fill(color=colors[3]) 46 | self[2].set_fill(color=colors[8]) 47 | self[3].set_fill(color=colors[2]) 48 | self[4].set_fill(color=colors[5]) 49 | self[5].set_fill(color=colors[7]) 50 | 51 | class MyBoxes(VGroup): 52 | CONFIG = { 53 | 'center': ORIGIN, 54 | 'bottom_size': [0.25, 0.25], 55 | 'box_height': 2, 56 | 'gap': 0, 57 | 'fill_color': BLUE, 58 | 'resolution': (20, 20), 59 | } 60 | 61 | def __init__(self, **kwargs): 62 | 63 | VGroup.__init__(self, **kwargs) 64 | self.create_boxes(self.resolution) 65 | self.mask_array = np.zeros(self.resolution) 66 | self.colors = color_gradient([BLUE_D, YELLOW, RED, RED_D], 110) 67 | 68 | def create_boxes(self, resolution=(20, 20)): 69 | a, b = self.bottom_size[0] + self.gap, self.bottom_size[1] + self.gap 70 | m, n = resolution[0], resolution[1] 71 | for i in range(m): 72 | for j in range(n): 73 | box_ij = MyBox(pos=a * (j - n/2 + 1/2) * RIGHT + b * (i - m/2 + 1/2) * UP, bottom_size=self.bottom_size, 74 | box_height=self.box_height, fill_color=self.fill_color) 75 | box_ij.reset_color() 76 | self.add(box_ij) 77 | 78 | def update_height_by_2darray(self, arr_2d): 79 | m, n = self.resolution[0], self.resolution[1] 80 | if len(arr_2d)>=m and len(arr_2d[0])>=n: 81 | for i in range(m): 82 | for j in range(n): 83 | self[i*n+j].update_height(arr_2d[i, j]) 84 | 85 | def update_height_by_func(self, func, s=1): 86 | for box in self: 87 | center = box.get_center() 88 | box.update_height(func(center[0], center[1]) * s) 89 | 90 | def update_top_and_bottom_by_2darray(self, arr_top, arr_bottom): 91 | m, n = self.resolution[0], self.resolution[1] 92 | if len(arr_top)>=m and len(arr_top[0])>=n and len(arr_bottom)>=m and len(arr_bottom[0])>=n: 93 | for i in range(m): 94 | for j in range(n): 95 | self[i*n+j].update_top_and_bottom(arr_top[i, j], arr_bottom[i, j]) 96 | 97 | def update_top_and_bottom_by_func(self, func_top, func_bottom, s=1): 98 | for box in self: 99 | center = box.get_center() 100 | box.update_top_and_bottom(func_top(center[0], center[1]) * s, func_bottom(center[0], center[1]) * s) 101 | 102 | def update_top_by_func(self, func_top, s=1): 103 | for box in self: 104 | center = box.get_center() 105 | box.update_top(func_top(center[0], center[1]) * s) 106 | 107 | def update_bottom_by_func(self, func_bottom, s=1): 108 | for box in self: 109 | center = box.get_center() 110 | box.update_top(func_bottom(center[0], center[1]) * s) 111 | 112 | def update_color_by_func(self, func): 113 | 114 | a, b = self.bottom_size[0] + self.gap, self.bottom_size[1] + self.gap 115 | m, n = self.resolution[0], self.resolution[1] 116 | x, y = np.linspace(-a * n/2, a * n/2, n), np.linspace(-b * m/2, b * m/2, m) 117 | X, Y = np.meshgrid(x, y) 118 | Z = func(X, Y) 119 | z_min, z_max = Z.min(), Z.max() 120 | # print(z_min, z_max) 121 | 122 | for box in self: 123 | center = box.get_center() + box.box_height/2 * OUT 124 | # print(int((func(center[0], center[1]) - z_min)/(z_max-z_min) * 100)) 125 | box.set_color(self.colors[int((func(center[0], center[1]) - z_min)/(z_max-z_min) * 100)]) 126 | box.reset_color() 127 | 128 | def update_color_by_2darray(self, top_array): 129 | Z = top_array 130 | m, n = self.resolution[0], self.resolution[1] 131 | z_min, z_max = Z.min(), Z.max() 132 | if len(Z) >= m and len(Z) >= n: 133 | for i in range(m): 134 | for j in range(n): 135 | self[i*n+j].set_color(self.colors[int((Z[i, j] - z_min)/(z_max-z_min) * 100)]) 136 | self[i*n+j].reset_color() 137 | 138 | def set_mask_array(self, mask): 139 | self.mask_array = mask 140 | 141 | def apply_mask(self): 142 | 143 | m, n = self.resolution[0], self.resolution[1] 144 | for i in range(m): 145 | for j in range(n): 146 | if self.mask_array[i, j] == 1.: # if self.mask_array[i, j]: 147 | self[i*n+j].set_fill(opacity=0) 148 | 149 | class ChemicalBoxes(VGroup): 150 | CONFIG = { 151 | 'center': ORIGIN, 152 | 'bottom_size': (0.45, 0.6), 153 | 'box_height': 0.4, 154 | 'gap': 0, 155 | 'fill_color': BLUE, 156 | 'shade_in_3d': False 157 | } 158 | 159 | def __init__(self, **kwargs): 160 | VGroup.__init__(self, **kwargs) 161 | self.id_to_pos = [ 162 | 0, 144, 161, 163 | 126, 127, 138, 139, 140, 141, 142, 143, 164 | 108, 109, 120, 121, 122, 123, 124, 125, 165 | *list(range(90, 108)), 166 | *list(range(72, 90)), 167 | 54, 55, 168 | *list(range(20, 35)), 169 | *list(range(57, 72)), 170 | 36, 37, 171 | *list(range(2, 17)), 172 | *list(range(39, 54)) 173 | ] 174 | self.create_boxes() 175 | self.mask_array = np.zeros((9, 18)) 176 | self.colors = color_gradient([BLUE_D, YELLOW, RED, RED_D], 110) 177 | 178 | def create_boxes(self): 179 | pos = MyBoxes(resolution=(9, 18), bottom_size=self.bottom_size, gap=0.15, box_height=0.4) 180 | boxes = VGroup() 181 | for i in range(0, 119): 182 | box = MyBox(pos=pos[self.id_to_pos[i]].get_center(), bottom_size=self.bottom_size, 183 | box_height=self.box_height, fill_color=self.fill_color) 184 | box.reset_color() 185 | boxes.add(box) 186 | boxes[0].set_fill(opacity=0) 187 | self.add(boxes) 188 | 189 | def add_label(self): 190 | self.id_to_label = [ 191 | "0", "H", "He", 192 | "Li", "Be", "B", "C", "N", "O", "F", "Ne", 193 | "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", 194 | "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr", 195 | "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe", 196 | "Cs", "Ba", 197 | "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu", 198 | "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", 199 | "Fr", "Ra", 200 | "Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr", 201 | "Rf", "Db", "Sg", "Bh", "Hs", "Mt", "Ds", "Rg", "Cn", "Nh", "Fl", "Mc", "Lv", "Ts", "Og" 202 | ] 203 | self.label_to_id = {} 204 | for i, label in enumerate(self.id_to_label): 205 | self.label_to_id[label] = i 206 | labels = VGroup() 207 | for i in range(0, 119): 208 | label = TextMobject(self.id_to_label[i], color=BLACK, background_stroke_width=0) 209 | label.scale(0.5).move_to(self[0][i][1].get_center()).set_shade_in_3d(z_index_as_group=True).shift(OUT * 1e-3) 210 | labels.add(label) 211 | labels[0].set_fill(opacity=0) 212 | for i in [43, 61, *list(range(84, 119))]: 213 | labels[i].set_color(RED) 214 | self.add(labels) 215 | return self 216 | 217 | def set_block_color(self): 218 | colors = [PURPLE_E, PURPLE, PINK, ORANGE, YELLOW, GOLD, BLUE, GREEN_B, GREEN] 219 | self.id_to_color_id = [ 220 | 0, 0, 2, 221 | 0, 1, 4, 4, 4, 4, 3, 2, 222 | 0, 1, 5, 4, 4, 4, 3, 2, 223 | 0, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 4, 4, 3, 2, 224 | 0, 1, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 3, 2, 225 | 0, 1, 226 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 227 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 3, 2, 228 | 0, 1, 229 | 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 230 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 3, 2 231 | ] 232 | for i in range(0, 119): 233 | self[0][i].set_color(colors[self.id_to_color_id[i]]).reset_color() 234 | return self 235 | 236 | def set_height_by_array(self, h): 237 | for i in range(1, 119): 238 | if h[i] == 0.25: 239 | self[0][i].update_top_and_bottom(0.1, 0) 240 | else: 241 | self[0][i].update_top_and_bottom(h[i], 0) -------------------------------------------------------------------------------- /tony_useful/MyText.py: -------------------------------------------------------------------------------- 1 | # from @cigar666 2 | from manimlib.imports import * 3 | 4 | class MyText_old(TexMobject): 5 | 6 | CONFIG = { 7 | 'default_font': '思源黑体', 8 | } 9 | 10 | def __init__(self, *tex_strings, **kwargs): 11 | self.tex_list = tex_strings 12 | TexMobject.__init__(self, *tex_strings, **kwargs) 13 | self.not_replace_texs = ['\\over', ] 14 | self.new_font_texs = VGroup() 15 | 16 | def reset_tex_with_font(self): 17 | self.new_font_texs = VGroup() 18 | 19 | def get_color_by_tex(self, tex, **kwargs): 20 | parts = self.get_parts_by_tex(tex, **kwargs) 21 | colors = [] 22 | for part in parts: 23 | colors.append(part.get_color()) 24 | return colors[0] 25 | 26 | def set_font_by_tex(self, tex, font, new_tex=None, color=None, **kwargs): 27 | parts_to_font = self.get_parts_by_tex(tex, **kwargs) 28 | if color == None: 29 | color = self.get_color_by_tex(tex) 30 | 31 | if new_tex != None: 32 | tex = new_tex 33 | for part in parts_to_font: 34 | 35 | tex_new = Text(tex, font=font, color=color) 36 | tex_new.set_height(part.get_height()) 37 | # tex_new.set_width(part.get_width()) 38 | tex_new.move_to(part) 39 | self.new_font_texs.add(tex_new) 40 | 41 | def set_font_by_tex_to_font_map(self, texs_to_font_map, texs_replace_map, **kwargs): 42 | for texs, font in list(texs_to_font_map.items()): 43 | try: 44 | # If the given key behaves like tex_strings 45 | if texs in texs_replace_map: 46 | self.set_font_by_tex(texs, font, new_tex=texs_replace_map[texs], **kwargs) 47 | else: 48 | self.set_font_by_tex(texs, font, **kwargs) 49 | except TypeError: 50 | # If the given key is a tuple 51 | for tex in texs: 52 | if tex in texs_replace_map: 53 | self.set_font_by_tex(texs, font, new_tex=texs_replace_map[texs], **kwargs) 54 | else: 55 | self.set_font_by_tex(texs, font, **kwargs) 56 | 57 | def create_default_font_dict(self): 58 | self.default_font_dict = {} 59 | for tex in self.tex_strings: 60 | if not tex in self.not_replace_texs: 61 | self.default_font_dict[tex] = self.default_font 62 | return self.default_font_dict 63 | 64 | def get_new_font_texs(self, texs_replace_map, **kwargs): 65 | texs_to_font_map = self.create_default_font_dict() 66 | self.set_font_by_tex_to_font_map(texs_to_font_map, texs_replace_map, **kwargs) 67 | return self.new_font_texs 68 | 69 | class MyText(TexMobject): 70 | 71 | CONFIG = { 72 | 'default_font': 'SWGothe', 73 | 'tex_scale_factor': 1, 74 | } 75 | 76 | def __init__(self, *tex_strings, **kwargs): 77 | self.tex_list = tex_strings 78 | TexMobject.__init__(self, *tex_strings, **kwargs) 79 | self.new_font_texs = VGroup() 80 | 81 | def reset_tex_with_font(self): 82 | self.new_font_texs = VGroup() 83 | 84 | def get_color_by_tex(self, tex, **kwargs): 85 | parts = self.get_parts_by_tex(tex, **kwargs) 86 | colors = [] 87 | for part in parts: 88 | colors.append(part.get_color()) 89 | return colors[0] 90 | 91 | def get_new_font_texs(self, replace_dict): 92 | for i in range(len(self.tex_strings)): 93 | tex = self.tex_strings[i] 94 | color=self.get_color_by_tex(tex) 95 | if tex in replace_dict: 96 | tex = replace_dict[tex] 97 | tex_new = Text(tex, font=self.default_font, color=color) 98 | tex_new.set_height(self[i].get_height()) 99 | if tex == '-' or tex == '=': 100 | tex_new.set_width(self[i].get_width(), stretch=True) 101 | tex_new.scale(self.tex_scale_factor) 102 | tex_new.move_to(self[i]) 103 | self.new_font_texs.add(tex_new) 104 | return self.new_font_texs 105 | 106 | class Test_mytext(Scene): 107 | 108 | def construct(self): 109 | 110 | color_dict = {'R': PINK, 'd': YELLOW, 'r': ORANGE, '\\theta': BLUE, '\\over': WHITE, 111 | 't': BLUE, 'e': GREEN, 'i': RED, '\\sin': WHITE, '\\cos': WHITE} 112 | 113 | font_list = ['Comic Sans MS', '庞门正道标题体', 'Consolas', 'SWGothe', 'Rough___Dusty_Chalk', 114 | 'SWScrps', '新蒂小丸子体'] 115 | 116 | origin_formula = TexMobject('f', '(', 't', ')', '=', 'x', '(', 't', ')', '+', 'y', '(', 't', ')', 'i', '=', 117 | '(', 'R', '-', 'r', ')', 'e^{', 'i', 't}', '+', 'd', 'e^{', '-', 'i', '{R', '-', 118 | 'r', '\\over', 'r}', 't}').scale(1)\ 119 | .set_color_by_tex_to_color_map(color_dict).to_corner(LEFT * 2 + UP * 1.5) 120 | formulas = VGroup(origin_formula) 121 | 122 | for i in range(len(font_list)): 123 | formula_i = MyText('f', '(', 't', ')', '=', 'x', '(', 't', ')', '+', 'y', '(', 't', ')', 'i', '=', 124 | '(', 'R', '-', 'r', ')', 'e^{', 'i', 't}', '+', 'd', 'e^{', '-', 'i', '{R', '-', 125 | 'r', '\\over', 'r}', 't}', default_font=font_list[i], tex_scale_factor=0.75) 126 | formula_i.set_color_by_tex_to_color_map(color_dict) 127 | replace_dict = {'e^{': 'e', 't}': 't', '{R': 'R', 'r}': 'r', '\\over': '-'} 128 | new_formula = formula_i.get_new_font_texs(replace_dict) 129 | new_formula.to_corner(LEFT * 2 + UP * 1.5).shift(DOWN * 0.8 * (i+1)) 130 | formulas.add(new_formula) 131 | 132 | self.add(formulas) 133 | 134 | self.wait(5) 135 | 136 | -------------------------------------------------------------------------------- /tony_useful/RandomAnim.py: -------------------------------------------------------------------------------- 1 | # from @Elteoremadebeethoven 2 | 3 | from manimlib.imports import * 4 | 5 | def return_random_from_word(word): 6 | """ 7 | This function receives a TextMobject, 8 | obtains its length: 9 | len(TextMobject("Some text")) 10 | and returns a random list, example: 11 | INPUT: word = TextMobjecT("Hello") 12 | length = len(word) # 4 13 | rango = list(range(length)) # [0,1,2,3] 14 | OUTPUT: [3,0,2,1] # Random list 15 | """ 16 | rango = list(range(len(word))) 17 | random.shuffle(rango) 18 | return rango 19 | 20 | def return_random_direction(word): 21 | """ 22 | This function returns a list of random UP or DOWN: 23 | [UP,UP,DOWN,UP,DOWN,DOWN,...] 24 | """ 25 | return [random.choice([UP,DOWN]) for _ in range(len(word))] 26 | 27 | def get_random_coord(r_x,r_y,step_x,step_y): 28 | """ 29 | Given two ranges (a, b) and (c, d), this function returns an 30 | intermediate array (x, y) such that "x" belongs to (a, c) 31 | and "y" belongs to (b, d). 32 | """ 33 | range_x = list(range(r_x[0],r_x[1],step_x)) 34 | range_y = list(range(r_y[0],r_y[1],step_y)) 35 | select_x = random.choice(range_x) 36 | select_y = random.choice(range_y) 37 | return np.array([select_x,select_y,0]) 38 | 39 | def return_random_coords(word,r_x,r_y,step_x,step_y): 40 | """ 41 | This function returns a random coordinate array, 42 | given the length of a TextMobject 43 | """ 44 | rango = range(len(word)) 45 | return [word.get_center() + get_random_coord(r_x,r_y,step_x,step_y) for _ in rango] 46 | 47 | 48 | class WriteRandom(LaggedStart): 49 | CONFIG = { 50 | "lag_ratio":0.1, 51 | "run_time":2.5, 52 | "anim_kwargs":{}, 53 | "anim_type":Write 54 | } 55 | def __init__(self,text,**kwargs): 56 | digest_config(self, kwargs) 57 | super().__init__(*[ 58 | self.anim_type(text[i],**self.anim_kwargs) 59 | for i in return_random_from_word(text) 60 | ]) 61 | 62 | class UnWriteRandom(WriteRandom): 63 | CONFIG = { 64 | "anim_kwargs": { 65 | "rate_func": lambda t: smooth(1-t) 66 | }, 67 | "remover": True, 68 | } 69 | 70 | class FadeInRandom(WriteRandom): 71 | CONFIG = { 72 | "anim_type": FadeIn 73 | } 74 | 75 | class FadeInFromCenterRandom(WriteRandom): 76 | CONFIG = { 77 | "anim_type": FadeInFromCenter 78 | } 79 | 80 | class FadeOutRandom(WriteRandom): 81 | CONFIG = { 82 | "anim_type": FadeOut 83 | } 84 | 85 | class GrowRandom(WriteRandom): 86 | CONFIG = { 87 | "anim_type": GrowFromCenter 88 | } 89 | 90 | class UnGrowRandom(GrowRandom): 91 | CONFIG = { 92 | "anim_kwargs": { 93 | "rate_func": lambda t: smooth(1-t), 94 | }, 95 | "remover": True, 96 | } 97 | 98 | class FadeInFromRandom(LaggedStart): 99 | CONFIG = { 100 | "lag_ratio":0.08, 101 | "anim_type":FadeInFrom, 102 | "anim_kwargs":{} 103 | } 104 | def __init__(self,text,**kwargs): 105 | digest_config(self, kwargs) 106 | super().__init__(*[ 107 | self.anim_type(text[i],d,**self.anim_kwargs) 108 | for i,d in zip(return_random_from_word(text),return_random_direction(text)) 109 | ]) 110 | 111 | class FadeOutFromRandom(FadeInFromRandom): 112 | CONFIG = { 113 | "anim_type":FadeOutAndShiftDown 114 | } 115 | 116 | class GrowFromRandom(LaggedStart): 117 | CONFIG = { 118 | "lag_ratio":0.2, 119 | "anim_kwargs":{} 120 | } 121 | def __init__(self,text,r_x=[-2,3],r_y=[-2,3],step_x=1,step_y=1,**kwargs): 122 | digest_config(self, kwargs) 123 | super().__init__(*[ 124 | GrowFromPoint(text[i],d,**self.anim_kwargs) 125 | for i,d in zip(return_random_from_word(text),return_random_coords(text,r_x,r_y,step_x,step_y)) 126 | ]) 127 | 128 | class UnGrowFromRandom(GrowFromRandom): 129 | CONFIG = { 130 | "anim_kwargs": { 131 | "rate_func": lambda t: smooth(1-t) 132 | }, 133 | "remover": True 134 | } 135 | -------------------------------------------------------------------------------- /tony_useful/Subtitle.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class SubTopic(Text): 4 | CONFIG = { 5 | 'font' : 'Source Han Serif CN', 6 | 'size' : 1, 7 | 'to_scale' : 0.6, 8 | 'color' : GOLD, 9 | } 10 | 11 | def __init__(self, text, **config): 12 | Text.__init__(self, text, **config) 13 | self.scale(self.to_scale) 14 | dot = Dot().set_color(self.color).next_to(self, LEFT) 15 | self.add(dot) 16 | -------------------------------------------------------------------------------- /tony_useful/Title2.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Title2(Text): 4 | CONFIG = { 5 | "scale_factor": 0.75, 6 | "include_underline": True, 7 | "underline_width": FRAME_WIDTH - 2, 8 | # This will override underline_width 9 | "match_underline_width_to_text": False, 10 | "underline_buff": MED_SMALL_BUFF, 11 | } 12 | 13 | def __init__(self, text, **kwargs): 14 | Text.__init__(self, text, **kwargs) 15 | self.scale(self.scale_factor) 16 | self.to_edge(UP) 17 | if self.include_underline: 18 | underline = Line(LEFT, RIGHT) 19 | underline.next_to(self, DOWN, buff=self.underline_buff) 20 | if self.match_underline_width_to_text: 21 | underline.match_width(self) 22 | else: 23 | underline.set_width(self.underline_width) 24 | self.add(underline) 25 | self.underline = underline -------------------------------------------------------------------------------- /tony_useful/VideoCover.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : VideoCover.py 3 | > Author : Tony 4 | > Created Time : 2019/05/25 9:49:37 5 | ''' 6 | 7 | from big_ol_pile_of_manim_imports import * 8 | 9 | class VideoCover(Scene): 10 | CONFIG = { 11 | "Author" : "@鹤翔万里", 12 | "author_colors" : [BLUE, YELLOW, ORANGE, RED], 13 | "en_title_name" : "test", 14 | "title_name" : "测试", 15 | "subtitle_name" : "", 16 | } 17 | 18 | def construct(self): 19 | author = TextMobject(self.Author).set_color(self.author_colors).scale(1).to_corner(DOWN+RIGHT) 20 | en_title = TextMobject(self.en_title_name).scale(3).to_corner(UP+np.array((0., 2., 0.))) 21 | title = TextMobject(self.title_name).scale(1.9).set_color(YELLOW).next_to(en_title, DOWN, buff=0.6) 22 | subtitle = TextMobject(self.subtitle_name).scale(1.2).next_to(title, DOWN).set_color(BLUE) 23 | self.add(author, en_title, title, subtitle) -------------------------------------------------------------------------------- /tony_useful/VideoStart.py: -------------------------------------------------------------------------------- 1 | ''' 2 | > File Name : VideoStart.py 3 | > Author : Tony 4 | > Created Time : 2019/03/13 14:17:47 5 | ''' 6 | 7 | from manimlib.imports import * 8 | 9 | class VideoStart(Scene): 10 | CONFIG = { 11 | "Author" : "@鹤翔万里", 12 | "title_name" : "测试", 13 | "subtitle_name" : "", 14 | "svg_filename" : "TonySVG", 15 | "author_colors" : [BLUE, YELLOW, ORANGE, RED], 16 | } 17 | def construct(self): 18 | author = TextMobject( 19 | self.Author, 20 | tex_to_color_map={self.Author : self.author_colors} 21 | ).scale(1.5) 22 | svg_file = SVGMobject(file_name = self.svg_filename) 23 | svg_file.to_corner(UP) 24 | 25 | title = TextMobject(self.title_name) 26 | title.to_corner((BOTTOM + ORIGIN)) 27 | # subtitle = TextMobject(self.subtitle_name).scale(0.8).set_color(BLUE) 28 | # subtitle.next_to(title, DOWN, buff=0.75) 29 | self.play( 30 | FadeInFromDown(svg_file), 31 | Write(author) 32 | ) 33 | self.play( 34 | Write(title), 35 | # Write(subtitle), 36 | ) 37 | self.wait() 38 | self.play( 39 | LaggedStart(FadeOutAndShiftDown(author)), 40 | FadeOut(title), 41 | # FadeOut(subtitle), 42 | run_time = 0.5, 43 | ) -------------------------------------------------------------------------------- /tony_useful/bilibili.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class TripleScene(Scene): 4 | CONFIG = { 5 | "good_file": "good", 6 | "coin_file": "coin", 7 | "favo_file": "favo", 8 | } 9 | def construct(self): 10 | self.get_svg() 11 | good = self.good 12 | coin = self.coin 13 | favo = self.favo 14 | self.play( 15 | FadeInFromPoint(good, good.get_center()), 16 | FadeInFromPoint(coin, coin.get_center()), 17 | FadeInFromPoint(favo, favo.get_center()) 18 | ) 19 | self.wait(0.4) 20 | circle_coin = Circle().scale(0.7).move_to(coin).set_stroke(PINK, 6) 21 | circle_favo = Circle().scale(0.7).move_to(favo).set_stroke(PINK, 6) 22 | self.play( 23 | good.set_color, LIGHT_PINK, 24 | ShowCreation(circle_coin), 25 | ShowCreation(circle_favo), 26 | run_time=1.5 27 | ) 28 | self.play( 29 | FadeOut(circle_coin), 30 | FadeOut(circle_favo), 31 | Flash(coin.get_center(), color=PINK, line_length=0.7, flash_radius=1.5), 32 | Flash(favo.get_center(), color=PINK, line_length=0.7, flash_radius=1.5), 33 | Flash(good.get_center(), color=PINK, line_length=0.7, flash_radius=1.5), 34 | coin.set_color, LIGHT_PINK, 35 | favo.set_color, LIGHT_PINK, 36 | run_time=0.3 37 | ) 38 | self.wait(2) 39 | self.play( 40 | FadeOut(good), 41 | FadeOut(coin), 42 | FadeOut(favo), 43 | run_time=0.8 44 | ) 45 | self.wait() 46 | 47 | def get_svg(self): 48 | self.good = SVGMobject(self.good_file).set_height(1).move_to(LEFT*2.5+DOWN*2.7) 49 | self.coin = SVGMobject(self.coin_file).set_height(1).move_to(DOWN*2.7) 50 | self.favo = SVGMobject(self.favo_file).set_height(1).move_to(RIGHT*2.5+DOWN*2.7) 51 | -------------------------------------------------------------------------------- /tony_useful/code.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class Code(Text): 4 | CONFIG = { 5 | 'font' : 'Monaco for Powerline', 6 | 'size' : 0.5, 7 | 'color' : WHITE, 8 | 'stroke_color' : WHITE, 9 | 'stroke_weight': 0, 10 | } 11 | 12 | def __init__(self, *text, **config): 13 | res_text = '' 14 | for each_text in text: 15 | res_text += each_text + '\n' 16 | super(Code, self).__init__(res_text, **config) 17 | self.set_stroke(self.stroke_color, self.stroke_weight) 18 | 19 | class LinedCode(Text): 20 | CONFIG = { 21 | 'font' : 'Consolas', 22 | 'size' : 0.5, 23 | 'color' : WHITE, 24 | 'stroke_color' : WHITE, 25 | 'stroke_weight': 0, 26 | 'ln_color' : GRAY, 27 | } 28 | 29 | def __init__(self, *text, **config): 30 | digest_config(self, config) 31 | res_text = '' 32 | i = 1 33 | for each_text in text: 34 | res_text += str(i) + ' ' + each_text + '\n' 35 | self.t2c['{} '.format(i)] = self.ln_color 36 | i = i + 1 37 | super(LinedCode, self).__init__(res_text, **config) 38 | self.set_stroke(self.stroke_color, self.stroke_weight) -------------------------------------------------------------------------------- /tony_useful/debugTeX.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | import itertools 3 | 4 | def debugTeX(self, texm, scale=0.6): 5 | for i, j in enumerate(texm): 6 | tex_id = Text(str(i), font="Consolas").scale(scale).set_color(PURPLE) 7 | tex_id.move_to(j) 8 | self.add(tex_id) -------------------------------------------------------------------------------- /tony_useful/imports.py: -------------------------------------------------------------------------------- 1 | from manim_projects.tony_useful.bilibili import * 2 | from manim_projects.tony_useful.code import * 3 | from manim_projects.tony_useful.VideoStart import * 4 | from manim_projects.tony_useful.Arc_group import * 5 | from manim_projects.tony_useful.Title2 import * 6 | from manim_projects.tony_useful.Subtitle import * 7 | from manim_projects.tony_useful.debugTeX import * 8 | from manim_projects.tony_useful.Boxes import * 9 | from manim_projects.tony_useful.sector import * 10 | from manim_projects.tony_useful.RandomAnim import * -------------------------------------------------------------------------------- /tony_useful/sector.py: -------------------------------------------------------------------------------- 1 | from manimlib.imports import * 2 | 3 | class MySectors(VGroup): 4 | CONFIG = { 5 | 'stroke_width': 0, 6 | 'fill_opacity': 1, 7 | 'inner_radius': 1.6, 8 | # 'outer_radius': [], 9 | 'gap': 0.025, 10 | 'start_direction': UP, 11 | 'values': [1,2,3], 12 | 'labels': None, 13 | # 'data': {'labels': 1.23}, 14 | 'unit': None, 15 | # 'data_2d': None, 16 | 'outer_radius_func': lambda t: t/10 + 0.32, 17 | 'label_font': '思源黑体 CN Bold', 18 | 'center': ORIGIN, 19 | } 20 | 21 | def __init__(self, **kwargs): 22 | VGroup.__init__(self, **kwargs) 23 | self.colors = color_gradient([ORANGE, RED, PINK, BLUE, GREEN, YELLOW], len(self.values)) 24 | self.sectors, self.labels_group = VGroup(), VGroup() 25 | self.sectors = self.create_sectors() 26 | if not self.labels == None: 27 | self.labels_group = self.create_label() 28 | self.add(self.sectors, self.labels_group) 29 | 30 | 31 | def create_sectors(self): 32 | angle = TAU/len(self.values) 33 | colors = self.colors 34 | start_a = np.angle(complex(*self.start_direction[0:2])) 35 | 36 | for i in range(len(self.values)): 37 | r_i = self.inner_radius + self.outer_radius_func(self.values[i]) 38 | sector_i = Sector(arc_center=self.center, inner_radius=self.inner_radius, outer_radius=r_i, 39 | stroke_width=self.stroke_width, start_angle=start_a + i * angle, 40 | angle=angle * (1 - self.gap), color=colors[i], fill_opacity=self.fill_opacity) 41 | self.sectors.add(sector_i) 42 | return self.sectors 43 | 44 | 45 | def create_label(self): 46 | for tex, value in zip(self.labels, self.values): 47 | i = self.labels.index(tex) 48 | r = self.inner_radius + self.outer_radius_func(self.values[i]) 49 | size = TAU * r / len(self.values) * 0.2 50 | tex_i = Text(tex, font=self.label_font, color=WHITE, plot_depth=1).set_height(size) 51 | value_i = Text(str(value), font=self.label_font, color=WHITE, plot_depth=1).set_height(size).next_to(tex_i, DOWN * 0.64 * size) 52 | if not self.unit == None: 53 | unit_i = Text(self.unit, font=self.label_font, color=WHITE, plot_depth=1).set_height(size).next_to(value_i, RIGHT * 0.2 * size) 54 | VGroup(value_i, unit_i).next_to(tex_i, DOWN * 0.64 * size) 55 | label_i = VGroup(tex_i, value_i, unit_i) 56 | else: 57 | label_i = VGroup(tex_i, value_i) 58 | angle = TAU/len(self.values) 59 | start_a = np.angle(complex(*self.start_direction[0:2])) 60 | self.labels_group.add(label_i.shift(self.center + complex_to_R3((r-size * 1.2-r*0.05) * np.exp(1j * (start_a + (i + 0.5) * TAU/len(self.values)))))) 61 | return self.labels_group 62 | 63 | def create_cicles(self, color=BLUE_A): 64 | 65 | circle_01 = Circle(radius=self.inner_radius, stroke_width=12, stroke_color=color, plot_depth=2.5) 66 | circle_02 = Circle(radius=self.inner_radius - 0.15, stroke_width=4, stroke_color=color, plot_depth=2.5) 67 | self.circles = VGroup(circle_01, circle_02).move_to(self.center) 68 | self.add(self.circles) 69 | return self.circles 70 | 71 | def create_circle_shadow(self, width=32, num=50, color=BLUE_A): 72 | self.shadow = VGroup(*[Circle(radius=self.inner_radius + (i+0.5) * width/100/num, stroke_width=width/num, stroke_color=color, 73 | stroke_opacity=(i-num) ** 2 * 1/num/num, plot_depth=2) for i in range(num+1)]).move_to(self.center) 74 | self.add(self.shadow) 75 | return self.shadow 76 | 77 | 78 | class MyRotating(Animation): 79 | CONFIG = { 80 | "axis": OUT, 81 | "radians": TAU, 82 | "run_time": 3, 83 | "rate_func": linear, 84 | "about_point": None, 85 | "inner_radius": 1.5, 86 | 'stroke_width': 0, 87 | 'fill_opacity': 1, 88 | 'start_direction': RIGHT, 89 | "len": 27, 90 | "gap": 0.025, 91 | } 92 | 93 | def __init__(self, mobject, target, value, angle_tracker, index, **kwargs): 94 | digest_config(self, kwargs) 95 | self.mobject = mobject 96 | self.target_mobject = target 97 | self.value_tracker = value 98 | self.angle_tracker = angle_tracker 99 | self.index = index 100 | 101 | def interpolate_mobject(self, alpha): 102 | # now_mobject = self.starting_mobject.copy() 103 | r_i = interpolate(self.starting_mobject.outer_radius, self.target_mobject.outer_radius, alpha) 104 | color = interpolate_color(self.starting_mobject.get_color(), self.target_mobject.get_color(), alpha) 105 | start_a = np.angle(complex(*self.start_direction[0:2])) 106 | angle = TAU / self.len 107 | now_mobject = Sector( 108 | arc_center=self.about_point, 109 | inner_radius=self.inner_radius, 110 | outer_radius=r_i, 111 | stroke_width=self.stroke_width, 112 | start_angle=start_a, #+ 1 * angle, 113 | angle=angle * (1 - self.gap), 114 | color=color, 115 | fill_opacity=self.fill_opacity 116 | ) 117 | now_mobject.rotate( 118 | alpha * self.radians, 119 | axis=self.axis, 120 | about_point=self.about_point, 121 | ).set_plot_depth(-100+self.index*2) 122 | self.mobject.become(now_mobject) 123 | self.value_tracker.set_value(r_i) 124 | self.angle_tracker.set_value(start_a + alpha * self.radians) 125 | 126 | # def clean_up_from_scene(self, scene): 127 | # scene.remove(self.mobject) 128 | # scene.add(self.target_mobject) --------------------------------------------------------------------------------