Games 103 作业二

news2024/12/27 14:24:54

Games 103 作业二

作业二其实就是要使用隐式积分和PBD两种方式来实现布料求解。难度相对于作业一来说要简单一些,在文档中基本把步骤都写清楚了。主要逻辑首先参考Lecture 05 PPT的第18页:

Games 103 作业二1

然后我们按照文档的步骤一步一步地来。注意0号顶点和20号顶点是不参与更新的,它们相当于就是定死了位置。第一步是初始化,这个很简单:

for (int i = 0; i < V.Length; i++)
{
    if (!Skip_Update(i))
    {
        V[i] *= damping;
    }
}
for(int i = 0; i < X.Length; i++)
{
    if (!Skip_Update(i))
    {
        X_hat[i] = X[i] + V[i] * t;
        X[i] = X_hat[i];
    }
}

第二步就是计算梯度。这里的梯度就是PPT里的
∇ F ( x ( k ) ) = 1 Δ t 2 M ( x ( k ) − x [ 0 ] − Δ t 2 v [ 0 ] ) − f ( x ( k ) ) \nabla F(\textbf{x}^{(k)}) = \dfrac{1}{\Delta t^2} \textbf{M} (\textbf{x}^{(k)} - \textbf{x}^{[0]} - \Delta t^2 \textbf{v}^{[0]}) - \textbf{f} (\textbf{x}^{(k)}) F(x(k))=Δt21M(x(k)x[0]Δt2v[0])f(x(k))
这里的f就是重力和弹簧间的弹力。重力是个常量好办,弹力的计算需要遍历所有的边,找到边的两个顶点,分别进行计算,参考PPT的第11页:

Games 103 作业二2

void Get_Gradient(Vector3[] X, Vector3[] X_hat, float t, Vector3[] G)
{
    //Momentum and Gravity.
    for (int i = 0; i < G.Length; i++)
    {
        if (!Skip_Update(i))
        {
            G[i] = mass * (X[i] - X_hat[i]) / (t * t) - mass * gravity;
        }
    }

    //Spring Force.
    for (int e = 0; e < L.Length; e++)
    {
        int i = E[e * 2 + 0];
        int j = E[e * 2 + 1];
        float x = Vector3.Distance(X[i], X[j]);
        Vector3 f = spring_k * (1 - L[e] / x) * (X[i] - X[j]);

        if (!Skip_Update(i))
        {
            G[i] += f;
        }

        if (!Skip_Update(j))
        {
            G[j] -= f;
        }
    }
}

然后需要计算:
∂ 2 F ( x ( k ) ) ∂ x 2 = 1 Δ t 2 M + H ( x ( k ) ) \dfrac{\partial^2F(\textbf{x}^{(k)})}{\partial\textbf{x}^2} = \dfrac{1}{\Delta t^2}\textbf{M} + \textbf{H}(\textbf{x}^{(k)}) x22F(x(k))=Δt21M+H(x(k))
作业文档中给了近似求解的方法,我们就不用算 H \textbf{H} H了。我们使用Chebyshev加速牛顿法迭代,可以参考PPT中第26页:

Games 103 作业二3

作业中是固定的32次迭代次数,这里的break判断就可以省略掉;另外,x的更新直接使用作业里的公式即可:

for(int k=0; k<32; k++)
{
    Get_Gradient(X, X_hat, t, G);

    if(k == 0)
    {
        omega = 1.0f;
    }
    else if(k == 1)
    {
        omega = 2.0f / (2.0f - rho * rho);
    }
    else
    {
        omega = 4.0f / (4.0f - rho * rho * omega);
    }
    
    //Update X by gradient.
    for(int i = 0; i < X.Length; i++)
    {
        if (!Skip_Update(i))
        {
            Vector3 old = X[i];
            X[i] = omega * (X[i] - 1 / (mass / (t * t) + 4 * spring_k) * G[i]) + (1 - omega) * last_X[i];
            last_X[i] = old;
        }
    }
}

迭代完别忘记更新下V,这里要使用+=,因为一开始算 x ~ \widetilde{x} x 的时候加过v了:

for(int i = 0; i < X.Length; i++)
{
    if (!Skip_Update(i))
    {
        V[i] += (X[i] - X_hat[i]) / t;
    }
}

最后的碰撞检测很简单,算一下点到球心的距离,如果小于半径就说明发生碰撞:

void Collision_Handling()
{
    Mesh mesh = GetComponent<MeshFilter> ().mesh;
    Vector3[] X = mesh.vertices;

    //Handle colllision.
    Vector3 c = sphere.transform.position;
    for(int i = 0; i < X.Length; i++)
    {
        if(!Skip_Update(i))
        {
            float d = Vector3.Distance(X[i], c);
            if (d < r)
            {
                V[i] = V[i] + 1 / t * (c + r * (X[i] - c) / d - X[i]);
                X[i] = c + r * (X[i] - c) / d;
            }
        }
    }

    mesh.vertices = X;
}

最后效果如下:

Games 103 作业二4

