[Graphics]自组织植物建模方法(Continous&Lasso&Brush)

最近做了一个小程序,顺便用在了国科大“智能人机交互”课程(2018秋学期)的作业里。主要就是用self-organizing tree modeling和sketch的手段合起来做的程序。

用来实现自组织的植物建模。所谓的自组织,主要是指芽Bud对空间Space、资源Resource的争夺,前者实现了Branch在空间中进行自发生长,后者则用以模拟植物的顶端优势。在正文开始之前,还是惯例介绍一下这次做的结果~

一、相关资源和信息:

开发环境:C++/OpenGL

B站视频:https://www.bilibili.com/video/av42213837/

演示程序:https://pan.baidu.com/s/1swjQqXv

二、程序的部分效果截图:

本程序基于自组织的植物建模方法,开发了三种创建模式,分别是:套索、自生长、刷子。其效果分别如下所示:

1. 使用套索Lasso

2. 自组织生长的植物

自组织生成的不同形态的植物模型
自组织生成的不同形态的植物模型

 

不同形态的植物模型
自组织生成的植物模型

 

3. 使用刷子创建植物模型

刷子对植物进行形状编辑

三、算法流程

接下来的部分将对本程序的核心思路进行描述。假设读者已经具备一定的图形学知识,这里就简单介绍一下self-organizing modeling的部分,其他sketch部分就不介绍了。

1. 基本数据结构的定义:

InterNode:树木的一段枝干,由两个坐标点描述,位于两点之间的线段即一小段枝干,是植物模型的最小分割单元。

芽Bud:每个Bud可生长出一个Metamer,每个Metamer由若干InterNode组成。Bud分为顶芽Terminal Bud侧芽Lateral Bud

2. Space Colonization空间殖民方法指导的自组织生长

为了表示可供植物生长的空间,我们用一个点集表示。这些点均匀的分布在三维空间中,我们可称之为Marker Points

每次迭代过程中,需分析现存的每个芽Bud。对于每个Bud,使用如下图所示的探测锥来对空间进行探索,其中半径为r的球形空间是bud的独有空间;半径为d+r的锥形空间为探测区域,落于其中的Marker Points描述了Bud的生长方向。在每轮迭代过程中,首先将每个Bud的独有球形空间内的Marker Points删除,接着计算Bud到位于锥形空间内的所有Marker Points的平均方向v(描述新生的Metamer的生长方向),生长结束后,删除位于锥形空间内的Marker Points。

Bud的探测椎

3. 顶端优势

顶端优势在整个建模过程中,并非是必须的步骤,但是使用顶端优势能够丰富植物模型的种类。本程序采用的顶端优势过程分为两个过程:自顶向下的积累资源、自下向上的分配资源。

(1)自顶向下的积累资源:

假设每个芽Bud接收的光照均为1.0,然后我们从上往下逐层积累光照资源,如上图左所示,每个InterNode中积累的资源是其子InterNode资源的总和,不断向下计算直到根节点位置。此时,假设根节点积累的光量资源为Q。

(2)自下向上的分配资源:

这里对根节点的资源翻倍,即根节点的待分配资源v为根节点积累的资源Q的2倍:v = 2Q。然后从下向上分配资源,因此为了描述顶端优势,我们引入参数λ(λ介于0~1之间):其中λv表示分配到顶芽的资源,(1-λ)v表示分配到侧芽的资源。因此若λ<0.5,则侧芽生长旺盛,顶芽受到抑制;若λ>0.5,则顶芽生长旺盛,侧芽受到抑制。我们可以让每个InterNode获得的资源表示该枝段的长度,以表达其顶端优势控制的效果。

使用顶端优势的几种不同结果如下图所示:

 

### saADC 连续模式配置与使用 saADC(Single-ended Analog-to-Digital Converter)是一种单端模数转换器,在嵌入式系统中广泛用于将模拟信号数字化以便进一步处理。对于 saADC 的连续模式配置和使用,以下是详细的说明。 #### 配置 saADC 连续模式的关键要素 为了启用 saADC 的连续模式并确保其正常工作,需要完成以下几个方面的设置: 1. **使能 saADC 模块** 在硬件初始化阶段,需通过寄存器操作或驱动函数启动 saADC 模块。这通常涉及向控制寄存器写入特定值以激活模块[^1]。 2. **配置采样间隔** 设置合适的采样时间间隔是实现连续模式的核心之一。可以通过修改 `SAADC_SAMPLE_INTERVAL` 寄存器来指定两次采样之间的延迟。此参数决定了 ADC 转换频率,因此应根据应用需求调整[^3]。 3. **设定触发源** 对于连续采集而言,可以选择软件触发或者外部事件作为每次新测量周期的起点。当采用自动循环方式时,则无需额外干预即可持续获取数据流[^2]。 4. **定义缓冲区大小及位置** 创建一个足够大的内存区域用来存储由 SAADC 返回的结果值集合;同时告知外设这些地址信息所在之处——即加载相应的描述符结构体成员变量至对应字段之中去指向实际分配出来的 RAM 块首址及其长度等属性值。 5. **中断与 DMA 支持** 如果希望减少 CPU 占用率可以考虑利用直接内存访问(DMA)技术来进行大批量的数据搬运动作而不需要频繁唤醒处理器参与其中的工作流程当中去执行简单的复制粘贴类任务而已了事罢了嘛~ 另一方面来说呢?也可以依靠异常机制通知应用程序层有关已完成某些预定条件下的具体情形如何啦!比如说每当有一组新的样本准备好可供读取的时候就产生一次IRQ请求让上位机知道现在已经有新鲜出炉的好东西等着被拿走咯! 6. **校准过程** 开始任何精确度要求较高的检测之前最好先做一下零点漂移补偿之类的前期准备工作哦~这样可以获得更加可靠稳定的最终输出数值表现效果哟~ ```c // 示例代码展示如何配置 nRF5 SDK 中的 SAADC 为连续模式 void configure_saadc_continuous_mode(void){ ret_code_t err_code; // 初始化 SAADC 外设 err_code = saadc_init(); APP_ERROR_CHECK(err_code); // 定义输入通道以及增益因子等相关选项... saadc_channel_config_t channel_conf; memset(&channel_conf, 0, sizeof(channel_conf)); channel_conf.gain = SAADC_GAIN1_6; // Gain setting. channel_conf.reference = SAADC_REFERENCE_INTERNAL;// Reference voltage source selection. channel_conf.acquisition_time = SAADC_ACQUISITION_TIME_40US; // Acquisition time. // 启动第一个通道 (假设连接到AIN0) err_code = saadc_channel_init(0,&channel_conf); APP_ERROR_CHECK(err_code); // 设定采样速率 和 缓冲区管理策略 ... uint8_t buffer[CONFIG_BUFFER_SIZE]; err_code = saadc_buffer_set(buffer,sizeof(buffer)/sizeof(uint16_t),true); // true 表示开启环形缓冲功能 APP_ERROR_CHECK(err_code); // 最后一步:切换成 CONTINUOUS MODE 并开始监听 IRQs 或者等待 DMA 请求到来~ err_code = saadc_start(SAADC_MODE_CONTINUOUS,NULL); APP_ERROR_CHECK(err_code); } ``` 以上就是关于如何针对 saADC 实现连续扫描工作的基本指导方针概述内容总结完毕之后接下来让我们来看几个可能感兴趣的相关话题讨论吧?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值