首页 > 其他分享 >元素周期表及元素性质

元素周期表及元素性质

时间:2023-03-11 20:33:54浏览次数:29  
标签:orbital dots color self 元素 dot property 周期表 性质

from manim import *
import elementy.elements as elements

frame_width = config["frame_width"]
frame_height = config["frame_height"]

Elements = elements.get_elements()

def narrator(a):
    for i in a:
        globals()[f't{str(i)}']=Text(a[i], font = "STZhongsong").to_edge(DOWN).scale(0.6)

class Element(VGroup):
    def __init__(
        self,
        **kwargs
    ):
        super().__init__(**kwargs)
        square = RoundedRectangle(height=2, width=2, corner_radius=0.3, fill_opacity=0.8, fill_color=GRAY)
        self.add(square)
        self.square = square

    def add_content(self, current_content = None, next_content = None, is_number = True):

        if is_number:
            font_size = 15
        else:
            font_size = 25

        if current_content is not None:
            mob_current_content = Text(current_content, font_size=font_size).move_to(self)
            self.add(mob_current_content)
            self.current_content = mob_current_content

        if next_content is not None:
            mob_next_content = Text(next_content, font_size=font_size).move_to(self).flip(axis=[1,0,0]).set_opacity(0)
            self.add(mob_next_content)
            self.next_content = mob_next_content
        
    @property
    def flip(self):
        anim =  AnimationGroup(self.square.animate.flip(axis=[1,0,0]).set_color(self.target_color),
                              self.current_content.animate.flip(axis=[1,0,0]).set_opacity(0),
                              self.next_content.animate.flip(axis=[1,0,0]).set_opacity(1))
        return anim

    def get_target_color(self, value, min, max, color1, color2):
        target_value = (value-min)/(max-min)
        color = interpolate_color(color1, color2, target_value)
        self.target_color = color

class ElementsPeriodicTable(VGroup):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        row = 5
        col = 18
        elements = VGroup()
        for i in range(row):
            for j in range(col):
                elements.add(Element())
        
        elements.arrange_in_grid(row, col, buff=0.5)
        elements.set_width(frame_width*0.95)
        del elements.submobjects[1:17]
        del elements.submobjects[4:14]
        del elements.submobjects[12:22]

        self.elements = elements
        self.add(elements)

        self.origin()

    def origin(self):
        n = 0
        symbol = []
        for element in self.elements:
            element.add_content(current_content=Elements[n].symbol, is_number=False)
            symbol.append(Elements[n].symbol)
            n += 1
        self.symbol = symbol

    def to_property(self, property_list, color1, color2):
        max_value = max(property_list)
        min_value = min(property_list)

        self.get_full_graph()
        n = 0
        for element in self.elements:
            value = property_list[n]
            element.add_content(next_content=str(round(value, 2)))
            element.get_target_color(value, min_value, max_value, color1, color2)
            n += 1
        anim1 = LaggedStart(*[ele.flip for ele in self.elements], run_time=3)
        anim2 = Wait(3)
        anim = Succession(anim1, anim2)

        return anim

    @property
    def to_affinity(self):
        property_list = [Elements[i].electron_affinity for i in range(len(self.elements))]
        print(property_list)
        self.property_list = property_list
        self.graph_color = PURPLE
        return self.to_property(property_list, PURPLE_A, PURPLE_E)
        
    
    @property
    def to_ionization(self):
        property_list = [Elements[i].ionisation_energies[0] for i in range(len(self.elements))]
        self.property_list = property_list
        self.graph_color = BLUE
        return self.to_property(property_list, BLUE_A, BLUE_E)

    @property
    def to_radius(self):
        property_list = [Elements[i].radius_covalent for i in range(len(self.elements))]
        self.property_list = property_list
        self.graph_color = GREEN
        return self.to_property(property_list, GREEN_A, GREEN_E)
    
    def get_graph(self):
        property_list = self.property_list
        period = self.period
        symbol = self.symbol
        if period == 1:
            ele_index = [0, 2]
        elif period == 2:
            ele_index = [2, 10]
        elif period == 3:
            ele_index = [10, 18]
        elif period == 4:
            ele_index = [18, 36]
        elif period == 5:
            ele_index = [36, 54]
        period_property_list = property_list[ele_index[0]:ele_index[1]]
        period_symbol = symbol[ele_index[0]:ele_index[1]]
        max_value = max(period_property_list)
        min_value = min(period_property_list)
        plane = NumberPlane(
            x_range = (0, len(period_property_list)),
            y_range = (min_value, max_value),
            x_length = frame_width*0.8,
            y_length = frame_height*0.6,
            axis_config={"include_numbers": True}
        )
        graph = plane.plot_line_graph(
            x_values = [i + 1 for i in range(len(self.elements))],
            y_values = period_property_list,
            line_color = self.graph_color
        )
        graph.center()
        n = 0
        graph_vg = VGroup(graph)
        for dot in graph["vertex_dots"]:
            text = Text(period_symbol[n], font_size=30).next_to(dot, UP)
            graph_vg.add(text)
            n += 1
        self.graph = graph_vg
    
    def set_period(self, period):
        self.period = period
        self.get_graph()

    def get_full_graph(self):
        property_list = self.property_list
        symbol = self.symbol
        max_value = max(property_list)
        min_value = min(property_list)
        plane = NumberPlane(
            x_range = (0, len(property_list)),
            y_range = (min_value, max_value),
            x_length = frame_width*0.8,
            y_length = frame_height*0.6,
            axis_config={"include_numbers": True}
        )
        graph = plane.plot_line_graph(
            x_values = [i + 1 for i in range(len(self.elements))],
            y_values = property_list,
            line_color = self.graph_color
        )
        graph.center()
        # n = 0
        # graph_vg = VGroup(graph)
        # for dot in graph["vertex_dots"]:
        #     text = Text(symbol[n], font_size=15).next_to(dot, UP)
        #     graph_vg.add(text)
        #     n += 1
        self.full_graph = graph
        return graph