然后我们再看下PBD的实现。第一步就是让每个顶点自由更新:

for(int i=0; i<X.Length; i++)
{
    if(i==0 || i==20)	continue;
    //Initial Setup
    //...
    V[i] *= damping;
    V[i] += gravity * t;
    X[i] += V[i] * t;
}

接下来,通过若干次迭代施加约束,这里可以参考Lecture 06 PPT的第10页:

Games 103 作业二5

作业里 α \alpha α取的0.2:

void Strain_Limiting()
{
    Mesh mesh = GetComponent<MeshFilter> ().mesh;
    Vector3[] vertices = mesh.vertices;

    //Apply PBD here.
    //...
    Vector3[] sum_X = new Vector3[vertices.Length];
    int[] sum_N = new int[vertices.Length];

    for (int e = 0; e < L.Length; e++)
    {
        int i = E[e * 2 + 0];
        int j = E[e * 2 + 1];
        float x = Vector3.Distance(vertices[i], vertices[j]);
        Vector3 f = L[e] * (vertices[i] - vertices[j]) / x;

        sum_X[i] += 0.5f * (vertices[i] + vertices[j] + f);
        sum_N[i]++;
        sum_X[j] += 0.5f * (vertices[i] + vertices[j] - f);
        sum_N[j]++;
    }

    for(int i = 0; i < V.Length; i++)
    {
        if(i == 0 || i == 20)	continue;
        Vector3 f = (0.2f * vertices[i] + sum_X[i]) / (0.2f + sum_N[i]);
        V[i] += 1 / t * (f - vertices[i]);
        vertices[i] = f;
    }

    mesh.vertices = vertices;
}

最后效果如下:

Games 103 作业二6

如果你觉得我的文章有帮助,欢迎关注我的微信公众号 我是真的想做游戏啊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JSX基础语法

文章目录 认识JSX语法JSX是什么为什么Rect选择了JSXJSX书写规范JSX注释编写 JSX的基本使用JSX的事件绑定this绑定问题参数传递问题 JSX的条件渲染常见的条件渲染方式 JSX的列表渲染JSX的原理和本质JSX的本质虚拟DOM的创建过程 案例练习 认识JSX语法 // 1. 定义根组件 const el…

【Truffle】一、Truffle的安装与部署

目录 一、准备安装 二、安装truffle 三、创建 Truffle 项目工程 1.为 Truffle 项目创建新目录&#xff1a; 2.下载 (“unbox”) MetaCoin box: 四、项目分析 五、测试合约 一、准备安装 安装truffle必须要提前配置Nodejs环境&#xff0c;关于Nodejs的配置&#xff0c;我在…

黑豹程序员-架构师学习路线图-百科:Lombok消除冗长的java代码

文章目录 1、为什么要使用Lombok&#xff1f;2、Lombok的工作原理3、反对声渐渐消亡4、总结4.1、什么是Lombok&#xff1f;4.2、Lombok的发展历史4.3、Lombok常见的注解 1、为什么要使用Lombok&#xff1f; 现代的java项目开发都使用分层开发&#xff0c;MVC分层已经深入人心&…

Vue组件自定义事件实现子组件给父组件传递数据

一、绑定自定义事件 &#xff08;一&#xff09;使用v-on或绑定事件 事件是绑定在组件身上的&#xff0c;当我们触发这个事件的时候&#xff0c;就会执行事件回调函数。 <组件标签 v-on:事件名"事件回调函数"/> // 或 <组件标签 事件名"事件回调函…

文心一言 VS 讯飞星火 VS chatgpt (122)-- 算法导论10.4 3题

三、用go语言&#xff0c;给定一个n结点的二叉树&#xff0c;写出一个 O(n)时间的非递归过程&#xff0c;将该树每个结点的关键字输出。可以使用一个栈作为辅助数据结构。 文心一言&#xff1a; 以下是一个使用 Go 语言编写的函数&#xff0c;该函数使用一个栈作为辅助数据结…

Web应用系统设计

Web应用设计的本质目的是为了解决软件系统的复杂性,所以我们在进行web设计时,首先要分析系统的复杂性,然后再进行设计。 1.案例 某公司在创业初期快速地开发了一个B2C的垂直电商网站,然后就迅速的投向市场进行运营。为了能够快速上线,系统设计得非常简单,选择了三层架构…

大厂面试题-Java并发编程基础篇(一)

目录 一、什么是守护线程&#xff0c;它有什么特点 二、谈谈你对AQS的理解 三、AbstractQueuedSynchronized为什么采用双向链表 四、lock和synchronized区别 五、线程池如何知道一个线程的任务已经执行完成 六、什么叫做阻塞队列的有界和无界 七、ConcurrentHashMap底层…

拓扑排序基础详解,附有练习题

介绍 拓扑排序是一种对有向无环图&#xff08;DAG&#xff09;进行排序的算法。在一个有向图中&#xff0c;如果存在一条从节点 A 到节点 B 的路径&#xff0c;那么节点 A 就依赖于节点 B。 有向无环图如下 什么是入度&#xff0c;出度&#xff1f; 入度&#xff1a;有多少个…

