ZhangZhihui's Blog  

 

1

 

class BraceAnnotation(Scene):
    def construct(self):
        dot = Dot([-2, -1, 0])
        dot2 = Dot([2, 1, 0])
        line = Line(dot.get_center(), dot2.get_center()).set_color(ORANGE)
        b1 = Brace(line)
        b1text = b1.get_text("Horizontal distance")
        b2 = Brace(line, direction=line.copy().rotate(PI / 2).get_unit_vector())
        b2text = b2.get_tex("x-x_1")
        self.add(line, dot, dot2, b1, b2, b1text, b2text)

我不理解dot.get_center(),为什么一个点能有get_center()方法?

 

这是一个非常棒的直觉!从几何学的抽象定义来看,“点” (Point) 确实是没有体积、没有半径的,它本身就是一个坐标位置,似乎谈不上“中心”。

但在 Manim 的程序架构中,Dot 的本质是一个 Mobject(数学对象)。理解这个问题的关键在于区分 “数学上的点” 和 “程序里的对象”:

1. 继承的力量:万物皆有中心

在 Manim 中,几乎所有能显示在屏幕上的东西(圆、方块、甚至一个点)都继承自 Mobject 类。

  • Mobject 在程序设计上被视为一个矩形区域(Bounding Box)。

  • 即使是 Dot,它在屏幕上也有像素尺寸(默认半径为 0.08)。

  • get_center() 是定义在最顶层基类 Mobject 上的方法。这意味着,只要是一个对象,Manim 就会为它维护一个坐标系统。

2. 为什么不直接用坐标?

你可能会问:“既然我已经知道 dot 是在 [-2, -1, 0],为什么不直接写坐标,而要调用 dot.get_center()?”

这就是 “声明式编程” 与 “硬编码” 的区别:

  • 硬编码 (Hardcoding):Line([-2, -1, 0], [2, 1, 0])。如果你以后想把点移动到 [-3, 0, 0],你必须手动去改 Line 的坐标。

  • 动态关联 (Dynamic Reference):Line(dot.get_center(), ...)。如果你在代码前面改变了 dot 的位置(比如执行了 dot.shift(UP)),Line 依然能自动抓取到 dot 最新的位置。

3. get_center() 的实际意义

对于 Dot 来说,get_center() 返回的就是它那个“像素圆心”的坐标。

在你的代码中:

Python
 
line = Line(dot.get_center(), dot2.get_center())

这行代码的潜台词是:“我不在乎这两个点具体在哪里,我只要这根线始终连接这两个对象的中心。”


进阶:更好的写法

其实在 Manim 中,连 get_center() 都可以省略。Line 对象非常聪明,如果你直接把对象传给它,它会自动调用它们的中心:

Python
 
# 这样写效果是一样的,而且更简洁
line = Line(dot, dot2).set_color(ORANGE)

总结 (TL;DR)

  • 数学上:点确实就是中心。

  • 程序上:Dot 是一个有大小的对象,get_center() 是为了统一接口。

  • 逻辑上:使用 get_center() 是为了让对象之间建立位置关联,而不是写死坐标。

这种思想在你以后处理复杂的 Brace(大括号)定位时会非常有用——你会发现大括号的位置往往也是相对于某个对象的 get_center() 或者 get_edge() 来确定的。

 

posted on 2026-05-15 11:27  ZhangZhihuiAAA  阅读(26)  评论(0)    收藏  举报