class AtomicOrbitalTemplate(TexTemplate):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.add_to_preamble("\\usepackage{tikzorbital}")

class AtomicOrbital(VGroup):
    def __init__(
        self,
        orbital_name: str,
        orbital_name_tex: str,
        **kwargs
    ):
        super().__init__(**kwargs)
        self.template = AtomicOrbitalTemplate()
        orbital = MathTex("\\begin{tikzpicture} \\orbital{%s}  \\end{tikzpicture}" % orbital_name, tex_template = self.template, stroke_width=2, fill_color=BLUE, fill_opacity=0.6, **kwargs)
        name = MathTex(orbital_name_tex)
        name.next_to(orbital, DOWN)
        self.orbital = orbital
        self.name = name
        self.add(self.orbital)
        self.add(self.name)

class AtomicElectronsArrangement(VGroup):
    def __init__(self, orbital_name, orbital_label, electrons_num, **kwargs):
        super().__init__(**kwargs)
        if orbital_name == 's':
            self.orbital_lines_buff = 2
            self.orbital_num = 1
            self.orbital_name_shift_distance = 0
            orbital = AtomicOrbital('s', orbital_label)
        elif orbital_name == 'p':
            self.orbital_lines_buff = 6
            self.orbital_num = 3
            self.orbital_name_shift_distance = 0.3
            orbital = AtomicOrbital('py', orbital_label)
        elif orbital_name == 'd':
            self.orbital_lines_buff = 6
            self.orbital_num = 5
            self.orbital_name_shift_distance = 0.8
            orbital = AtomicOrbital('dyz', orbital_label)
        lines = VGroup(*[Line(LEFT/2, RIGHT/2) for i in range(self.orbital_num)])
        lines.arrange(buff=0.5)
        orbital.next_to(lines[0], self.orbital_lines_buff*LEFT)
        orbital.name.shift(self.orbital_name_shift_distance*DOWN)
        self.orbital = orbital
        self.add(lines, orbital)
        self.center()
        dots = VGroup()
        if electrons_num > self.orbital_num:
            for i in range(self.orbital_num):
                dot = Dot(color=BLUE).move_to(lines[i]).shift(0.2*UP + 0.3*LEFT)
                arrow = MathTex(r'\uparrow').set_color(BLUE).scale(0.8).next_to(dot, 0.5*UP)
                dots.add(VGroup(dot ,arrow))
            for i in range(electrons_num - self.orbital_num):
                dot = Dot(color=RED).move_to(lines[i]).shift(0.2*UP + 0.3*RIGHT)
                arrow = MathTex(r'\downarrow').set_color(RED).scale(0.8).next_to(dot, 0.5*UP)
                dots.add(VGroup(dot ,arrow))
        else:
            for i in range(electrons_num):
                dot = Dot(color=BLUE).move_to(lines[i]).shift(0.2*UP + 0.3*LEFT)
                arrow = MathTex(r'\uparrow').set_color(BLUE).scale(0.8).next_to(dot, 0.5*UP)
                dots.add(VGroup(dot ,arrow))
        dots.set_opacity(0)
        self.add(dots)
        self.dots = dots

        self.show_dots = self.anim_show_dots()

    def anim_show_dots(self):
        anim = Succession(*[ApplyMethod(dot.set_opacity, 1) for dot in self.dots])  # bug:使用 animate 会使物件 opacity 变为 1 的同时回到屏幕中心
        return anim
    
