Skip to content

Instantly share code, notes, and snippets.

@karminski
Created September 5, 2025 05:08
Show Gist options
  • Save karminski/d71b4c83b761538002593dec0014a21a to your computer and use it in GitHub Desktop.
Save karminski/d71b4c83b761538002593dec0014a21a to your computer and use it in GitHub Desktop.

(CC-BY-NC-SA 4.0 by karminski-牙医)

杯子倒水测试

(CC-BY-NC-SA 4.0 by karminski-牙医)

请使用Python和pygame库,创建一个二维流体模拟程序。该程序需要模拟液体(由大量粒子代表)在重力作用下从一个正在倾斜的杯子中倒出的过程。

核心要求:

创建Pygame环境:

初始化一个pygame窗口,尺寸建议为 1920x1080像素。 设置一个主循环来处理事件、更新物理状态和渲染画面。 背景色设置为白色。

定义杯子容器:

杯子是二维的,由几条线段构成一个容器形状。杯口为空,向上放置。你可以用一个顶点列表来定义其形状,例如 [(x1, y1), (x2, y2), ...]。 初始状态下,杯子应竖直立在屏幕中间。 杯子的线条应能被渲染出来,颜色为黑色。

创建粒子系统:

液体由大量的粒子(例如400个)来表示。 每个粒子都是一个小圆圈,拥有以下属性:

  • 位置 (x, y)
  • 速度 (vx, vy)
  • 直径 (e.g., 4 像素)
  • 颜色 (e.g., 蓝色)

建议创建一个Particle类来管理这些属性。 初始时,所有粒子在杯子上方的位置逐步生成,让粒子全部流入杯子内部。

实现物理模拟:

重力:

在每个时间步(frame),对所有粒子施加一个恒定的向下的加速度(例如 g = 0.1)。

与容器的碰撞:

实现粒子与构成杯子的线段之间的碰撞检测。 需要防止粒子从线段之间的连接点漏出去。 当粒子撞击墙壁时,其速度应该被反弹。为了模拟能量损失,反弹后的速度应该乘以一个小于1的恢复系数(e.g., 0.7)。

粒子间的相互作用 (简化流体行为):

这是模拟的关键。为了防止粒子不自然地聚集或重叠,实现一个简单的排斥力。 当两个粒子的距离小于它们半径之和的某个阈值时,给它们施加一个微小的、沿两者中心连线方向向外的力。这可以简单地通过直接调整它们的位置或速度来实现,将它们轻微推开。

运动更新:

使用欧拉积分法(Euler integration)来更新每个粒子的位置: velocity += acceleration * dt position += velocity * dt (为了简化,你可以假设 dt=1,并将加速度直接加到速度上)。

屏幕底部:

粒子落到屏幕底部而不是掉出去.

实现动画效果:

生成粒子:先在杯子上方生成粒子,全部流入杯中。 杯子倾倒: 然后,杯子需要随时间缓慢旋转。 让杯子围绕其中心的一个点进行旋转。 旋转角度可以从0度缓慢增加到约135度,模拟倒水的过程。

代码结构:

  • 请使用面向对象的方法,例如创建Particle类和Flask类。
  • 在代码的关键部分添加注释,特别是物理计算(重力、碰撞、粒子间作用力)和坐标变换(杯子旋转)的部分。
  • 注意需要先绘制杯子然后再绘制粒子,以免粒子直接掉下去。
  • 代码中请全部使用英文。所有代码放在同一个 py 文件里

鞭炮连锁爆炸测试

(CC-BY-NC-SA 4.0 by karminski-牙医)

请使用 three.js 实现一个逼真的"鞭炮箱子"3D爆炸连锁反应演示。所有代码(包括HTML, CSS, JavaScript)都必须封装在一个独立的HTML文件中。

场景设置:

  1. 平面: 创建一个尺寸为1000×1000的灰色、光滑的水平平面,能接收阴影。地面材质使用{color: 0x808080, roughness: 0.8, metalness: 0.1}

  2. 鞭炮建模:

    • 主体: 红色圆柱体,高度1,直径0.2,材质使用{color: 0xff0000, roughness: 0.6, metalness: 0.2}
    • 封土: 圆柱体顶部和底部各有一个土黄色的小圆柱,高度0.05,材质{color: 0xdaa520, roughness: 0.8}
    • 引线: 从顶部封土中心伸出的蓝绿色细圆柱,长度0.5,直径0.05,材质{color: 0x20b2aa, roughness: 0.4}
    • 碰撞体积: 鞭炮之间有碰撞体积, 防止模型互相重叠
    • 燃烧状态: 引线顶端需要能显示小的橙红色发光球体模拟火星
  3. 透明箱子:

    • 尺寸:10×10×8的透明玻璃箱子, 顶部没有碰撞体积, 其他面则有碰撞体积,材质{color: 0xffffff, transparent: true, opacity: 0.15, roughness: 0.1, metalness: 0.0}
    • 箱子内部: 动画开始时随机从箱子顶部5的聚集开始按照每组10个生成鞭炮, 生成总计10组, 鞭炮自由落体到箱子内部
    • 箱子位置: 放置在平面中心偏后的位置

