python冰雪奇缘使用教程_99 行代码的《冰雪奇缘》

本文介绍了如何利用Taichi编程语言,仅用99行代码实现一个简单的连续介质模拟器,模拟《冰雪奇缘》中的雪的交互效果。代码实现了水、果冻、雪三种不同材料的模拟,可以在GPU上高效运行。文章通过简单的代码示例展示了Taichi的强大功能和计算效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

Material Point Method(物质点法)

Moving Least Squares Material Point Method(移动最小二乘物质点法)

Differentiable MLS-MPM (ChainQueen可微物理引擎)

“硬核”的计算机图形学

Taichi编程语言

Differentiable Programming (可微编程) 与 Taichi

import taichi as ti:假装成Python的Taichi语言

总结

终于下决心一口气把四颗智齿拔了,这两天伴随着牙疼只能吃土豆泥和蒸蛋,写编译器之类的体力活是干不了了。登录知乎发现自己居然曾今开了个专栏,无奈一直沉迷于写代码,一篇文章都没写,实在有些惭愧。

最近正好看了《冰雪奇缘2》,就顺便聊聊动画电影里面连续介质,比如雪的模拟吧。实际上,由于最近图形技术的发展,只需要99行代码就可以写一个简单的连续介质模拟器,模拟三种相互作用的不同材料(水,果冻,雪),并且在你的笔记本上就能运行:

import taichi as ti

quality = 1 # Use a larger value for higher-res simulations

n_particles, n_grid = 9000 * quality ** 2, 128 * quality

dx, inv_dx = 1 / n_grid, float(n_grid)

dt = 1e-4 / quality

p_vol, p_rho = (dx * 0.5)**2, 1

p_mass = p_vol * p_rho

E, nu = 0.1e4, 0.2 # Young's modulus and Poisson's ratio

mu_0, lambda_0 = E / (2 * (1 + nu)), E * nu / ((1+nu) * (1 - 2 * nu)) # Lame parameters

x = ti.Vector(2, dt=ti.f32, shape=n_particles) # position

v = ti.Vector(2, dt=ti.f32, shape=n_particles) # velocity

C = ti.Matrix(2, 2, dt=ti.f32, shape=n_particles) # affine velocity field

F = ti.Matrix(2, 2, dt=ti.f32, shape=n_particles) # deformation gradient

material = ti.var(dt=ti.i32, shape=n_particles) # material id

Jp = ti.var(dt=ti.f32, shape=n_particles) # plastic deformation

grid_v = ti.Vector(2, dt=ti.f32, shape=(n_grid, n_grid)) # grid node momemtum/velocity

grid_m = ti.var(dt=ti.f32, shape=(n_grid, n_grid)) # grid node mass

ti.cfg.arch = ti.cuda # Try to run on GPU

@ti.kernel

def substep():

for i, j in ti.ndrange(n_grid, n_grid):

grid_v[i, j] = [0, 0]

grid_m[i, j] = 0

for p in range(n_particles): # Particle state update and scatter to grid (P2G)

base = (x[p] * inv_dx - 0.5).cast(int)

fx = x[p] * inv_dx - base.cast(float)

# Quadratic kernels [http://mpm.graphics Eqn. 123, with x=fx, fx-1,fx-2]

w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1), 0.5 * ti.sqr(fx - 0.5)]

F[p] = (ti.Matrix.identity(ti.f32, 2) + dt * C[p]) @ F[p] # deformation gradient update

h = ti.exp(10 * (1.0 - Jp[p])) # Hardening coefficient: snow gets harder when compressed

if material[p] == 1: # jelly, make it softer

h = 0.3

mu, la = mu_0 * h, lambda_0 * h

if material[p] == 0: # liquid

mu = 0.0

U, sig, V = ti.svd(F[p])

J = 1.0

for d in ti.static(range(2)):

new_sig = sig[d, d]

if material[p] == 2: # Snow

new_sig = min(max(sig[d, d], 1 - 2.5e-2), 1 + 4.5e-3) # Plasticity

Jp[p] *= sig[d, d] / new_sig

sig[d, d] = new_sig

J *= new_sig

if material[p] == 0: # Reset deformation gradient to avoid numerical instability

