Python粒子树代码
时间: 2023-06-18 19:06:15 浏览: 145
以下是一个基于Python的粒子树代码示例:
```python
import random
import math
class Particle:
def __init__(self, x, y, mass=1):
self.x = x
self.y = y
self.mass = mass
self.vx = 0
self.vy = 0
def apply_force(self, fx, fy):
self.vx += fx / self.mass
self.vy += fy / self.mass
def move(self, dt):
self.x += self.vx * dt
self.y += self.vy * dt
class QuadTree:
def __init__(self, x, y, w, h, capacity=4):
self.x = x
self.y = y
self.w = w
self.h = h
self.capacity = capacity
self.particles = []
self.children = None
def subdivide(self):
half_w = self.w / 2
half_h = self.h / 2
self.children = [
QuadTree(self.x, self.y, half_w, half_h),
QuadTree(self.x + half_w, self.y, half_w, half_h),
QuadTree(self.x, self.y + half_h, half_w, half_h),
QuadTree(self.x + half_w, self.y + half_h, half_w, half_h)
]
def insert(self, particle):
if self.children is not None:
quad = self._find_quadrant(particle)
self.children[quad].insert(particle)
return
self.particles.append(particle)
if len(self.particles) > self.capacity:
self.subdivide()
for p in self.particles:
quad = self._find_quadrant(p)
self.children[quad].insert(p)
self.particles = None
def _find_quadrant(self, particle):
x = particle.x
y = particle.y
half_w = self.w / 2
half_h = self.h / 2
if x < self.x + half_w:
if y < self.y + half_h:
return 0
else:
return 2
else:
if y < self.y + half_h:
return 1
else:
return 3
def query(self, x, y, radius):
result = []
self._query(x, y, radius, result)
return result
def _query(self, x, y, radius, result):
if self.particles is not None:
for p in self.particles:
dx = p.x - x
dy = p.y - y
dist = math.sqrt(dx*dx + dy*dy)
if dist < radius:
result.append(p)
elif self.children is not None:
for child in self.children:
if child._intersects_circle(x, y, radius):
child._query(x, y, radius, result)
def _intersects_circle(self, x, y, radius):
dx = abs(x - (self.x + self.w / 2))
dy = abs(y - (self.y + self.h / 2))
r = radius + math.sqrt(self.w**2 + self.h**2) / 2
return dx <= r and dy <= r
def draw(self, canvas):
if self.children is not None:
for child in self.children:
child.draw(canvas)
else:
for p in self.particles:
canvas.create_oval(p.x - 2, p.y - 2, p.x + 2, p.y + 2, fill='black')
def simulate():
particles = []
qt = QuadTree(0, 0, 500, 500)
for i in range(1000):
x = random.uniform(0, 500)
y = random.uniform(0, 500)
mass = random.uniform(0.1, 1)
particle = Particle(x, y, mass)
particles.append(particle)
qt.insert(particle)
for p in particles:
fx = fy = 0
neighbors = qt.query(p.x, p.y, 20)
for n in neighbors:
if n is not p:
dx = n.x - p.x
dy = n.y - p.y
dist = math.sqrt(dx*dx + dy*dy)
force = (p.mass * n.mass) / (dist * dist)
fx += force * dx / dist
fy += force * dy / dist
p.apply_force(fx, fy)
p.move(0.1)
canvas.delete('all')
qt.draw(canvas)
canvas.after(10, simulate)
if __name__ == '__main__':
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
simulate()
root.mainloop()
```
这个示例代码实现了一个简单的粒子模拟,包括一个 `Particle` 类表示粒子,一个 `QuadTree` 类表示四叉树,以及一个 `simulate` 函数用于模拟粒子的运动。在 `simulate` 函数中,首先创建了一些随机位置和质量的粒子,并将它们插入到四叉树中。然后对于每个粒子,查询四叉树中距离它一定范围内的其他粒子,计算受到的力,更新速度和位置。最后在画布上绘制所有粒子的位置。该代码示例使用了 tkinter 库来绘制图形界面。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)