爆炸与连锁反应模拟:

  1. 触发机制:

    • 页面底部提供"开始燃放"按钮触发动画
    • 一个已燃烧的鞭炮从屏幕上方以抛物线轨迹落入箱子中
  2. 引线燃烧效果:

    • 燃烧动画: 引线在2秒内从顶端向下逐渐缩短,燃烧部分显示橙红色发光效果
  3. 爆炸效果:

    • 瞬间替换: 鞭炮爆炸瞬间消失,替换为大量彩色纸屑碎片
    • 纸屑系统: 生成50-80个小的彩色方形/矩形碎片,颜色为红色
    • 爆炸冲击波: 产生球形扩散的透明冲击波效果,影响周围鞭炮
    • 碎片物理: 纸屑具有初始向外的速度,受重力影响,有随机旋转动画
  4. 冲击力与弹射:

    • 影响范围: 爆炸中心半径2-3单位内的鞭炮受到冲击
    • 弹射动画: 被冲击的鞭炮以随机方向和力度弹开1-5单位距离
    • 旋转效果: 弹射的鞭炮具有随机的翻滚旋转动画
    • 碰撞检测: 弹射的鞭炮与箱壁、地面产生反弹效果
  5. 火光传播与连锁反应:

    • 火光范围: 每次爆炸产生半径3单位的火光球形区域,持续0.5-1秒
    • 引燃机制: 火光范围内未爆炸鞭炮的引线自动点燃,开始1秒燃烧倒计时
    • 传播延迟: 不同鞭炮的引燃有0.1-0.3秒的随机延迟,避免同时爆炸
    • 连锁扩散: 形成真实的多米诺骨牌式连锁反应
  6. 环境交互效果:

    • 地面冲击: 落地的鞭炮和碎片在地面产生小的冲击反弹
    • 碎片堆积: 纸屑碎片最终散落在地面和箱子周围,形成堆积效果

高级视觉效果:

  1. 粒子系统增强:

    • 火花粒子: 燃烧引线和爆炸时产生明亮的火花,有拖尾效果
    • 烟雾效果: 爆炸后产生灰白色烟雾粒子,缓慢上升并逐渐消散
    • 光晕效果: 爆炸瞬间产生明亮的光晕,照亮周围区域
  2. 动态光照:

    • 爆炸闪光: 每次爆炸时创建瞬间的点光源,模拟爆炸闪光
    • 引线火光: 燃烧的引线产生小的动态点光源
    • 颜色温度: 光源颜色从橙红色到亮白色变化

光照与渲染设置:

  1. 光源配置:

    • 主光源: 45度角的定向光DirectionalLight,强度1.2,能投射阴影
    • 环境光: 强度0.4的环境光,确保场景无纯黑区域
    • 动态光源: 爆炸和燃烧产生的临时点光源
  2. 阴影系统:

    • 启用渲染器阴影贴图renderer.shadowMap.enabled = true
    • 所有鞭炮、箱子能投射阴影castShadow = true
    • 地面接收阴影receiveShadow = true
    • 动态阴影更新以体现运动物体
  3. 后期效果:

    • 爆炸时启用临时的屏幕闪白效果
    • 可选择性添加轻微的镜头震动效果

摄像机与控制:

  • 摄像机从斜45度角俯视整个场景,距离箱子约15单位
  • 可鼠标控制
  • 确保能完整观察到连锁反应的全过程和碎片散落效果

代码结构要求:

  • 创建独立的Firecracker类管理单个鞭炮状态
  • 创建ExplosionSystem类管理爆炸效果和粒子
  • 创建ChainReactionManager类控制连锁反应逻辑
  • 所有物理计算使用简化但真实的运动方程
  • 代码中添加详细注释,特别是爆炸传播和物理模拟部分
  • 性能优化:合理控制粒子数量

交互控制:

  • 提供"重置场景"按钮重新开始演示
  • 可选择添加"单个引爆"模式,点击特定鞭炮进行局部引爆测试
  • 显示当前未爆炸鞭炮数量和已发生爆炸次数的统计信息

