GAMES101(作业8)

news2024/9/30 5:45:34

作业8

题目:

模拟绳子动画,包括基于物理的,和非物理的,应该修改的函数是:rope.cpp 中的void Rope::simulateEuler(... Rope::rope(...),,void Rope::simulateVerlet(...)

代码框架:

main:负责接收命令行参数,通过getopt捕获参数设置AppConfig的数据-》创建Application,设置渲染器

  • int getopt(int argc,char * const argv[ ],const char * optstring);用来分析命令行参数

    • 参数argc和argv分别代表参数个数和内容,跟main( )函数的命令行参数是一样的。

    • 参数 optstring为选项字符串

      • 单个字符,表示选项

      • 单个字符后接一个冒号:表示该选项后必须跟一个参数

      • 单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟。

    • 全域变量optarg指向当前选项参数(如果有)的指针。

CGL:命名空间,包含应用层一下所有模块

application:应用程序

  • AppConfig类,负责从命令行接收信息,mass质点的质量,ks弹簧劲度系数,gravity重力,steps_per_frame每帧仿真步长数

  • Application类继承CGL库中的Renderer

    • 初始化,调用rope的构造函数

    • 渲染,通过opengl库:渲染点(质点),线(弹簧)

void Application::render() {
  //Simulation loops
  for (int i = 0; i < config.steps_per_frame; i++) {/* 每帧仿真步长数 */
    /* 对两个绳子更新这一帧的位置 */
    ropeEuler->simulateEuler(1 / config.steps_per_frame, config.gravity);
    ropeVerlet->simulateVerlet(1 / config.steps_per_frame, config.gravity);
  }
  // Rendering ropes
  Rope *rope;
  /* 分别两个绳子,并设置颜色,和当前绳子*/
  for (int i = 0; i < 2; i++) {
    if (i == 0) {
      glColor3f(0.0, 0.0, 1.0);
      rope = ropeEuler;
    } else {
      glColor3f(0.0, 1.0, 0.0);
      rope = ropeVerlet;
    }
    /* 绘制质点 */
    glBegin(GL_POINTS);

    for (auto &m : rope->masses) {
      Vector2D p = m->position;
      glVertex2d(p.x, p.y);
    }

    glEnd();
    /* 绘制弹簧 */
    glBegin(GL_LINES);

    for (auto &s : rope->springs) {
      Vector2D p1 = s->m1->position;
      Vector2D p2 = s->m2->position;
      glVertex2d(p1.x, p1.y);
      glVertex2d(p2.x, p2.y);
    }

    glEnd();
    /* 提交缓冲区到前台 */
    glFlush();
  }
}

rope:绳子类,包括质点数组,弹簧数组,simulateEuler基于物理的仿真,simulateVerlet非物理的仿真

mass:质点类,包含一个质点,质量,pinned是否是固定的,开始位置,速度,受力等

spring:弹簧类,包括一个弹簧,2个质点,长度,劲度系数k等

解:

首先安装库
sudo apt i n s t a l l l i b g l u 1 −mesa−dev f r e e g l u t 3 −dev \\
mesa−common−dev
sudo apt i n s t a l l xorg−dev #会自 动 安装 l i b f r e e t y p e 6 −dev
 创建绳子

在构造函数中,遍历每个质点,调用mass:类和spring类的构造,并存放到rope的数组中,并且根据参数值,设置mass:对象和spring对象的属性

Vector2D step = (end - start) / (num_nodes - 1);
for(int i = 0; i < num_nodes; i++){
    masses.push_back(new Mass(start + step * i, node_mass, true));
    if(i){
        springs.push_back(new Spring(masses[i-1], masses[i], k));
        masses[i]->pinned = false;
    }
}

 

simulateEuler()

首先遍历绳子的每个弹簧,根据胡可定律计算受到的力,包括ab质点的相互作用力,fr摩擦力,以及空气阻力,带入公式就好

然后遍历每个质点,如果非固定属性,那么根据首先根据f = ma 计算加速度,再根据欧拉方法计算质点的这一步长的位置,+=是上一步长的位置 + 这一步长的增量

for (auto &s : springs)
{
    float length = (s->m2->position - s->m1->position).norm();
    Vector2D dis = s->m2->position - s->m1->position;
    Vector2D force = s->k * (length - s->rest_length) * dis / length;
    s->m1->forces += force;
    s->m2->forces -= force;
    // damping
    Vector2D reve = s->m2->velocity - s->m1->velocity;
    Vector2D force1 = 0.05 * (reve.x * dis.x + reve.y * dis.y) * dis / length;
    s->m1->forces += force1;
    s->m2->forces -= force1;
    // air damping
    s->m1->forces -= 0.005 * s->m1->velocity;
    s->m2->forces -= 0.005 * s->m2->velocity;

for (auto &m : masses)
{
    if (!m->pinned)
    {
        m->forces += gravity;
        m->velocity += m->forces / m->mass * delta_t;
        m->position += m->velocity * delta_t;
        m->forces = Vector2D(0, 0);
}

 

 simulateVerlet()

作业告诉了这个公式, 带入就好

for (auto &s : springs)
{
    float length = (s->m2->position - s->m1->position).norm();
    Vector2D dis = s->m2->position - s->m1->position;
    Vector2D force = s->k * (length - s->rest_length) * dis / length;
    s->m1->forces += force;
    s->m2->forces -= force;
}
for (auto &m : masses)
{
    if (!m->pinned)
    {
        Vector2D temp_position = m->position;
        m->forces += gravity;
        Vector2D pos = m->position;
        m->position += (1 - 0.00005) * (m->position - m->last_position) + m->forces / m->mass * delta_t * delta_t;
        m->last_position = pos;
    }
    m->forces = Vector2D(0, 0);
}

 

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

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

相关文章

9.26-9.29学习

一.项目结构的建立 5个微服务模块 新建好各个模块后&#xff0c;在项目pom下引入各模块。各pom文件指定springboot版本2.1.8.RELEASE .gitignore #表示任意路径下的xx文件 **/mvnw **/mvnw.cmd**/.mvn **/target/.idea**/.gitignore 二.数据库初始化 一个微服务模块对应一个数…

微信小程序 蓝牙通讯

客户的需求如下&#xff1a;通过微信小程序控制蓝牙ble设备(电子面膜)&#xff0c;通过不同指令控制面膜的亮度和时间。 01.首先看下客户的ble设备服务文档&#xff1a;(本部分需要有点蓝牙基础,在调试过程中可以用安卓软件nRF Connect软件来执行测试命令) 0xFFF1灯控命令 命…

PCL 法线空间采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 法线计算 2.1.2 基于法线进行采样 2.1.3 可视化原始点云和采样后的点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实…

英伟达的AI一键生成数字人物理运动动画框架:统一控制模式,提升交互性和沉浸感

在虚拟现实(VR)、增强现实(AR)和3D内容创作领域,创建具有真实感和动态性的虚拟角色一直是技术上的挑战。最近,英伟达推出了一种新的框架,通过将物理驱动的角色控制视为运动修复问题,实现了跨场景的虚拟角色控制。这一创新方法不仅支持多种控制模式,还能够生成连贯且自…

container_of 函数的分析

这个函数的目的是&#xff0c; 通过结构体里面的内容 找到 大结构体的 基地址。 函数的原型是&#xff1a;  &#xff30;&#xff34;&#xff32;是指针 &#xff54;&#xff59;&#xff50;&#xff45; &#xff0c; &#xff4d;&#xff45;&#xff4d;&#xff…

PCL 快速均匀下采样

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 快速均匀下采样 2.1.2 可视化原始点云和下采样后的点云 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#…

恋爱辅助应用小程序app开发之广告策略

恋爱话术小程序带流量主广告开启&#xff0c;是一个有效的盈利模式&#xff0c;可以增加小程序的收入来源。以下是对此的详细分析 一、流量主广告的定义与优势 流量主广告是指在小程序中嵌入广告位&#xff0c;通过展示广告内容来获取广告主的付费。对于恋爱话术小程序而言&am…

图解C#高级教程(一):委托

什么是委托 可以认为委托是持有一个或多个方法的对象。但它与对象不同&#xff0c;因为委托可以被执行。当执行委托时&#xff0c;委托会执行它所“持有”的方法。先看一个完整的使用示例。 // See https://aka.ms/new-console-template for more informationdelegate void M…

无人机避障—— 激光雷达定高北醒TF03-UART(二)

无人机避障过程&#xff0c;光靠大疆飞控内部的气压计不准&#xff0c;很容易在高度较低的时候受到地面植被等障碍物影响&#xff0c;使得掉高严重&#xff0c;因此采用激光雷达定高模块进行定高。 硬件&#xff1a; 北醒TF03-UART、Xavier-NX 软件代码&#xff1a; 北醒官…

关于没有启用root问题,分区表挂载错误,导致系统无法启动

方法一、root没有登陆过&#xff0c;改root密码 1、为啥这样设置&#xff0c;root 2、密码破解也无效 2.1、开机启动&#xff0c;按 e 进入启动文件界面 2.2、把ro修改为rw&#xff0c;注意r和o之间包了个反斜杠 2.3、ctrl x退出当前模式 2.4、rw initsysroot/bin/sh 2.5、c…

HarmonyOs 查看官方文档使用弹窗

1. 学会查看官方文档 HarmonyOS跟上网上的视频学习一段时间后&#xff0c;基本也就入门了&#xff0c;但是有一些操作网上没有找到合适教学的视频&#xff0c;这时&#xff0c;大家就需要养成参考官方文档的习惯了&#xff0c;因为官方的开发文档是我们学习深度任何一门语言或…

http请求过程 part-2

http请求过程 http应用层 实体 实体分为实体首部和实体主体&#xff0c;实体首部是用来描述主体的 实体部分是可选的&#xff0c;它被用来运送请求或者响应的数据 传输层-TCP HTTP连接是建立在TCP连接的基础上 以流形式通过一条已经打开的TCP连接&#xff0c;按顺序进行…

Django Web开发接口定义

Django Web 介绍 Django Web是一个Pyhton高级 Web 框架,实际上 Django 也可以做到前后端分离,即主要作为后端框架使用,不用模板渲染也是可行的。 Django Web 应用的运行流程,如下图所示: 此外,Django Web 在开发环境可以通过自带的服务器进行本地调试。但是该服务器不适…

LeetCode从入门到超凡(五)深入浅出---位运算

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的LeetCode学习总结文档&#xff1b;本文主要讲解 位运算算法。&#x1f495;&#x1f495;&#x1f60a; 一、 位运算简介 1.什么是位…

【腾讯元宝-免费论文精读】

【腾讯元宝-免费论文精读】 1. 腾讯混元大模型2. 论文精读过程3. 总结&#xff1a; 1. 腾讯混元大模型 由腾讯研发的大语言模型&#xff0c;具备强大的中文创作能力&#xff0c; 复杂语境下的逻辑推理能力&#xff0c;以及可靠的任务执行能力 腾讯元宝&#xff1a;轻松工作&am…

Django对接支付宝沙箱环境(2024年9月新测有效)

1、申请沙箱环境 #需要填一些个人信息 https://opendocs.alipay.com/ 2、使用支付宝登入&#xff0c;并进入控制台&#xff0c;进入开发者工具推荐-->沙箱 3、获取基本信息 主要是APPID,和支付宝网关地址 4、生成应用私钥和应用公钥和支付宝公钥 上面的接口加签方式选择…

【Linux 22】生产者消费者模型

文章目录 &#x1f308; 一、生产者消费者模型⭐ 1. 生产者消费者模型的概念⭐ 2. 生产者消费者模型的特点⭐ 3. 生产者消费者模型的优点 &#x1f308; 二、基于阻塞队列的生产消费模型⭐ 1. 阻塞队列概念⭐ 2. 模拟实现基于阻塞队列的生产消费模型 &#x1f308; 三、POSIX 信…

Kubernetes云原生存储解决方案之 Rook Ceph实践探究

Kubernetes云原生存储解决方案之 Rook Ceph实践探究 除了手动部署独立的 Ceph 集群并配置与Kubernetes进行对接外&#xff0c;Rook Ceph 支持直接在 Kubernetes 集群上部署 Ceph 集群。 通过Rook Ceph云原生存储编排平台&#xff0c;使得 Kubernetes 集群中启用高可用的 Ceph…

PHP 基础语法详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

【有啥问啥】多目标跟踪SORT算法原理详解

多目标跟踪SORT算法原理详解 引言 多目标跟踪&#xff08;Multiple Object Tracking, MOT&#xff09;是计算机视觉领域的一个重要研究方向&#xff0c;广泛应用于视频监控、自动驾驶、人机交互等多个领域。其核心任务是在视频序列中持续、准确地识别和定位多个目标。SORT&am…