class AnimIonization(VGroup):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.Be_B = self.mob_Be_B()
        self.N_O = self.mob_N_O()
    
    def mob_Be_B(self):
        text = VGroup(Text('Be', font_size=30), Text('B', font_size=30)).arrange(buff=5)
        text.shift(2*DOWN)
        Be_e = AtomicElectronsArrangement('s', '2s', 2).scale(0.8).next_to(text[0], 6*UP)
        B_e1 = AtomicElectronsArrangement('s', '2s', 2).scale(0.8)
        B_e2 = AtomicElectronsArrangement('p', '2p', 1).scale(0.8)
        B_e = VGroup(B_e1, B_e2).arrange(direction=UP, buff=1).next_to(text[1], 2*UP)
        self.show_Be_B_dots = Succession(Be_e.show_dots, B_e1.show_dots, B_e2.show_dots)
        mob_vg = VGroup(text, Be_e, B_e)
        return mob_vg
    
    def mob_N_O(self):
        text = VGroup(Text('N', font_size=30), Text('O', font_size=30)).arrange(buff=5)
        text.shift(DOWN)
        N_e = AtomicElectronsArrangement('p', '2p', 3).scale(0.6).next_to(text[0], 3*UP)
        O_e = AtomicElectronsArrangement('p', '2p', 4).scale(0.6).next_to(text[1], 3*UP)
        self.show_N_O_dots = Succession(N_e.show_dots, O_e.show_dots)
        mob_vg = VGroup(text, N_e, O_e)
        return mob_vg

class AnimAtomRadius(VGroup):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.two_atoms = self.mob_two_atoms()
        self.mob_atom()
        self.shrink = self.anim_shrink()
        self.grow = self.anim_grow()

    def anim_atom_wave(self, mob, radius=2):
        wave = Circle(radius=radius).set_color(color=[BLUE_B, BLUE_D])
        anim = Broadcast(wave, focal_point=mob.get_center(), n_mobs=4, initial_opacity=0.8, run_time=4)
        return anim

    def mob_two_atoms(self):
        atom1 = Circle(radius=2, fill_opacity=0.8).set_color(color=[BLUE_A, BLUE_E])
        atom2 = Circle(radius=2, fill_opacity=0.8).set_color(color=[BLUE_E, BLUE_A]).shift(3*RIGHT)
        line = DashedLine(0.75*LEFT, 0.75*RIGHT).shift(0.75*RIGHT)
        vertical_line = Line(3*UP, 3*DOWN, color=BLUE)
        atoms = VGroup(atom1, atom2).center()
        self.show_two_atoms = AnimationGroup(self.anim_atom_wave(atom1), self.anim_atom_wave(atom2))
        lines = VGroup(line, vertical_line)
        self.show_lines_of_two_atom = Succession(DrawBorderThenFill(lines), FadeOut(lines))
        return atoms
    
    def mob_atom(self):
        single_atom = Circle(radius=2, fill_opacity=0.8).set_color(color=[BLUE_A, BLUE_E]).set_z_index(-2)
        nucleus = Circle(radius=0.3, fill_opacity=0.8).set_color(color=[GREEN_A, GREEN_E]).set_z_index(2)
        atom = VGroup(single_atom, nucleus)
        single_atom.save_state()
        self.single_atom = single_atom
        self.nucleus = nucleus
        self.atom = atom
    
    def anim_shrink(self):
        dots_lines = VGroup()
        for i in range(4):
            dot = Dot().set_color(color=[RED, PURPLE])
            distance = 0.3 + np.random.random()
            angle = np.random.random()*2*PI
            dot.shift([distance*np.cos(angle), distance*np.sin(angle), 0])
            line = DashedLine(dot.get_center(), self.atom.get_center(), dashed_ratio=0.5).set_opacity(0.6)
            rotate_angle = angle_of_vector(dot.get_center())
            arrow = MathTex(r'\leftarrow').scale(0.8).shift(line.get_length()/2*RIGHT).rotate(rotate_angle, about_point=ORIGIN)
            dot_line = VGroup(dot, line, arrow).add_updater(lambda z: z.rotate(0.04, about_point=ORIGIN))
            dots_lines.add(dot_line)
            self.shrink_dots_lines = dots_lines


        anim = Succession(*[Succession(AnimationGroup(FadeIn(dot_line), ApplyMethod(self.single_atom.scale, 0.9)), Wait(2)) for dot_line in dots_lines])
        return anim
    
    def anim_grow(self):
        dots = VGroup()
        dots_lines = VGroup()
        for i in range(4):
            dot = Dot().set_color(color=[RED, PURPLE])
            distance = 0.5 + np.random.random()*1.5
            angle = np.random.random()*2*PI
            dot.shift([distance*np.cos(angle), distance*np.sin(angle), 0])
            dot.add_updater(lambda z: z.rotate(0.04, about_point=ORIGIN))
            lines = VGroup()
            for pre_dot in dots:
                def generate_updater(line, dot1, dot2):
                    def updater(line):
                        line.become(DashedLine(dot1.get_center(), dot2.get_center(), dashed_ratio=0.5).set_opacity(0.6))
                    return updater
                single_line = DashedLine(dot.get_center(), pre_dot.get_center(), dashed_ratio=0.5).set_opacity(0.6)
                single_line.add_updater(generate_updater(single_line, dot, pre_dot))
                lines.add(single_line)
            dot_line = VGroup(dot, lines)
            dots.add(dot)
            dots_lines.add(dot_line)
            self.grow_dots_lines = dots_lines


        anim = Succession(Restore(self.single_atom), *[Succession(AnimationGroup(FadeIn(dot_line, suspend_mobject_updating=False, run_time=0.01), ApplyMethod(self.single_atom.scale, 1.1)), Wait(2)) for dot_line in dots_lines])
        return anim
    

 

标签:orbital,dots,color,self,元素,dot,property,周期表,性质
From: https://www.cnblogs.com/daxiangcai/p/17206874.html

相关文章

  • web自动化测试-元素定位(四)
    对浏览器的控制,通过webdriver对象对网页内容(元素)的控制,通过webElement对象元素定位,实际上就是通过webdriver,获取webElement的过程selenium提供了8个定位策略1.什么是元......
  • lc203.移除链表元素
    题目给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val==val的节点,并返回新的头节点。示例输入:head=[1,2,6,3,4,5,6],val=6输出:[......
  • 竞赛图的性质
    竞赛图是把一个完全图的边定向后得到的有向图,所以也是一个\(n\)个点\(\binom{n}{2}\)条边的无自环重边的有向图。竞赛图有许多优美的性质和定理,并且多半都和强连通分......
  • 监听元素属性变化
    <divid="div1">111111111</div><buttononclick="handleClick()">OK</button><scripttype="text/javascript"charset="utf-8">constdiv1=document.querySele......
  • Grid布局,根据元素个数,自适应宽高
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content=......
  • 解决vue中v-html元素中标签样式失效问题
    最近在项目中遇到移动端和pc端样式冲突的问题。加上scoped会导致v-html下绑定的标签样式不生效、第三方引用的类库对其修改也不生效,特此总结一下几点,用来解决: Vue为v-......
  • Appium - 元素定位与操作
    Appium常用API。元素定位DOM结构dom:DocumentObjectModel,文档对象模型。dom应用:用于表示界面的控件层级,界面的结构化描述。常见的格式为html\xml。核心元素为......
  • jquery遍历元素children、find、parent、parents、parentsUntil、next、prev、sibling
    ​​​​全栈工程师开发手册(作者:栾鹏)​​jquery系列教程2-DOM操作全解​​jquery遍历元素jquery元素的函数包括children、find、parent、parents、parentsUntil、next......
  • jquery删除替换元素remove、detach、empty、replaceWith、replaceAll
    ​​​​全栈工程师开发手册(作者:栾鹏)​​jquery系列教程2-DOM操作全解​​jquery删除替换元素jquery中进行删除替换元素的函数包括remove、detach、empty、replaceWith......
  • jquery获取设置元素宽高位置height()、width()、offset()、position()、scrollTop()、
    ​​​​全栈工程师开发手册(作者:栾鹏)​​jquery系列教程2-style样式操作全解​​jquery获取设置元素宽高位置jquery的通过height()、width()、offset()、position()、s......