日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python 粒子动画_python-盒子中有很多粒子-物理模拟

發布時間:2024/7/23 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 粒子动画_python-盒子中有很多粒子-物理模拟 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我目前正在嘗試模擬盒子周圍彈跳的許多粒子.

我考慮了@kalhartt的建議,這是改進的代碼,用于初始化框內的粒子:

import numpy as np

import scipy.spatial.distance as d

import matplotlib.pyplot as plt

# 2D container parameters

# Actual container is 50x50 but chose 49x49 to account for particle radius.

limit_x = 20

limit_y = 20

#Number and radius of particles

number_of_particles = 350

radius = 1

def force_init(n):

# equivalent to np.array(list(range(number_of_particles)))

count = np.linspace(0, number_of_particles-1, number_of_particles)

x = (count + 2) % (limit_x-1) + radius

y = (count + 2) / (limit_x-1) + radius

return np.column_stack((x, y))

position = force_init(number_of_particles)

velocity = np.random.randn(number_of_particles, 2)

初始化的位置如下所示:

初始化粒子后,我想在每個時間步更新它們.用于更新的代碼立即遵循先前的代碼,如下所示:

# Updating

while np.amax(abs(velocity)) > 0.01:

# Assume that velocity slowly dying out

position += velocity

velocity *= 0.995

#Get pair-wise distance matrix

pair_dist = d.cdist(position, position)

pair_d = pair_dist<=4

#If pdist [i,j] is <=4 then the particles are too close and so treat as collision

for i in range(len(pair_d)):

for j in range(i):

# Only looking at upper triangular matrix (not inc. diagonal)

if pair_d[i,j] ==True:

# If two particles are too close then swap velocities

# It's a bad hack but it'll work for now.

vel_1 = velocity[j][:]

velocity[j] = velocity[i][:]*0.9

velocity[i] = vel_1*0.9

# Masks for particles beyond the boundary

xmax = position[:, 0] > limit_x

xmin = position[:, 0] < 0

ymax = position[:, 1] > limit_y

ymin = position[:, 1] < 0

# flip velocity and assume that it looses 10% of energy

velocity[xmax | xmin, 0] *= -0.9

velocity[ymax | ymin, 1] *= -0.9

# Force maximum positions of being +/- 2*radius from edge

position[xmax, 0] = limit_x-2*radius

position[xmin, 0] = 2*radius

position[ymax, 0] = limit_y-2*radius

position[ymin, 0] = 2*radius

更新它并使其運行完成后,我得到以下結果:

這比以前要好得多,但是仍然有一些補丁之間的距離太近-例如:

太近了.我認為更新是有效的…感謝@kalhartt,我的代碼更好,更快了(而且我學到了有關numpy … props @kalhartt的一些知識),但我仍然不知道它在哪里搞砸了.我嘗試更改實際更新的順序,其中成對距離最后一次或position = velocity最后一次但無濟于事.我添加了* 0.9以使整個過程更快消失,并嘗試使用4來確保2 *半徑(= 2)不太嚴格…但是似乎沒有任何效果.

任何和所有幫助將不勝感激.

解決方法:

僅有兩種錯字妨礙您前進.首先是范圍(len(position)/ 2)中的i:僅迭代一半以上的粒子.這就是為什么一半的粒子保留在x邊界中的原因(如果您觀察較大的迭代,則更清晰).第二,第二個y條件應為最小(我假設)position [i] [1]< 0.下面的塊為我綁定了粒子(我沒有使用碰撞代碼進行測試,因此可能存在問題).

for i in range(len(position)):

if position[i][0] > limit_x or position[i][0] < 0:

velocity[i][0] = -velocity[i][0]

if position[i][1] > limit_y or position[i][1] < 0:

velocity[i][1] = -velocity[i][1]

順便說一句,嘗試盡可能利用numpy消除循環.它更快,更高效,并且在我看來更具可讀性.例如,force_init看起來像這樣:

def force_init(n):

# equivalent to np.array(list(range(number_of_particles)))

count = np.linspace(0, number_of_particles-1, number_of_particles)

x = (count * 2) % limit_x + radius

y = (count * 2) / limit_x + radius

return np.column_stack((x, y))

您的邊界條件將如下所示:

while np.amax(abs(velocity)) > 0.01:

position += velocity

velocity *= 0.995

# Masks for particles beyond the boundary

xmax = position[:, 0] > limit_x

xmin = position[:, 0] < 0

ymax = position[:, 1] > limit_y

ymin = position[:, 1] < 0

# flip velocity

velocity[xmax | xmin, 0] *= -1

velocity[ymax | ymin, 1] *= -1

最后說明,用position [xmax,0] = limit_x之類的東西將位置硬剪切到邊界框可能是一個好主意. position [xmin,0] =0.在某些情況下,速度較小,框外的粒子將被反射,但在下一次迭代中不會進入框內.因此它將永遠位于被永久反射的盒子外面.

編輯:碰撞

碰撞檢測是一個困難得多的問題,但讓我們看看我們能做什么.讓我們看一下您當前的實現.

pair_dist = d.cdist(position, position)

pair_d = pair_dist<=4

for i in range(len(pair_d)):

for j in range(i):

# Only looking at upper triangular matrix (not inc. diagonal)

if pair_d[i,j] ==True:

# If two particles are too close then swap velocities

# It's a bad hack but it'll work for now.

vel_1 = velocity[j][:]

velocity[j] = velocity[i][:]*0.9

velocity[i] = vel_1*0.9

總體而言,這是一個非常好的方法,cdist將有效地計算距離

在點集之間,您會發現哪些點與pair_d = pair_dist< = 4發生碰撞.

嵌套的for循環是第一個問題.我們需要遍歷pair_d的True值,其中j>一世.首先,您的代碼實際上通過在range(i)中使用j來遍歷較低的三角形區域. i,在這種情況下并不特別重要,因為不會重復i,j對.但是Numpy有兩個內置函數可以替代,np.triu可以將對角線以下的所有值都設置為0,而np.nonzero可以為矩陣提供非零元素的索引.所以這:

pair_dist = d.cdist(position, position)

pair_d = pair_dist<=4

for i in range(len(pair_d)):

for j in range(i+1, len(pair_d)):

if pair_d[i, j]:

...

相當于

pair_dist = d.cdist(position, position)

pair_d = np.triu(pair_dist<=4, k=1) # k=1 to exclude the diagonal

for i, j in zip(*np.nonzero(pair_d)):

...

第二個問題(如您所述)是速度只是被切換和縮放而不是被反映.我們真正想要做的是沿連接它們的軸求和否定每個粒子速度的分量.請注意,要做到這一點,我們將需要將它們連接到位置[j]-position [i]的向量和連接它們的向量的長度(我們已經計算出).因此,不幸的是,部分cdist計算被重復了.讓我們退出使用cdist并自己做.這里的目標是制作兩個數組diff和norm,其中diff [i] [j]是從粒子i指向j的向量(因此diff是3D數組),而norm [i] [j]是粒子i之間的距離和j.我們可以這樣用numpy做到這一點:

nop = number_of_particles

# Give pos a 3rd index so we can use np.repeat below

# equivalent to `pos3d = np.array([ position ])

pos3d = position.reshape(1, nop, 2)

# 3D arras with a repeated index so we can form combinations

# diff_i[i][j] = position[i] (for all j)

# diff_j[i][j] = position[j] (for all i)

diff_i = np.repeat(pos3d, nop, axis=1).reshape(nop, nop, 2)

diff_j = np.repeat(pos3d, nop, axis=0)

# diff[i][j] = vector pointing from position[i] to position[j]

diff = diff_j - diff_i

# norm[i][j] = sqrt( diff[i][j]**2 )

