翼度科技»论坛 编程开发 python 查看内容

manim边学边做--MathTex

5

主题

5

帖子

15

积分

新手上路

Rank: 1

积分
15
上一篇介绍的SingleStringMathTex主要用来显示只有一行的数学公式,
对于复杂的数学公式,可以使用MathTex类。
MathTex类继承自SingleStringMathTex,在其基础之上增加了更多的功能。
其实,MathTex是制作数学动画时常用的类,反而SingleStringMathTex用的不多。

MathTex在manim各个模块中的位置大致如上图中所示。
1. 主要参数

MathTex的主要参数有:
参数名称类型说明tex_stringslist多个latex格式的公式arg_separatorstring多个公式之间的间隔substrings_to_isolatelist将公式中分离成一个个小部分tex_to_color_mapdict公式中不同部分的颜色设置tex_environmentstr不熟悉latex的话不要设置2. 主要方法

MathTex继承了SingleStringMathTex之后,扩展了不少新的方法,可以更好的控制和展示数学公式。
名称说明get_part_by_tex获取 latex公式 中的一部分get_parts_by_tex获取 latex公式 中的多个部分index_of_part公式的某部分在整个公式中的索引index_of_part_by_tex某个tex string在整个公式中的索引set_color_by_tex根据某个 tex string 设置颜色set_color_by_tex_to_color_map用字典的形式设置多个 tex string 的颜色set_opacity_by_tex根据某个 tex string 设置透明度sort_alphabetically按字母顺序排列 latex公式 中的各个部分MathTex的大部分方法都要配合substrings_to_isolate参数来一起使用,
通过substrings_to_isolate将完整的数学公式划分成一个个小部分,然后设置不同的样式。
3. 使用示例

下面的使用示例,大部分是结合参数方法一起使用的。
3.1. 公式之间的间隔

MathTex支持输入多个公式,多个公式之间默认是空格分隔,可以通过arg_separator参数设置不同的分隔。
  1. tex = MathTex("z", "=",
  2.               "\sqrt{x^2+y^2}")
  3. tex = MathTex("z", "=",
  4.               "\sqrt{x^2+y^2}",
  5.               arg_separator="\quad")
复制代码
\quad表示设置4个空格。

3.2. 拆分公式

拆分公式非常有用,拆分之后,可以对公式的一部分进行操作.
比如设置颜色,透明度,甚至可以在公式的不同部分应用不同的动画,做出更酷炫的展现形式。
默认情况下,公式是一个整体,哪怕用公式中的一个字符去获取,也会得到整个公式。
  1. tex = MathTex("z=\sqrt{x^2+y^2}")
  2. print(f"{len(tex) =}")
  3. ## 输出结果:
  4. # len(tex) =1
  5. part = tex.get_part_by_tex("x")
  6. print(f"{part = }")
  7. ## 输出结果:
  8. # part = SingleStringMathTex('z=\\sqrt{x^2+y^2}')
复制代码
所以,先使用substrings_to_isolate参数拆分公式,
然后就可以使用get_part_by_tex,get_parts_by_tex这些函数来获取公式的不同部分。
  1. tex = MathTex("y=ax^2+bx+c",
  2.               substrings_to_isolate=["x", "y"])
  3. print(f"{len(tex) =}")
  4. ## 输出结果:
  5. # len(tex) =6
  6. part = tex.get_part_by_tex("y")
  7. print(f"{part = }")
  8. ## 输出结果:
  9. # part = SingleStringMathTex('y')
  10. parts = tex.get_parts_by_tex("x")
  11. print(f"{parts = }")
  12. ## 输出结果:
  13. # parts = VGroup(SingleStringMathTex('x'),
  14. #                SingleStringMathTex('x'))
复制代码
从上面的示例中看出,对于公式 \(y=ax^2+bx+c\),按\(x,y\)分割之后,
整个公式被分成了6份,所以len(tex)=6,分成了:

  • \(y\)
  • \(=a\)
  • \(x\)
  • \(^2+b\)
  • \(x\)
  • \(+c\)
