鼠标位置不会在kernel中更新

一个很新手的问题,我在尝试往N-body程序中添加鼠标位置黑洞,kernel外的鼠标位置是会实时更新的,但kernel中的鼠标位置一直是(0.0, 0.0),想知道是哪里出错了,求指点,感谢

import taichi as ti

ti.init(ti.gpu)

# global control
paused = ti.field(ti.i32, ())

# gravitational constant 6.67408e-11, using 1 for simplicity
G = 1
PI = 3.141592653

# number of planets
N = 2000
# unit mass
m = 5
#black hole mass
M = 100000
# galaxy size
galaxy_size = 0.4
# planet radius (for rendering)
planet_radius = 3
# init vel
init_vel = 120

# time-step size
h = 1e-5
# substepping
substepping = 10

# pos, vel and force of the planets
# Nx2 vectors
pos = ti.Vector.field(2, ti.f32, N)
vel = ti.Vector.field(2, ti.f32, N)
force = ti.Vector.field(2, ti.f32, N)
cursor_pos = ti.Vector.field(2, ti.f32, shape=())
black_hole_pos = ti.Vector.field(2, ti.f32, shape=())

@ti.kernel
def initialize():
    center=ti.Vector([0.5, 0.5])
    for i in range(N):
        theta = ti.random() * 2 * PI
        r = (ti.sqrt(ti.random()) * 0.7 + 0.3) * galaxy_size
        offset = r * ti.Vector([ti.cos(theta), ti.sin(theta)])
        pos[i] = center+offset
        vel[i] = [-offset.y, offset.x]
        vel[i] *= init_vel

@ti.kernel
def compute_force():
    # clear force
    for i in range(N):
        force[i] = ti.Vector([0.0, 0.0])

    # compute gravitational force
    for i in range(N):
        p = pos[i]
        
        for j in range(N):# double the computation for a better memory footprint and load balance
             if i != j:
                 diff = p-pos[j]
                 r = diff.norm(1e-5)

                 # gravitational force -(GMm / r^2) * (diff/r) for i
                 f = -G * m * m * (1.0/r)**3 * diff

                 # assign to each particle
                 force[i] += f

    # mouse/black hole force
    for i in range(N):
        black_hole_pos = cursor_pos
        bdiff = black_hole_pos - pos[i]
        R = bdiff.norm(1e-5)
        F = -G * m * M * (1.0 / R) ** 3 * bdiff

        force[i] -= F

@ti.kernel
def update():
    dt = h/substepping
    for i in range(N):
        #symplectic euler
        vel[i] += dt*force[i]/m
        pos[i] += dt*vel[i]

gui = ti.GUI('N-body problem', (512, 512))

initialize()
while gui.running:

    for i in range(substepping):
        gui.get_event()
        cursor_pos = gui.get_cursor_pos()
        print(black_hole_pos)
        print(cursor_pos)
        compute_force()
        update()

    gui.clear(0xffffff)
    gui.circles(pos.to_numpy(), color=0x112F41, radius=planet_radius)
    gui.show()
import taichi as ti

ti.init(ti.gpu)

# global control
paused = ti.field(ti.i32, ())

# gravitational constant 6.67408e-11, using 1 for simplicity
G = 1
PI = 3.141592653

# number of planets
N = 2000
# unit mass
m = 5
# black hole mass
M = 100000
# galaxy size
galaxy_size = 0.4
# planet radius (for rendering)
planet_radius = 3
# init vel
init_vel = 120

# time-step size
h = 1e-5
# substepping
substepping = 10

# pos, vel and force of the planets
# Nx2 vectors
pos = ti.Vector.field(2, ti.f32, N)
vel = ti.Vector.field(2, ti.f32, N)
force = ti.Vector.field(2, ti.f32, N)
cursor_pos = ti.Vector.field(2, ti.f32, shape=())
black_hole_pos = ti.Vector.field(2, ti.f32, shape=())


@ti.kernel
def initialize():
    center = ti.Vector([0.5, 0.5])
    for i in range(N):
        theta = ti.random() * 2 * PI
        r = (ti.sqrt(ti.random()) * 0.7 + 0.3) * galaxy_size
        offset = r * ti.Vector([ti.cos(theta), ti.sin(theta)])
        pos[i] = center + offset
        vel[i] = [-offset.y, offset.x]
        vel[i] *= init_vel


@ti.kernel
def compute_force():
    # clear force
    for i in range(N):
        force[i] = ti.Vector([0.0, 0.0])

    # compute gravitational force
    for i in range(N):
        p = pos[i]

        for j in range(N):  # double the computation for a better memory footprint and load balance
            if i != j:
                diff = p - pos[j]
                r = diff.norm(1e-5)

                # gravitational force -(GMm / r^2) * (diff/r) for i
                f = -G * m * m * (1.0 / r) ** 3 * diff

                # assign to each particle
                force[i] = f

    black_hole_pos[None] = cursor_pos[None]
    # mouse/black hole force
    for i in range(N):
        bdiff = black_hole_pos[None] - pos[i]
        R = bdiff.norm(1e-5)
        F = -G * m * M * (1.0 / R) ** 3 * bdiff

        force[i] -= F


@ti.kernel
def update():
    dt = h / substepping
    for i in range(N):
        # symplectic euler
        vel[i] += dt * force[i] / m
        pos[i] += dt * vel[i]


gui = ti.GUI('N-body problem', (512, 512))

initialize()
while gui.running:

    for i in range(substepping):
        gui.get_event()
        cursor_pos[None] = gui.get_cursor_pos()
        print(black_hole_pos)
        print(cursor_pos)
        compute_force()
        update()

    gui.clear(0xffffff)
    gui.circles(pos.to_numpy(), color=0x112F41, radius=planet_radius)
    gui.show()

Hi,

出错在把一个Vector.field直接 assign 给了一个listTaichi里access或者assign一个() shapefield需要用[None]

e.g.
black_hole_pos[None] = foo

1 个赞

感谢,我把鼠标位置拆成了x和y坐标放到kernel中重新组合解决了