大象牙膏测试

(CC-BY-NC-SA 4.0 by karminski-牙医)

请使用 three.js 实现一个逼真的"大象牙膏"化学实验3D演示。所有代码(包括HTML, CSS, JavaScript)都必须封装在一个独立的HTML文件中。

场景设置:

  1. 平面: 创建一个尺寸为1000*1000的灰色、光滑的水平平面它能接收阴影。
  2. 三角烧瓶:
    • 形状: 在平面中心放置一个透明的玻璃三角烧瓶。烧瓶应具有清晰的轮廓:圆柱形的颈部、逐渐变宽的圆锥形瓶身和扁平的底部。请勿使用简单的圆锥体代替。
    • 材质: 烧瓶材质应为高度透明的玻璃,具有适当的高透射率,较低的粗糙度,以及正确的折射率来模拟玻璃。设置 { color: 0xffffff, transparent: true, opacity: 0.9, roughness: 0.95, metalness: 0.35, clearcoat: 1.0, clearcoatRoughness: 0.03, transmission: 0.95, ior: 1.5, side: THREE.DoubleSid}应能看到背景和透过液体的光线折射效果。
    • 液体: 烧瓶内预先装有约三分之一高度的荧光粉色液体。液体表面应平整,并与烧瓶内壁贴合。注意参考三角烧瓶建模的形状,理想的做法是复制三角烧瓶的部分锥形的形状,不要让液体建模溢出三角烧瓶。
    • 注意: 三角烧瓶的建模整个模型的方向朝向向上。

"大象牙膏"喷发效果模拟:

  1. 触发: 页面在footer的位置提供一个按钮点击后开始喷发。
  2. 泡沫形态与质感:
    • 喷射出的泡沫应由大量微小、半透明、能够相互融合的粒子组成,模拟真实泡沫的稠密和蓬松质感,避免看起来像孤立的小球。颜色为荧光粉色,可以带有一些亮度变化以增加层次感。
    • 考虑使用一个简单的噪点纹理或程序化方式为泡沫粒子增加一些表面细节,使其看起来更像多孔的泡沫而非光滑球体。
  3. 喷射动态与流体模拟:
    • 初期喷发: 泡沫从烧瓶口猛烈向上喷出,形成一个持续上升的圆柱(紧密的泡沫堆积在一起形成柱状)。高度至少要有三角烧瓶的3倍高度,泡沫住直到快达到最大高度的时候才开始分散,初始喷射速度和压力较大。
    • 压力衰减: 喷射的强度(速度和产生泡沫的速率)应随时间逐渐减弱,导致泡沫柱的高度和喷射距离逐渐减小,模拟化学反应物耗尽的过程。
    • 粒子运动: 粒子运动轨迹应模拟基本的流体动力学影响,而不仅仅是简单的抛物线。例如,粒子之间应有轻微的排斥力以模拟泡沫的膨胀感,或者在喷射主流周围有随机的速度扰动。整体受重力影响。
  4. 泡沫与环境交互及变形:
    • 重力与堆积: 喷出的泡沫粒子受重力影响下落。当泡沫颗粒接触平面或烧瓶外壁时,它们应该模拟受压变形的效果,例如在垂直方向上被压扁(减少Y轴缩放),并在水平方向上略微扩展(增加X和Z轴缩放)。
    • 堆积形态: 落在平面和烧瓶上的泡沫应该能逐渐堆积起来,形成一定厚度的覆盖层,而不是消失。堆积的泡沫也应有类似的变形和融合效果。
    • **泡沫固定: ** 泡沫在落到物体表面后,略微滑行一段距离便停止移动。
  5. 液体减少: 随着喷发,三角烧瓶内的液体液面逐渐下降,用来演示液体减少的效果。注意不是液体整体缩小,而是液体的顶部的面逐渐下降的效果。

光照与渲染:

  1. 光源:
    • 设置一个主光源,以产生清晰的阴影。
    • 添加一个环境光以提亮场景暗部,确保没有纯黑区域。
  2. 阴影: 启用渲染器的阴影贴图 。平面应能接收阴影,烧瓶和喷出的泡沫应能投射阴影。
  3. 反射与折射: 烧瓶的材质应能展示出环境的微弱反射和光线透过液体及玻璃的折射。

摄像机与控制:

  • 摄像机应从斜45度角俯视场景中心(三角烧瓶所在位置),确保能清晰观察到整个喷发过程和最终堆积效果。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment