|
# https://discord.com/channels/581738731934056449/1414961601127383170/1415086069568766024 |
|
from manim import * |
|
|
|
class dotinbox(Scene): |
|
def construct(self): |
|
outerbox = RegularPolygon(n=6).rotate(5*DEGREES).scale_to_fit_height(7) |
|
innerobjs = VGroup( |
|
RegularPolygon(n=5, fill_opacity=1).scale_to_fit_height(2).shift(UR), |
|
Square(side_length=1).shift(DL) |
|
) |
|
self.add(outerbox,innerobjs) |
|
dot = Dot(point=[-1,1,0],color=RED) |
|
dot.vel = np.array([3,0,0]) |
|
def dotupdater(mobj,dt): |
|
mobj.shift(dt*mobj.vel) |
|
ins = Intersection(outerbox,mobj) |
|
if ((ins.width*ins.height) < (mobj.width*mobj.height)/2): |
|
mp = mobj.get_center() |
|
mobj.shift(-dt*mobj.vel) |
|
vsdiff = [v - mp for v in outerbox.get_vertices()] |
|
vsdiff.sort(key=np.linalg.norm) |
|
norm = np.array([[0,-1,0],[1,0,0],[0,0,0]]) @ (vsdiff[1]-vsdiff[0]) |
|
projNV = ((mobj.vel @ norm)/(norm @ norm)) * norm |
|
mobj.vel = mobj.vel - 2*projNV |
|
mobj.shift(dt*mobj.vel) |
|
|
|
for inner in innerobjs: |
|
ins = Intersection(inner,mobj) |
|
if ((ins.width*ins.height) > (mobj.width*mobj.height)/2): |
|
mp = mobj.get_center() |
|
mobj.shift(-dt*mobj.vel) |
|
vsdiff = [v - mp for v in inner.get_vertices()] |
|
vsdiff.sort(key=np.linalg.norm) |
|
norm = np.array([[0,-1,0],[1,0,0],[0,0,0]]) @ (vsdiff[1]-vsdiff[0]) |
|
projNV = ((mobj.vel @ norm)/(norm @ norm)) * norm |
|
mobj.vel = mobj.vel - 2*projNV |
|
mobj.shift(dt*mobj.vel) |
|
dot.add_updater(dotupdater) |
|
dots = VGroup( |
|
dot.copy().set_color(np.random.choice([RED,GREEN,YELLOW,TEAL,BLUE,ORANGE])) |
|
for _ in range(10) |
|
) |
|
for d in dots: |
|
d.vel = np.array([np.random.uniform(-2,2),np.random.uniform(-2,2),0]) |
|
self.add(dots) |
|
self.wait(25) |