相关文章推荐
愉快的柿子  ·  mysql 随机数函数 ...·  1 年前    · 
有情有义的葡萄酒  ·  Structured ...·  1 年前    · 

我不明白的部分是如何在分子撞击边界面时创建一个简单的台球式反射。我假设的是简单的对称反射(边界处的入角=出角)。我还没有开始写代码,因为我不知道如何处理这部分,而我知道如何做其他部分。我知道这更像是一个数学问题,但我怎样才能在python中创建这些边界条件?理想情况下,我希望必须自己来编程这个功能,这样我才能理解它,而不是使用一个可以做这个的预建包。这就是我正在寻找的,对于任何给定的分子。

最终,我真正需要的是:给定初始位置(x1,y2),矢量大小v,角度θ,以及盒子的大小和位置,分子的最终静止位置是什么(x2,y2)。

3 个评论
如果这一切对你来说都是一样的,实际上做一个 "适当的 "角入等于角出的反射要容易得多。例如,请看。 here .
对我来说,这都是一样的!谢谢!这只是表明我对这个问题了解得很少。
但是,我不能放弃这个机会。我想用连续的矢量长度而不是整数来表示位移,而且我需要知道每个时间步长的点阵列中每个点的新位置。谢谢你的回答。它肯定会让我更接近。
python
numpy
physics
billiards
bart cubrich
bart cubrich
发布于 2019-03-07
3 个回答
Tarifazo
Tarifazo
发布于 2019-03-07
已采纳
0 人赞同

你不需要计算反射角,只要把问题分解成两个:一个是 x ,一个是 y 。在这两种情况下,你需要粒子在超过边界时 "回去"。

我以前在研究流体中的粒子密度时做过这个练习。最简单的是在两个方向都考虑一个(0,1)的边界。下面的代码应该可以做到这一点(提示:正确使用 abs 会产生相当于反射的效果)。

x0 = [.1, .9]
delta = [-0.2, 0.3]
x1 = [(1-abs(abs(xi + di)-1)) for xi, di in zip(x0, delta)]
print(x1)
# 0.1, 0.8
#or using numpy:
x1 = 1-np.abs(np.abs(np.asarray(x0) + np.asarray(delta))-1)
print(x1)
>> [0.09999999999999998, 0.8]
   array([0.1, 0.8])

我从你的问题中假定,你忽略了粒子与粒子的碰撞和粒子与粒子的 "非叠加"。

是的,我一开始就想让它尽可能简单。无摩擦、无碰撞的球体,以随机的初始速度和方向开始,并保持其方向。以后添加碰撞和摩擦可能会很有趣,但我真的只想做一个模仿扩散的视觉效果,但只处理粒子运动。当然,其他的效果会有很大的不同,但我认为这个视觉效果还是可以的。
This codes needs something recursive for multiple reflections right?
嗯,或者我想你可以把时间步长保持得非常小,这样每一步就不会有太多的运动发生。然后你就在每个时间步长中更新粒子的行进方向,这将在反弹时发生变化。
关注小空间的 "三角洲",而不是时间步骤。如果你的delta小于1(因为它应该是),你不能得到一个以上的反射。使用类似 np.clip(np.random.normal(mu, sigma), -0.99, 0.99)) 的东西。在每个步骤中,计算x和y的平均位置,并绘制它与步骤数的关系:你应该看到它移动到(0.5,0.5)。
谢谢!这就是我所想的。我可能会使用更小的时间延迟,因为你可以在角落里得到一些双重反射,在那里你的一些台球可能会逃跑。
Paul Panzer
Paul Panzer
发布于 2019-03-07
0 人赞同

这里是一个简单的实现。我每隔十步才改变运动向量,这样就可以直观地检查边界反射。当运动向量被更新时,粒子会闪烁红色。

所述的技巧 ħere 是 "展开 "边界盒。相反,我们让粒子不受约束地移动,然后将空间折叠到边界盒中。

import numpy as np
import pylab
from matplotlib.animation import FuncAnimation
xy = np.random.uniform(-1, 1, (2, 200))
xy[0, :160] = np.abs(xy[0, :160])
xy[0, 160:] = -np.abs(xy[0, 160:])
xy += 1
f, a = pylab.subplots()
pxy, = pylab.plot(*xy, 'o')
def init():
    a.set_xlim(0, 2)
    a.set_ylim(0, 2)
    return pxy,
def update(frame):
    global inc, xy
    if frame % 1 < 0.01:
        inc = np.random.normal(0, 0.01, xy.shape)
        pxy.set_markerfacecolor('red')
    elif frame % 1 < 0.11:
        pxy.set_markerfacecolor('blue')        
    xy += inc
    fxy = np.abs((xy+2)%4-2)
    pxy.set_data(*fxy)
    return pxy,
anim = FuncAnimation(f, update, frames=np.arange(1200) / 10,
                     init_func=init, blit=True)
pylab.show()
    
这似乎很好地得到了主要的想法。每隔十步再给粒子随机运动的想法是什么?这正是我想创造的视觉效果,只不过我想象的是粒子继续沿着它们的轨迹前进,直到它们撞上一堵墙。我可以把增量设定为固定的吗?
我不是物理学家,但我认为公认的方法实际上是在每个时间步长生成一个新的位移矢量。一种思考方式是,有如此多的粒子碰撞,位移基本上是随机的,而位移的统计是温度的函数。
谢谢。他的回答很有帮助,解决了我正在研究的整个想法,但我的整个想法是通过从头开始建立模型来学习物理学。@Mstaino的回答给了我一个简短的可用的代码片段,我可以用它开始建立其余的功能。但我也非常感谢你的回答,因为我可能会在最终产品中使用它的许多组件。
Kaiwen Chen
Kaiwen Chen
发布于 2019-03-07
0 人赞同

因此,有几件事情要牢记。

  • 你需要一个摩擦成分,否则,粒子将永远保持运动(能量守恒)。在这种情况下,摩擦是作为速度的函数发生的,而且摩擦也会在弹跳时发生。

  • 如果它只是一个单一的粒子,你可以通过定义边界框来计算,例如x在0到5之间,y在0到3之间。然后你可以通过插入x=5的值来计算与墙的截距,然后在直线的方程式中求解y。

  •