10款轻量型的嵌入式GUI库分享

LVGL LittlevGL是一个免费的开源图形库&#xff0c;提供了创建嵌入式GUI所需的一切&#xff0c;具有易于使用的图形元素、漂亮的视觉效果和低内存占用。 特点&#xff1a; 强大的构建模组 按钮、图表、列表、滑块、图像等 ​先进的图形 动画、反锯齿、半透明、平滑滚动 多样…

【VR开发】【Unity】【VRTK】1-无代码VRVR开发介绍

本篇开始精简讲解VRTK相关的知识。 VRTK是基于Unity的一套提供无代码VR开发的插件,这套插件开源,可商用,集合了目前可能的VR体验组件,可以让不会C#编程但想要开发VR体验的人在不写一行代码的前提下开发出心仪的VR作品。 这套组件问世后也很受欢迎,目前已经进化到了第四代…

2023阿里云双十一优惠活动「云上聚·创未来」价格和代金券领取

2023阿里云双十一优惠活动「金秋云创季」开始啦&#xff0c;10月27日到10月31日可以领满减优惠&#xff0c;到11月1日和11月11日之间可以购买云服务器等产品&#xff0c;11.12到11.30日赢最高百万上云抵扣金&#xff0c;阿里云百科aliyunbaike.com分享2023阿里云双十一优惠活动…

合成数据的好处和用途

在不断变化的数据科学和人工智能环境中&#xff0c;合成数据集的概念成为具有多种用途的强大工具。 假设您是一名数据科学家&#xff0c;并分配了为电子商务网站创建尖端推荐系统的任务。为此&#xff0c;您需要大量的用户交互数据。但是&#xff0c;您面临着保护用户隐私和处…

基本微信小程序的外卖点餐订餐平台

项目介绍 餐饮行业是一个传统的行业。根据当前发展现状&#xff0c;网络信息时代的全面普及&#xff0c;餐饮行业也在发生着变化&#xff0c;单就点餐这一方面&#xff0c;利用手机点单正在逐步进入人们的生活。传统的点餐方式&#xff0c;不仅会耗费大量的人力、时间&#xf…

世界前沿技术发展报告2023《世界航空技术发展报告》(三)民用飞机技术

&#xff08;三&#xff09;民用飞机技术 1.干线飞机1.1 中国C919客机获得型号合格证并交付使用1.2 空客公司A321XLR超远程型窄体客机完成首飞1.3 NASA持续开展下一代民机技术研究1.4 欧洲开展“超高性能机翼”演示验证项目 2.支线飞机2.1 德国航宇中心完成“电动飞机概念及技术…

世界前沿技术发展报告2023《世界航空技术发展报告》(四)无人机技术

&#xff08;四&#xff09;无人机技术 1.无人作战飞机1.1 美国空军披露可与下一代战斗机编组作战的协同式无人作战飞机项目1.2 俄罗斯无人作战飞机取得重要进展 2.支援保障无人机2.1 欧洲无人机项目通过首个里程碑2.2 美国海军继续开展MQ-25无人加油机测试工作 3.微小型无人机…

Python+pytest+request 接口自动化测试!

一、环境配置 1.安装python3 brew update brew install pyenv 然后在 .bash_profile 文件中添加 eval “$(pyenv init -)” pyenv install 3.5.3 -v pyenv rehash 安装完成后&#xff0c;更新数据库 pyenv versions 查看目前系统已安装的 Python 版本 pyenv global 3.5…

C#WinformListView实现缺陷图片浏览器

C#&Winform&ListView实现缺陷图片浏览器 功能需求图像浏览行间距调整悬浮提示 功能需求 机器视觉检测系统中特别是缺陷检测系统&#xff0c;通常需要进行对已经检出的缺陷图片进行浏览查阅。主要是通过条件筛选查询出所需要的数据&#xff0c;进行分页再展示到界面中。…

基于SpringBoot的垃圾分类管理系统

基于SpringBootVue的垃圾分类管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven主要功能&#xff1a;包括前台和后台两部分、首页列表展示、垃圾分类、垃圾图谱、查看详…

当线性规划与算法相遇:揭秘单纯形法(Simplex)的独特魅力

传统的解决线性规划问题的方法是图形法、代数法求解&#xff0c;但是图形法解题有极大的局限性&#xff0c;因为一旦变量超过3个&#xff0c;基本上就无法通过图形解决&#xff0c;而代数法虽然可以解题&#xff0c;但对于复杂的问题可能效果较差甚至无法求解&#xff01; 相比…

嵌入式PID算法理论+实践分析

1.1 概述 比例&#xff08;Proportion&#xff09;积分&#xff08;Integral&#xff09;微分&#xff08;Differential&#xff09;控制器&#xff08;PID控制器或三项控制器&#xff09;是一种采用反馈的控制回路机制&#xff0c;广泛应用于工业控制系统和需要连续调制控制的…