Homework0 Boids类鸟生物群体模拟

非常简单的Boids算法

(不知为何图非常小,我就上传到图床上了)

    import taichi as ti
    import numpy as np
    import math
    ti.init(arch = ti.gpu)
    dt = 1
    vis_radias = 40.0
    max_speed = 4.0
    boids_size = 2000
    boids_color = 255
    boids_radias = 1
    resx = 800
    resy = 600

    boids_pos = ti.Vector(2, dt=ti.f32, shape=boids_size)
    boids_velocity = ti.Vector(2, dt=ti.f32, shape=boids_size)
    img = ti.Vector(3,ti.i32, shape=(resx, resy))

    @ti.kernel
    def init():
        for x in range(0,boids_size):
            boids_pos[x] = ti.Vector([ti.random(ti.f32)*resx, ti.random(ti.f32)*resy])
            boids_velocity[x] = ti.Vector([max_speed*(ti.random(ti.f32)-0.5), max_speed*(ti.random(ti.f32)-0.5)])

    @ti.kernel
    def render():
        for i,j in ti.ndrange((0,resx),(0,resy)):
            img[i, j] = ti.Vector([255 - boids_color,255 - boids_color,255 - boids_color])
        for i in range(boids_size):
            for x in range(ti.cast(boids_pos[i][0],ti.i32) - boids_radias, ti.cast(boids_pos[i][0],ti.i32) + boids_radias):
                for y in range(ti.cast(boids_pos[i][1],ti.i32) - boids_radias,ti.cast(boids_pos[i][1],ti.i32) + boids_radias):
                    img[x, y] = ti.Vector([boids_velocity[i][1]*255,boids_velocity[i].norm()*255,boids_velocity[i][0]*255])
    @ti.kernel
    def update_pos():
        for x in range(boids_size):
            boids_pos[x] = boids_pos[x] + dt * boids_velocity[x];
            if (boids_pos[x][0] > resx): boids_pos[x][0] = 1
            elif (boids_pos[x][1] > resy): boids_pos[x][1] = 1
            elif (boids_pos[x][0] < 0): boids_pos[x][0] = resx-1
            elif (boids_pos[x][1] < 0): boids_pos[x][1] = resy-1

    @ti.kernel
    def update_by_rules():
        for i in range(boids_size):
            avoid = ti.Vector([0,0])
            cnt=0
            avoid = ti.Vector([0.,0.])
            follow = ti.Vector([0.,0.])
            middle = ti.Vector([0.,0.])
            for j in range(boids_size):
                if i!=j:
                    dis = boids_pos[i] - boids_pos[j]
                    if dis.norm() < vis_radias:
                        cnt += 1
                        boids_velocity[i] += dis.normalized()/dis.norm()*max_speed
                        follow += boids_velocity[j]
                        middle = middle + boids_pos[j]
            if cnt != 0:
                middle = middle/cnt - boids_pos[i]            
                boids_velocity[i] += (middle + (follow/cnt)).normalized()
                if boids_velocity[i].norm() > max_speed:
                    boids_velocity[i] = boids_velocity[i].normalized() *max_speed
    init()
    gui = ti.GUI('Boids', (resx, resy))
    while True:
        update_by_rules()
        update_pos()
        render()
        gui.set_image(img.to_numpy().astype(np.uint8))
        gui.show()
8 Likes

Great job! Orz.

Great job! Orz.

Wow,it is similar as ‘Vicsek model’ in physics.

Great example!

Does anyone know how to update this code to run with the latest Taichi?

TypeError: Matrix.__init__() got an unexpected keyword argument 'shape'

Got it:

boids_pos = ti.Vector.field(2, dtype=ti.f32, shape=(boids_size))
boids_velocity = ti.Vector.field(2, dtype=ti.f32, shape=(boids_size))
img = ti.Vector.field(3, dtype=ti.i32, shape=(resx, resy))