Position Based Dynamic 小练习

PBD

Github: https://github.com/JerryYan97/Taichi_PBD_Pratice.git

PS: 请问有没有同学用Taichi 实现过Projective Dynamics呀 :slight_smile:

3 个赞

I got a small program that connects springs to form something like it:

import taichi as ti
ti.init()

N = 8
x = ti.Vector.field(2, float, N, needs_grad=True)  # position
v = ti.Vector.field(2, float, N)  # velocity
U = ti.field(float, (), needs_grad=True)  # square error
c = ti.Vector.field(2, float, 1)


@ti.kernel
def compute_U():
    for i in ti.ndrange(N-1):
        r = x[i] - x[i+1]
        U[None] += k * abs(r.norm() - dx)


@ti.kernel
def advance():
    for i in x:
        v[i] += dt * (-x.grad[i] - friction * v[i] - g)  # dv/dt = -dU/dx, with added friction
    for i in x:
        x[i] += dt * v[i]  # dx/dt = v
    x[0] = x0_pos


def substep():
    with ti.Tape(U):
        # every kernel invocation within this indent scope
        # will also be accounted into the partial derivative of U
        # with corresponding input variables like x.
        compute_U()  # will also computes dU/dx and save in x.grad
    advance()


@ti.kernel
def init():
    for i in range(N):
        x[i] = x0_pos + i * c[0]


# hooke's constant
k = 0.19
dx = 0.1
dx_sq = dx*dx

# gravity acceleration, vertical
g = [0., 0.01]

friction = [0.015, 0.08]
c[0] = [0.1, -0.008]
x0_pos = [0.4, 0.9]
dt = 1e-3

it = 0
debug = 2

init()

gui = ti.GUI('Hanging-Springs')
while gui.running:
    for i in range(50):
        substep()
    if debug == 1:
        print('U = ', U[None])
    elif debug == 2:
        max_dx_sq = 0.
        q_norm = 0.
        q = [0., 0.]
        p = x.to_numpy()
        for i in range(N-1):
            q = p[i] - p[i+1]
            q_norm = q[0]**2 + q[1]**2
            if q_norm > max_dx_sq:
                max_dx_sq = q_norm
        print("max diff = ", max_dx_sq - dx_sq)
    it += 1
    gui.circles(x.to_numpy(), radius=3)
    gui.show()

One question I have is how to make it less “spring” and more like a rope?
I tried changing the hooke’s constant k to make it more stiff but than it vibrates more.

If you want to make it more like rod. You should add bending, twisting constraints. For more info, you can see here