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()
9 Likes

Great job! Orz.

Great job! Orz.

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