F[p] = ti.Matrix.identity(ti.f32, 2) * ti.sqrt(J)

elif material[p] == 2:

F[p] = U @ sig @ V.T() # Reconstruct elastic deformation gradient after plasticity

stress = 2 * mu * (F[p] - U @ V.T()) @ F[p].T() + ti.Matrix.identity(ti.f32, 2) * la * J * (J - 1)

stress = (-dt * p_vol * 4 * inv_dx * inv_dx) * stress

affine = stress + p_mass * C[p]

for i, j in ti.static(ti.ndrange(3, 3)): # Loop over 3x3 grid node neighborhood

offset = ti.Vector([i, j])

dpos = (offset.cast(float) - fx) * dx

weight = w[i][0] * w[j][1]

grid_v[base + offset] += weight * (p_mass * v[p] + affine @ dpos)

grid_m[base + offset] += weight * p_mass

for i, j in ti.ndrange(n_grid, n_grid):

if grid_m[i, j] > 0: # No need for epsilon here

grid_v[i, j] = (1 / grid_m[i, j]) * grid_v[i, j] # Momentum to velocity

grid_v[i, j][1] -= dt * 50 # gravity

if i < 3 and grid_v[i, j][0] < 0: grid_v[i, j][0] = 0 # Boundary conditions

if i > n_grid - 3 and grid_v[i, j][0] > 0: grid_v[i, j][0] = 0

if j < 3 and grid_v[i, j][1] < 0: grid_v[i, j][1] = 0

if j > n_grid - 3 and grid_v[i, j][1] > 0: grid_v[i, j][1] = 0

for p in range(n_particles): # grid to particle (G2P)

base = (x[p] * inv_dx - 0.5).cast(int)

fx = x[p] * inv_dx - base.cast(float)

w = [0.5 * ti.sqr(1.5 - fx), 0.75 - ti.sqr(fx - 1.0), 0.5 * ti.sqr(fx - 0.5)]

new_v = ti.Vector.zero(ti.f32, 2)

new_C = ti.Matrix.zero(ti.f32, 2, 2)

for i, j in ti.static(ti.ndrange(3, 3)): # loop over 3x3 grid node neighborhood

dpos = ti.Vector([i, j]).cast(float) - fx

g_v = grid_v[base + ti.Vector([i, j])]

weight = w[i][0] * w[j][1]

new_v += weight * g_v

new_C += 4 * inv_dx * weight * ti.outer_product(g_v, dpos)

v[p], C[p] = new_v, new_C

x[p] += dt * v[p] # advection

import random

group_size = n_particles // 3

for i in range(n_particles):

