数学分析基础可视化

平面点集基本概念

围绕平面点集基本概念,观察平面点集、邻域、内点之间的关系与推理路径。

打开原视频

point_set_topology.py
1from manim import *2import numpy as np3import random4 5class PointSetTopology(Scene):6    def construct(self):7        # 设置标题8        title = Text("平面点集基本概念", font="SimHei")9        title.to_corner(UL)10        self.play(Write(title))11        self.wait(1)12        13        # 创建坐标系14        axes = Axes(15            x_range=[-5, 5, 1],16            y_range=[-3, 3, 1],17            axis_config={"include_tip": True, "include_numbers": False},18            x_length=10,19            y_length=620        )21        axes_labels = axes.get_axis_labels(x_label="x", y_label="y")22        23        # 显示坐标系24        self.play(Create(axes), Create(axes_labels))25        self.wait(1)26        27        # 定义一个圆形点集(作为我们研究的主要集合)28        circle = Circle(radius=2, color=BLUE)29        circle.move_to(axes.coords_to_point(0, 0))30        31        # 添加圆形到场景32        self.play(Create(circle))33        34        # 添加集合标签35        set_label = MathTex("A", color=BLUE).next_to(circle, UP)36        self.play(Write(set_label))37        38        # 集合定义:平面点集,不显示具体表示39        set_definition = Text("平面点集A", font="SimHei", font_size=24)40        set_definition.to_corner(UR)41        self.play(Write(set_definition))42        self.wait(1)43        44        # 清除定义45        self.play(FadeOut(set_definition))46        47        # ------ 内点演示 ------48        interior_title = Text("内点", font="SimHei", font_size=32)49        interior_title.to_edge(UP)50        # 淡出主标题,显示内点标题51        self.play(FadeOut(title), Write(interior_title))52        53        # 选择集合内的一点54        interior_point = Dot(axes.coords_to_point(0, 0), color=GREEN)55        interior_label = Text("内点", font="SimHei", font_size=24, color=GREEN).next_to(interior_point, UP)56        57        # 添加这个点到场景58        self.play(Create(interior_point), Write(interior_label))59        60        # 创建邻域小圆61        neighborhood = Circle(radius=0.5, color=GREEN, fill_opacity=0.2)62        neighborhood.move_to(interior_point.get_center())63        64        # 显示邻域65        self.play(Create(neighborhood))66        67        # 内点定义68        interior_def = Text("内点:点p存在一个邻域完全包含在集合A中", font="SimHei", font_size=24)69        interior_def.to_edge(DOWN)70        self.play(Write(interior_def))71        self.wait(2)72        73        # 清除内点说明74        self.play(FadeOut(interior_title), FadeOut(interior_def))75        76        # ------ 外点演示 ------77        exterior_title = Text("外点", font="SimHei", font_size=32)78        exterior_title.to_edge(UP)79        self.play(Write(exterior_title))80        81        # 选择集合外的一点82        exterior_point = Dot(axes.coords_to_point(4, 0), color=RED)83        exterior_label = Text("外点", font="SimHei", font_size=24, color=RED).next_to(exterior_point, UP)84        85        # 添加这个点到场景86        self.play(Create(exterior_point), Write(exterior_label))87        88        # 移动邻域到外点89        self.play(90            neighborhood.animate.set_color(RED).move_to(exterior_point.get_center())91        )92        93        # 外点定义94        exterior_def = Text("外点:点p存在一个邻域完全不与集合A相交", font="SimHei", font_size=24)95        exterior_def.to_edge(DOWN)96        self.play(Write(exterior_def))97        self.wait(2)98        99        # 清除外点说明100        self.play(FadeOut(exterior_title), FadeOut(exterior_def))101        102        # ------ 界点演示 ------103        boundary_title = Text("界点", font="SimHei", font_size=32)104        boundary_title.to_edge(UP)105        self.play(Write(boundary_title))106        107        # 选择圆上的一点(界点)108        boundary_point = Dot(axes.coords_to_point(2, 0), color=YELLOW)109        boundary_label = Text("界点", font="SimHei", font_size=24, color=YELLOW).next_to(boundary_point, RIGHT)110        111        # 添加这个点到场景112        self.play(Create(boundary_point), Write(boundary_label))113        114        # 移动邻域到界点115        self.play(116            neighborhood.animate.set_color(YELLOW).move_to(boundary_point.get_center())117        )118        119        # 界点定义120        boundary_def = Text("界点:点p的任何邻域既包含A中的点,又包含不在A中的点", font="SimHei", font_size=24)121        boundary_def.to_edge(DOWN)122        self.play(Write(boundary_def))123        self.wait(2)124        125        # 清除界点说明和邻域126        self.play(FadeOut(boundary_title), FadeOut(boundary_def), FadeOut(neighborhood))127        128        # ------ 分界展示所有点类型 ------129        all_types_title = Text("点的分类总结", font="SimHei", font_size=32)130        all_types_title.to_edge(UP)131        self.play(Write(all_types_title))132        133        # 添加更多示例点134        more_interior_points = [135            Dot(axes.coords_to_point(-1, 0), color=GREEN),136            Dot(axes.coords_to_point(0, 1), color=GREEN),137            Dot(axes.coords_to_point(1, 1), color=GREEN)138        ]139        140        more_exterior_points = [141            Dot(axes.coords_to_point(-3, 0), color=RED),142            Dot(axes.coords_to_point(0, -3), color=RED),143            Dot(axes.coords_to_point(3, 3), color=RED)144        ]145        146        more_boundary_points = [147            Dot(axes.coords_to_point(0, 2), color=YELLOW),148            Dot(axes.coords_to_point(-2, 0), color=YELLOW),149            Dot(axes.coords_to_point(1.414, 1.414), color=YELLOW)  # 约等于√2150        ]151        152        # 添加这些点到场景153        self.play(154            *[Create(p) for p in more_interior_points],155            *[Create(p) for p in more_exterior_points],156            *[Create(p) for p in more_boundary_points]157        )158        159        # 点的分类说明160        points_summary = Text(161            "绿色:内点 (Interior Points)\n"162            "红色:外点 (Exterior Points)\n"163            "黄色:界点 (Boundary Points)",164            font="SimHei",165            font_size=24166        ).to_corner(DR)167        self.play(Write(points_summary))168        self.wait(2)169        170        # 清除分类说明,保留点171        self.play(FadeOut(all_types_title), FadeOut(points_summary))172        173        # 所有点一起淡出,包括聚点(按照要求修改)174        self.play(175            FadeOut(interior_point),176            FadeOut(interior_label),177            FadeOut(exterior_point),178            FadeOut(exterior_label),179            FadeOut(boundary_point),180            FadeOut(boundary_label),181            *[FadeOut(p) for p in more_interior_points],182            *[FadeOut(p) for p in more_exterior_points],183            *[FadeOut(p) for p in more_boundary_points]184        )185        186        # ------ 聚点演示 ------187        accumulation_title = Text("聚点", font="SimHei", font_size=32)188        accumulation_title.to_edge(UP)189        self.play(Write(accumulation_title))190        191        # 选择圆内的一点作为聚点示例(恢复为原来的位置)192        accum_point = Dot(axes.coords_to_point(-1, 1), color=PURPLE)193        accum_label = Text("聚点", font="SimHei", font_size=24, color=PURPLE).next_to(accum_point, UP)194        195        # 添加聚点到场景196        self.play(Create(accum_point), Write(accum_label))197        198        # 创建聚点邻域199        accum_neighborhood = Circle(radius=0.7, color=PURPLE, fill_opacity=0.2)200        accum_neighborhood.move_to(accum_point.get_center())201        self.play(Create(accum_neighborhood))202        203        # 在邻域内添加一系列点204        accum_points = []205        for _ in range(20):206            r = random.uniform(0, 0.6)207            theta = random.uniform(0, 2 * np.pi)208            x = -1 + r * np.cos(theta)209            y = 1 + r * np.sin(theta)210            point = Dot(axes.coords_to_point(x, y), color=BLUE_A, radius=0.03)211            accum_points.append(point)212        213        # 逐渐添加这些点,展示无限多点的概念214        for point in accum_points:215            self.play(Create(point), run_time=0.1)216        217        # 聚点定义218        accum_def = Text("聚点:点p的任何邻域都包含A中无穷多个点", font="SimHei", font_size=24)219        accum_def.to_edge(DOWN)220        self.play(Write(accum_def))221        self.wait(2)222        223        # 清除聚点演示224        self.play(225            FadeOut(accumulation_title),226            FadeOut(accum_def),227            FadeOut(accum_neighborhood),228            FadeOut(accum_point),229            FadeOut(accum_label),230            *[FadeOut(p) for p in accum_points]231        )232        233        # ------ 孤立点演示 ------234        isolated_title = Text("孤立点", font="SimHei", font_size=32)235        isolated_title.to_edge(UP)236        self.play(Write(isolated_title))237        238        # 创建一个新的离散点集B239        set_B_label = MathTex("B", color=ORANGE).next_to(circle, DOWN+LEFT)240        self.play(Write(set_B_label))241        242        # 创建一些孤立点243        isolated_points = [244            Dot(axes.coords_to_point(-3, -2), color=ORANGE),245            Dot(axes.coords_to_point(3, -1), color=ORANGE),246            Dot(axes.coords_to_point(0, -2.5), color=ORANGE)247        ]248        249        # 添加孤立点到场景250        for point in isolated_points:251            self.play(Create(point))252        253        # 为其中一个孤立点添加标签和邻域254        isolated_label = Text("孤立点", font="SimHei", font_size=24, color=ORANGE).next_to(isolated_points[0], UP)255        self.play(Write(isolated_label))256        257        # 创建孤立点邻域258        isolated_neighborhood = Circle(radius=0.5, color=ORANGE, fill_opacity=0.2)259        isolated_neighborhood.move_to(isolated_points[0].get_center())260        self.play(Create(isolated_neighborhood))261        262        # 孤立点定义263        isolated_def = Text("孤立点:点p存在一个邻域,除p外不包含集合中的其他点", font="SimHei", font_size=24)264        isolated_def.to_edge(DOWN)265        self.play(Write(isolated_def))266        self.wait(2)267        268        # 清除孤立点演示269        self.play(270            FadeOut(isolated_title),271            FadeOut(isolated_def),272            FadeOut(isolated_neighborhood),273            FadeOut(isolated_label),274            FadeOut(set_B_label),275            *[FadeOut(p) for p in isolated_points]276        )277        278        # ------ 开集演示 ------279        open_set_title = Text("开集", font="SimHei", font_size=32)280        open_set_title.to_edge(UP)281        self.play(Write(open_set_title))282        283        # 创建一个开圆(不包含边界)284        open_circle = Circle(radius=2, color=GREEN, stroke_width=3)285        open_circle.move_to(axes.coords_to_point(0, 0))286        287        # 添加开集标签288        open_set_label = MathTex("U", color=GREEN).next_to(circle, UP+RIGHT)289        290        # 动画:把原来的圆变成开圆291        dashed_circle = DashedVMobject(circle.copy(), num_dashes=50)292        dashed_circle.set_color(GREEN)293        self.play(294            ReplacementTransform(circle, dashed_circle),295            Write(open_set_label),296            FadeOut(set_label)297        )298        299        # 在场景中添加一些内点来说明开集300        open_set_interior_points = [301            Dot(axes.coords_to_point(0, 0), color=GREEN),302            Dot(axes.coords_to_point(-1, 0), color=GREEN),303            Dot(axes.coords_to_point(1, 1), color=GREEN)304        ]305        306        self.play(*[Create(p) for p in open_set_interior_points])307        308        # 开集定义309        open_set_def = Text("开集:集合中的每个点都是其内点", font="SimHei", font_size=24)310        open_set_def.to_edge(DOWN)311        self.play(Write(open_set_def))312        self.wait(2)313        314        # 清除开集演示315        self.play(316            FadeOut(open_set_title),317            FadeOut(open_set_def),318            *[FadeOut(p) for p in open_set_interior_points]319        )320        321        # ------ 闭集演示 ------322        closed_set_title = Text("闭集", font="SimHei", font_size=32)323        closed_set_title.to_edge(UP)324        self.play(Write(closed_set_title))325        326        # 恢复为完整圆(包含边界)327        closed_circle = Circle(radius=2, color=BLUE)328        closed_circle.move_to(axes.coords_to_point(0, 0))329        330        # 替换开圆为闭圆331        self.play(332            ReplacementTransform(dashed_circle, closed_circle),333            FadeOut(open_set_label),334            Write(set_label)335        )336        337        # 添加界点338        closed_set_boundary_points = [339            Dot(axes.coords_to_point(2, 0), color=YELLOW),340            Dot(axes.coords_to_point(0, 2), color=YELLOW),341            Dot(axes.coords_to_point(-2, 0), color=YELLOW)342        ]343        344        self.play(*[Create(p) for p in closed_set_boundary_points])345        346        # 闭集定义347        closed_set_def = Text("闭集:包含所有聚点的集合", font="SimHei", font_size=24)348        closed_set_def.to_edge(DOWN)349        self.play(Write(closed_set_def))350        self.wait(2)351        352        # 清除闭集演示的标题和定义,但保留图形元素353        self.play(354            FadeOut(closed_set_title),355            FadeOut(closed_set_def)356        )357        358        # 最终结论359        final_title = Text("平面点集基本概念总结", font="SimHei", font_size=32)360        final_title.to_edge(UP)361        self.play(Write(final_title))362        363        # 删除黄色圆圈,直接添加最终总结文字364        final_summary = Text(365            "• 内点、外点、界点构成了平面上所有点的分类\n"366            "• 聚点是极限点或收敛点,邻域内有无穷多点\n"367            "• 孤立点邻域内没有其他点\n"368            "• 开集内每点都是内点\n"369            "• 闭集包含所有聚点",370            font="SimHei",371            font_size=24372        )373        final_summary.to_edge(DOWN)374        self.play(Write(final_summary))375        self.wait(3)376 377        # 注意:不清除整个场景,保留最后的显示内容378        self.wait(2)379 380 381class PointSetRelationships(Scene):382    def construct(self):383        # 设置标题384        title = Text("点集拓扑概念关系", font="SimHei")385        title.to_corner(UL)386        self.play(Write(title))387        self.wait(1)388        389        # 创建图示框架390        frame = Rectangle(height=6, width=10, color=WHITE)391        392        self.play(Create(frame))393        394        # 创建集合A示意图395        set_A_circle = Circle(radius=2, color=BLUE)396        set_A_circle.move_to(ORIGIN)397        398        # 添加集合标签399        set_A_label = MathTex("A", color=BLUE).next_to(set_A_circle, UP)400        401        self.play(402            Create(set_A_circle),403            Write(set_A_label)404        )405        406        # 创建点集概念之间的关系图407        408        # 定义概念节点409        concepts = {410            "int": {"text": "Int(A)\n内部", "pos": UP * 2 + LEFT * 3, "color": GREEN},411            "ext": {"text": "Ext(A)\n外部", "pos": UP * 2 + RIGHT * 3, "color": RED},412            "bdry": {"text": "Bdry(A)\n边界", "pos": DOWN * 2, "color": YELLOW},413            "cl": {"text": "Cl(A)\n闭包", "pos": UP * 0.5 + LEFT * 3, "color": PURPLE},414            "der": {"text": "A'\n导集", "pos": DOWN * 0.5 + LEFT * 3, "color": ORANGE}415        }416        417        # 创建节点418        nodes = {}419        for key, info in concepts.items():420            node = VGroup(421                Circle(radius=0.5, color=info["color"]),422                Text(info["text"], font="SimHei", font_size=20)423            )424            node.move_to(info["pos"])425            nodes[key] = node426        427        # 显示节点428        for key, node in nodes.items():429            self.play(Create(node), run_time=0.7)430        431        # 定义关系432        relations = [433            {"from": "cl", "to": "int", "text": "包含", "pos_adj": RIGHT * 0.5},434            {"from": "cl", "to": "bdry", "text": "包含", "pos_adj": DOWN * 0.5 + RIGHT * 0.5},435            {"from": "cl", "to": "der", "text": "包含", "pos_adj": DOWN * 0.2},436            {"from": "int", "to": "ext", "text": "互斥", "pos_adj": UP * 0.3},437            {"from": "int", "to": "bdry", "text": "互斥", "pos_adj": RIGHT * 0.3},438            {"from": "ext", "to": "bdry", "text": "互斥", "pos_adj": LEFT * 0.3}439        ]440        441        # 创建关系箭头和标签442        arrows = []443        for rel in relations:444            start = nodes[rel["from"]].get_center()445            end = nodes[rel["to"]].get_center()446            447            # 创建箭头448            if rel["text"] == "互斥":449                # 使用虚线和双箭头表示互斥关系450                arrow = DashedLine(451                    start=start,452                    end=end,453                    color=GRAY454                )455            else:456                # 使用实线箭头表示包含关系457                arrow = Arrow(458                    start=start,459                    end=end,460                    color=WHITE,461                    buff=0.6  # 调整箭头与节点的距离462                )463            464            # 创建关系标签465            mid_point = (start + end) / 2 + rel["pos_adj"]466            label = Text(rel["text"], font="SimHei", font_size=18)467            label.move_to(mid_point)468            469            arrows.append(VGroup(arrow, label))470        471        # 显示关系472        for arrow in arrows:473            self.play(Create(arrow), run_time=0.7)474        475        # 添加重要公式476        formulas = [477            {"tex": r"A = \text{Int}(A) \cup \text{Bdry}(A)", "pos": DOWN * 3 + LEFT * 3},478            {"tex": r"\text{Cl}(A) = A \cup A'", "pos": DOWN * 3 + RIGHT * 3},479            {"tex": r"\text{Int}(A) \cap \text{Bdry}(A) = \emptyset", "pos": DOWN * 3.5}480        ]481        482        formula_objs = []483        for f in formulas:484            formula = MathTex(f["tex"])485            formula.move_to(f["pos"])486            formula_objs.append(formula)487            self.play(Write(formula))488        489        # 最后的概念总结490        summary = Text(491            "内点+边界=集合\n"492            "集合+导集=闭包\n"493            "内部、外部、边界两两互斥",494            font="SimHei",495            font_size=24496        )497        summary.to_edge(DOWN)498        499        self.play(500            FadeOut(set_A_circle),501            FadeOut(set_A_label),502            *[FadeOut(node) for node in nodes.values()],503            *[FadeOut(arrow) for arrow in arrows],504            *[FadeOut(formula) for formula in formula_objs],505            FadeOut(frame)506        )507        508        self.play(Write(summary))509        self.wait(3)510        511        # 结束动画512        self.play(FadeOut(summary), FadeOut(title))513        self.wait(1)514 515 516# 运行时请使用以下命令:517# manim -pql point_set_topology.py PointSetTopology518# manim -pql point_set_topology.py PointSetRelationships

讲解

这个视频围绕「平面点集基本概念」展开。画面把问题、图像和公式放在同一条理解路径中,让抽象关系先被看见。

开头先建立问题背景和主要对象,让观察从标题、坐标或第一组关系进入。

画面中出现的文字「平面点集基本概念」给出视觉入口。随后画面通过对象创建、移动、淡入淡出和高亮,把抽象命题拆成可以跟随的步骤。

随后出现更具体的图像或公式提示,动画会把局部对象和整体结论联系起来。这里可以重点观察变量、曲线、区域或向量如何随镜头推进而变化。

观察路径

观察路径可以分三步:先锁定「平面点集基本概念」中的核心对象,尤其留意平面点集、邻域、内点之间的联系;再跟随画面中变量、图像或向量的变化;最后回到公式或结论,判断局部变化如何支撑整体关系。

本页可以从平面点集、邻域、内点、边界点这些概念进入,继续沿相邻问题观察同一类数学结构。