也就是说,substrings_to_isolate中指定的\(x,y\)作为了整个公式的分割点。
tex.get_part_by_tex("y")得到的是包含\(y\)的那部分公式,因为\(y\)在substrings_to_isolate中,
所以上面示例中返回的是part = SingleStringMathTex('y')。
如果是tex.get_part_by_tex("a")的话,返回的将是part = SingleStringMathTex('=a')。
上面分成的6个部分中,有两个部分包含\(x\),
所以parts = tex.get_parts_by_tex("x")返回的VGroup包含两个元素。
通过index_of_part,index_of_part_by_tex可以根据索引来获取公式被分割的各个部分。
  1. tex = MathTex("y=ax^2+bx+c",
  2.               substrings_to_isolate=["x", "y"])
  3. part = tex.get_part_by_tex("b")
  4. print(tex.index_of_part(part))
  5. ## 输出结果
  6. # 3
  7. print(tex.index_of_part_by_tex("b"))
  8. ## 输出结果
  9. # 3
复制代码
在分成的6个部分中,\(b\)所在的部分是第4个,index是从0开始的,所以示例中输出结果为3。
之所以要拆分公式,就是为了对不同的部分进行不同的操作,下面的示例样式拆分之后带来的应用。
3.3. 公式着色

使用拆分前,虽然也可以通过color属性给公式着色,但是只能给整个公式设置一个颜色:
  1. tex = MathTex(
  2.     "z=\sqrt{x^2+y^2}",
  3.     color=RED,
  4. )
复制代码
拆分之后,可以通过set_color_by_tex给不同的部分设置不同的颜色:
  1. tex = MathTex("z", "=", "\sqrt{x^2+y^2}",
  2.               substrings_to_isolate=["x", "y", "z"])
  3. tex.set_color_by_tex("x", RED)
  4. tex.set_color_by_tex("y", GREEN)
  5. tex.set_color_by_tex("z", BLUE)
复制代码
同时设置多个颜色,也可以用set_color_by_tex_to_color_map方法:
  1. tex.set_color_by_tex_to_color_map({
  2.     "x": BLUE, "y": RED, "z": GREEN
  3. })
复制代码
上面三种方式着色后的效果如下:

3.4. 透明度设置

除了颜色,拆分之后,也可以给不同的部分设置透明度。
  1. tex = MathTex(    "z",    "=",    "\sqrt{x^2+y^2}",    substrings_to_isolate=["x", "y", "z"],)tex.set_opacity_by_tex("x", 0.4)tex.set_opacity_by_tex("y", 0.4)tex.set_opacity_by_tex("z", 0.6)tex.set_color_by_tex_to_color_map({
  2.     "x": BLUE, "y": RED, "z": GREEN
  3. })
复制代码
给\(x,y,z\)方别设置的不同的透明度和颜色,和未设置透明度时的对比如下:

3.5. 排序

最后这个是排序功能,是将数学公式的各个部分按照ASCII码的顺序排序。
比如,排序前(正常的公式从左到右的顺序排列各个部分):
  1. tex = MathTex("c>a>b",
  2.               substrings_to_isolate=["a", "b", "c"])
  3. for i in range(len(tex)):
  4.     print(tex[i])
  5. ## 输出结果:
  6. # SingleStringMathTex('c')
  7. # SingleStringMathTex('>')
  8. # SingleStringMathTex('a')
  9. # SingleStringMathTex('>')
  10. # SingleStringMathTex('b')
复制代码
排序后:
  1. tex.sort_alphabetically()
  2. for i in range(len(tex)):
  3.     print(tex[i])
  4. ## 输出结果:
  5. # SingleStringMathTex('>')
  6. # SingleStringMathTex('>')
  7. # SingleStringMathTex('a')
  8. # SingleStringMathTex('b')
  9. # SingleStringMathTex('c')
复制代码
按照ASCII码的顺序重新排列了各个部分。
这样排列有什么用呢?通过动画来显示公式时,渲染的顺序不一样。
排序前,从左到右一次显示c, >, a, >, b;
排序后,显示顺序为变为>, >, a, b, c。

4. 附件

文中完整的代码放在网盘中了(math_tex.py),
下载地址: 完整代码 (访问密码: 6872)

来源:https://www.cnblogs.com/wang_yb/p/18272507
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具