x[i] = [random.random() * 0.2 + 0.3 + 0.10 * (i // group_size), random.random() * 0.2 + 0.05 + 0.32 * (i // group_size)]

material[i] = i // group_size # 0: fluid 1: jelly 2: snow

v[i] = [0, 0]

F[i] = [[1, 0], [0, 1]]

Jp[i] = 1

import numpy as np

gui = ti.GUI("Taichi MLS-MPM-99", res=512, background_color=0x112F41)

for frame in range(20000):

for s in range(int(2e-3 // dt)):

substep()

colors = np.array([0x068587, 0xED553B, 0xEEEEF0], dtype=np.uint32)

gui.circles(x.to_numpy(), radius=1.5, color=colors[material.to_numpy()])

gui.show() # Change to gui.show(f'{frame:06d}.png') to write images to disk

这段代码用Python 3运行。运行前要根据操作系统和CUDA版本(如果有CUDA的话)安装taichi:

# CPU 版本 (支持Linux, OS X and Windows)

python3 -m pip install taichi-nightly

# GPU (CUDA 10.0) (只支持Linux)

python3 -m pip install taichi-nightly-cuda-10-0

# GPU (CUDA 10.1) (只支持Linux)

python3 -m pip install taichi-nightly-cuda-10-1

这99行代码虽然很短,其背后的故事却很长。虽然语法看起来是Python,其计算部分却会被一整套编译系统接管,最后输出可执行的x86_64或者PTX instructions,能够在CPU/GPU上高效运行。要只用99行代码实现一个这样一个模拟器,这其中凝聚了几代researcher的努力。我很幸运能够参与到这个接力赛中,并跑完最后一棒。

未完待续

<think>好的,我现在需要帮用户设计关于AI对话助手的细化测试用例示例。首先,用户提到他们想获取详细信息或示例,特别是细化后的测试用例设计。根据用户提供的引用内容,他们可能希望利用AI生成高质量的测试用例,尤其是处理边界条件和极端情况。 首先,我需要明确AI对话助手的主要功能模块。通常这类助手包括对话理解、意图识别、多轮对话管理、上下文理解、回复生成等。每个模块都需要针对性的测试用例。 接下来,参考用户提供的引用,特别是引用[3]和[4],其中提到利用OpenAI或类似模型生成测试用例,细化功能描述、边界条件等。所以,测试用例需要覆盖正常场景、边界条件、异常输入、性能和安全等方面。 例如,在意图识别模块,正常用例可以是用户输入明确的问题,如天气查询;边界条件可能涉及超长文本或混合多语言输入。异常输入测试可能包括特殊字符或空输入。性能方面需要考虑高并发下的响应时间,安全性则需要测试注入攻击的情况。 另外,用户引用中提到集成到测试框架如pytest,所以可能需要示例代码展示如何自动化这些用例。例如,使用Python的requests库调用AI助手的API,并断言响应是否符合预期。 同时,引用[2]提到功能测试用例生成的具体应用,需要确保用例的全面性和实际项目结合。因此,测试用例应分模块设计,每个模块下再细分不同情况,确保覆盖各种可能的用户交互场景。 最后,用户可能需要相关问题来进一步深入,比如如何评估测试覆盖率或优化生成用例的质量。因此,在回答末尾添加相关问题,帮助用户扩展思考。</think>### AI对话助手测试用例设计细化示例 #### 一、核心功能模块及测试场景 1. **对话理解能力** - **正常场景**:用户输入$"今天北京天气如何?"$,系统应返回天气信息[^4] - **边界条件**:输入长度超过$500$字符的超长文本,验证截断处理逻辑 - **混合语言**:中英文混杂输入$"帮我book一张明天去上海的ticket"$ 2. **意图识别能力** ```python # 测试代码示例(pytest框架) def test_intent_recognition(): test_cases = [ ("订周五的会议室", "schedule_meeting"), ("播放周杰伦的歌", "play_music"), ("空调调到25度", "device_control") ] for text, expected_intent in test_cases: response = ai_assistant.process(text) assert response.intent == expected_intent ``` 3. **多轮对话管理** $$对话状态机模型:S_{t+1} = f(S_t, U_t)$$ 其中$S_t$为第$t$轮对话状态,$U_t$为用户输入 #### 二、详细测试用例表示例 | 测试类型 | 输入示例 | 预期输出 | 验证指标 | |---------|---------|---------|---------| | 正常输入 | "帮我设置明天早上7的闹钟" | 确认闹钟时间和日期 | 意图识别准确率 ≥98%[^2] | | 模糊查询 | "那个...关于上周的事情" | 追问具体上下文 | 澄清请求触发率 | | 极端输入 | 连续发送$100$条空消息 | 异常流量检测并限流 | 系统崩溃率=0% | | 多模态输入 | 发送图片+文字"这张图里有什么动物?" | 返回图像识别结果 | 跨模态理解延迟 <2s | #### 三、特殊场景测试设计 1. **上下文继承测试** ``` 用户:推荐适合儿童看的电影 AI:推荐《冰雪奇缘》《疯狂动物城》 用户:第二个的导演是谁? AI:回答《疯狂动物城》导演信息 ``` 2. **知识边界测试** - 询问$2025$年诺贝尔奖获得者(未来事件) - 请求解释量子纠缠现象(专业知识) 3. **安全防护测试** ```python # 注入攻击测试 malicious_inputs = [ "DROP TABLE users;", "<script>alert('xss')</script>", "../../etc/passwd" ] for input in malicious_inputs: assert "安全风险" in ai_assistant.filter(input) ``` #### 四、性能测试指标 $$吞吐量 = \frac{N_{成功响应}}{T_{测试周期}} \geq 1000次/秒$$ $$P99延迟 \leq 500ms \quad (在CPU使用率80\%条件下)$$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值