norm = np.linalg.norm(diff, axis=2)

# check for collisions and take the region above the diagonal

collided = np.triu(norm < radius, k=1)

for i, j in zip(*np.nonzero(collided)):

# unit vector from i to j

unit = diff[i][j] / norm[i][j]

# flip velocity

velocity[i] -= 1.9 * np.dot(unit, velocity[i]) * unit

velocity[j] -= 1.9 * np.dot(unit, velocity[j]) * unit

# push particle j to be radius units from i

# This isn't particularly effective when 3+ points are close together

position[j] += (radius - norm[i][j]) * unit

...

由于這篇文章已經足夠長了,我對代碼的修改here is a gist.

標簽:scipy,python-2-7,physics,python,numpy

總結

以上是生活随笔為你收集整理的python 粒子动画_python-盒子中有很多粒子-物理模拟的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 黄瓜视频在线免费观看 | 波多野吉衣视频在线观看 | 欧美日韩国产一区二区在线观看 | 麻豆一区二区99久久久久 | 伊人影视在线 | 美女福利在线视频 | 天天狠天天干 | 亚洲综合一区在线观看 | 中文字幕在线观看av | 亚洲性欧美色 | 伊人久久激情 | 一级做a免费 | 欧美精品综合 | 99在线视频精品 | av免费观看大全 | 俺也来俺也去俺也射 | 久久一 | 美国特色黄a大片 | 午夜aa| 亚洲国产精品二区 | 成人h片 | 日本欧美久久久久免费播放网 | 美女高潮流白浆视频 | 中文字幕日韩三级片 | 亚洲欧美高清视频 | 亚洲综合中文字幕在线 | 九九亚洲视频 | 国内自拍偷拍 | 中日韩精品一区二区三区 | 看久久| 青青草成人免费视频 | 久久亚洲AV成人无码一二三 | 欧美亚洲中文精品字幕 | 中文字幕影院 | 在线一区av | 人妻精品一区二区在线 | 最近日韩中文字幕 | 不卡成人 | 亚洲国产精品美女 | 五月天爱爱 | 91精品国产乱码久久久久久久久 | 都市激情自拍偷拍 | av看片| 免费观看毛片网站 | 亚洲熟女乱综合一区二区 | 国产精选91 | 日韩国产高清在线 | 在线精品观看 | 欧美99久久精品乱码影视 | 国产日韩一区二区 | 欧美成人一二三 | 国产一区二区在线观看视频 | 国产精品伦一区二区三级视频 | 大胸美女被爆操 | 国产精品久久久久久中文字 | 国产在线拍揄自揄拍 | jlzzjlzz国产精品久久 | 日本成人在线一区 | 久久久夜色精品亚洲 | 中文字幕无码乱码人妻日韩精品 | 一区二区欧美精品 | 黄色一级视频 | 亚洲老妇色熟女老太 | 日韩久久影视 | 天堂一级片| 欧美激情图片 | 人人揉人人 | 精品伦理一区二区 | 黄色三级网络 | 色悠悠国产 | 91精品国产91久久久久久吃药 | 深爱激情av | 日韩精品欧美激情 | 俺也去婷婷 | 激情超碰在线 | 久久不射视频 | 欧美一级做a爰片久久高潮 久热国产精品视频 | √8天堂资源地址中文在线 欧美精品在线一区二区 | 亚洲午夜网 | av第一福利大全导航 | 欧美在线一级 | 毛片在线免费播放 | 国产a免费观看 | 五月天一区二区三区 | 手机在线看黄色 | 亚洲精品白浆 | 亚洲a视频 | 日韩福利网 | 中文久久久久 | 国产网站精品 | 美女主播福利视频 | 国产毛片网 | 免费福利在线观看 | 伊人伊人伊人伊人 | 国产不卡视频 | 日本高清黄色 | 日韩欧美二区 | 97超碰免费在线 | 日韩av网站大全 |