当前位置: 首页 > 编程日记 > 正文

三维等值面提取算法(Dual Contouring)

  上一篇介绍了Marching Cubes算法,Marching Cubes算法是三维重建算法中的经典算法,算法主要思想是检测与等值面相交的体素单元并计算交点的坐标,然后对不同的相交情况利用查找表在体素单元内构建相应的网格拓扑关系。Marching Cubes算法简单,但是存在一些缺陷:1.模型二义性问题;2.模型特征问题。

  对于二义性问题,以2D情形为例,存在一个单元中同一顶点状态而不同的连接方式(如下图所示)。

图:2D中Marching Cubes算法的二义性问题

  那么对于上图中两种连接方式的不同选择,可能会导致在同一张图像上完全不同的结果(如下图所示),二义性在3D中的直接后果是产生“孔洞”。如果在一个单元中,一条对角线的两端点值大于等值面阈值,另一条对角线的两端点值小于等值面阈值,那么通常会发生这种二义性问题。

图:二义性问题的不同结果

  对于特征问题,由于Marching Cubes算法只计算体素单元的交点坐标信息,并根据这些交点连接的三角面片来构建体素单元内的几何模型,这样假如体素单元内存在几何模型的特征信息(棱边、棱角),但是Marching Cubes算法最终构建出的几何模型会缺少这些特征信息(如下图所示)。

图:左上-交点坐标和法向;右上-Marching Cubes算法;左下-Extended Marching Cubes算法;右下-Dual Contouring算法

  Dual Contouring算法[Ju et al. 2002]也是经典的等值面提取算法,相比Marching Cubes算法,Dual Contouring算法利用Hermite数据(交点的位置和法向)进行等值面构建,它克服了Marching Cubes算法所出现的缺陷。具体算法分两步:

  第一步:利用二次误差函数生成顶点坐标

  对于每个与等值面相交的体素单元,通过最小化二次误差函数来生成一个顶点坐标:

 

其中pi为交点的位置,ni为交点的法向。

  误差函数可以写成矩阵形式:

 

其中矩阵A的行向量为交点的法向ni,向量b的每个元素为ni·pi

  极值点可以通过求解正则方程得到:

 

  但是文章指出这种方式会存在数值不稳定,并提出一种解决方法。基于QR矩阵分解计算正交矩阵Q,使得Q与[A b]相乘为如下上三角矩阵形式:

 

其中A'为3*3的上三角矩阵,b'为长度为3的向量,r为标量。

  那么误差函数可以变化为:

 

  然后再根据上式计算极值点。

  第二步:生成网格面片

  对于每一条等值面相交的体素边,那么包含该体素边的4个相邻体素单元内必然都存在顶点,将这4个顶点连接生成1个四边形面片。

  

  文章[Schaefer et al. 2002]详细介绍了Dual Contouring算法的实现细节,通过总结该文可以得到Dual Contouring算法过程如下:

  对于每个与等值面相交的体素单元:

  1. 创建1个4*4的零矩阵用于存放QR矩阵分解的结果;

  2. 对于体素单元的每条相交边,计算交点的位置pi和对应的法向ni

  3. 将向量[ ni.x, ni.y, ni.z, dot(pi,ni) ]添加到4*4的零矩阵底部;

  4. 通过QR矩阵分解得到3*3的上三角矩阵A'和向量b';

  5. 求解线性方程组A'TA'x = (A'Tb' - A'Tb'c) , 其中c是体素单元中所有交点的质心位置;

  6. 将计算得到的偏移量x加上质心位置c即为体素单元中的顶点坐标;

  7. 如果计算得到的顶点坐标位于体素单元之外,那么顶点坐标用质心位置c来代替;

  8. 对于每一条相交的体素边,将其周围4个体素单元内的顶点连接生成1个四边形面片。

 

图:左- Marching Cubes算法;右-Dual Contouring算法

 

图:左- Marching Cubes算法;右-Dual Contouring算法

 

图:box与sphere相交模拟

本文为原创,转载请注明出处:http://www.cnblogs.com/shushen。

相关: 

水泡动画模拟(Marching Cubes):http://www.cnblogs.com/shushen/p/5542131.html

参考文献:

[1] Tao Ju, Frank Losasso, Scott Schaefer, and Joe Warren. 2002. Dual contouring of hermite data. ACM Trans. Graph. 21, 3 (July 2002), 339-346.

[2] Scott Schaefer and Joe Warren. Dual contouring: The secret sauce. Technical Report 02-408, Department of Computer Science, Rice University, 2002.

[3] http://users.csc.calpoly.edu/~zwood/teaching/csc572/final15/kpidding/index.html

转载于:https://www.cnblogs.com/shushen/p/5607833.html

相关文章:

设置status bar的颜色

statusBar显示电池电量、时间、网络部分标示的颜色只能设置两种颜色: 默认的黑色(UIStatusBarStyleDefault)白色(UIStatusBarStyleLightContent) 配置info.plist文件 1.View controller-based status bar appearance…

EOS与以太坊有哪些区别?

链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 以太坊是一个专门为开发和运行去中心化应用(DAPP)搭建的智能合约平台;EOS与以太坊类似,同样…

Quartz 2D基本图形的绘制

基本步骤: 1.获取绘图上下文 2.创建并设置路径 3.将路径添加到上下文 4.设置上下文状态 5.绘制路径 6.释放路径 #import "YGView.h" //屏幕尺寸#define kScreenSize [UIScreen mainScreen].bounds.size//屏幕宽高定义#define kscreenWidth [[UIScr…

命令行程序增加 GUI 外壳

Conmajia © 2012 Updated on Feb. 21, 2018 命令行大家都用过: 图 1 命令行程序工作界面 现在想办法为它做一个 GUI 外壳,实际效果参考图 2. 图 2 带 GUI 外壳的命令行程序 程序思路是这样的: 通过运行 cmd.exe 来操作命令行&#xff0c…

人月神话阅读笔记07

第1章 焦油坑焦油坑的意思说明了即使你足够强大,也无法摆脱束搏而沉到坑底。IT项目也是这样,不论是开发大型软件系统还是小型项目,都会遇到诸多复杂的问题和影响因素,项目本身就是一个足够复杂的动态系统,没有最优&…

区块链隐私:交易还是计算?

链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 区块链隐私:交易还是计算? 隐私”是什么意思?在区块链生态系统中,“隐私”这个词被用于许多不同的语…

8 ServletContext

1 为什么需要ServletContext 技术 显示网站多少人在线,显示当前登录者是第几位登录者等信息。 2 什么是ServletContext 可以把它想象成一个服务器上的公共空间,每个用户都可以访问到它。 Web 容器在启动时,它会为每个Web 应用程序都创建一个对…

IOS沙盒Files目录说明和常用操作

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 读取Documents目录代码 NSArray *pathsDocumentsNSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); NSString *pathDocu…

iOS一些实用的技巧

获取触摸的点- (CGPoint)locationInView:(UIView *)view; - (CGPoint)previousLocationInView:(UIView *)view;自动适应父视图大小self.view.autoresizesSubviews YES;self.view.autoresizingMask UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;把pli…

在公共区块链中通过加密保护数据

链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 隐私限制 在处理或交换业务文件时,贸易伙伴可能需要某些隐私因素。 (1)交易数据的隐私性: 交易数据仅供交易双方阅读。 (2)交…

python xml模块学习

xml打开方式 # xml有两种打开方式 # 1. 打开文件,读取XML内容 str_xml open(xman.xml, r).read() print(str_xml)# 将字符串解析成xml特殊对象,root代指xml文件的根节点 root ET.XML(str_xml) # 读取字符串,将字符串转为Element对象 pri…

实例 - 购物车 (列表、循环)

salary int(input(Please input your money:))product [(iphone6s,5800),(mac bood,9000),(coffee,32),(python book,80),(bicyle,1500), ]shopping []while True:#打印商品内容n 1for i,v in product:print(n,.,i,v)n 1#引导用户选择商品choice input(选择购买商品编号:…

右滑手势导航返回的相关设置

iOS7之后提供了右滑返回上一级界面的手势,但是自定义返回按钮会失效,解决办法如下: -(void)viewWillAppear:(BOOL)animated{ [superviewWillAppear:animated]; if([self.navigationController respondsToSelector:selector(interacti…

区块链编程完全指南:平台、语言与结论

链客,专为开发者而生,有问必答! 此文章来自链客区块链技术问答社区,未经允许拒绝转载。 区块链,代表着未来的发展方向。是的,在文章开头,我们首先给出这样的结论。当然,认定未来将围…

基于QProbe创建基本Android图像处理框架

先来看一个GIF 这个GIF中有以下几个值得注意的地方这个界面是基本的主要界面所应该在的地方。其右下角有一个“”号,点击后,打开图像采集界面在这个界面最上面的地方,显示的是当前图像处理的状态。(一般来说,是成功/不…

iOS三种拨打电话的方法

1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示NSMutableString* str[[ NSMutableStringalloc ] initWithFormat : "tel:%" , "xxxxxxxxxxx" ];[[UIApplica…

查询今天是周几?

<?php $wdate(w); $weekarray( "0">"星期日", "1">"星期一", "2">"星期二", "3">"星期三", "4">"星期四", "5">"星期五",…

区块链学习之-发布合约

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 命令行编译&#xff0c;发布合约1. 编译合约&#xff0c;编译不了curl --data ‘{“jsonrpc”:“2.0”,“method”: “eth_compileSolidi…

Codeforces 900D Unusual Sequences:记忆化搜索

题目链接&#xff1a;http://codeforces.com/problemset/problem/900/D 题意&#xff1a; 给定x,y&#xff0c;问你有多少个数列a满足gcd(a[i]) x 且 ∑(a[i]) y。 题解&#xff1a; 由于gcd(a[i]) x&#xff0c;所以y一定是x的倍数&#xff0c;否则无解。 那么原题就等价于…

对AFNetworking的简单封装

#import "YGLoadDataManager.h"#import "AFNetworking.h"implementation YGLoadDataManager#pragma mark -- GET请求 -- (void)getWithURLString:(NSString *)URLStringparameters:(id)parameterssuccess:(void (^)(id))successfailure:(void (^)(NSError …

js原型链prototype与__proto__以及new表达式

对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model转载于:https://www.cnblogs.com/imust2008/p/5621751.html

公有链和联盟链的本质不同

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 区块链是生命体、经济体。未来的区块链世界离不开自己的价值尺度建设 公有链和联盟链的本质不同 区块链受到大家广泛关注应该是2015年10月…

C++ 重载运算符简单举例

我们可以重定义或重载大部分 C 内置的运算符。这样&#xff0c;就能使用自定义类型的运算符。 重载的运算符是带有特殊名称的函数&#xff0c;函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样&#xff0c;重载运算符有一个返回类型和一个参数列表。…

ApacheBench(ab)使用详解

ab命令原理 Apache的ab命令模拟多线程并发请求&#xff0c;测试服务器负载压力&#xff0c;也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。 ab命令对发出负载的计算机要求很低&#xff0c;既不会占用很多CPU&#xff0c;也不会占用太多的内存&#xff0c;但却会给目…

ios如何实现静音模式下声音仍然可以外放

AVAudioSession *audioSession [AVAudioSession sharedInstance]; [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

创建数据目录及多节点目录

链客&#xff0c;专为开发者而生&#xff0c;有问必答&#xff01; 此文章来自链客区块链技术问答社区&#xff0c;未经允许拒绝转载。 创建数据目录及多节点目录 mkdir -p ~/workmeta/EduEthereumServerDeploy/deploy_2/{node1,node2} > cd ~/workmeta/EduEthereumServerD…

卷积神经网络学习笔记与心得(4)池化

图片经过卷积、激活后的结果一般带有大量原图信息。 上图中卷积核提取的是竖直方向上的连续像素&#xff0c;但是&#xff0c;被增强的像素只占了结果的1/3&#xff0c;对于多层网络&#xff0c;其余重要性较低的信息也被传入了下一层网络&#xff0c;造成了不必要的浪费&#…

mina、netty消息边界问题(采用换行符)

在TCP连接开始到结束连接&#xff0c;之间可能会多次传输数据&#xff0c;也就是服务器和客户端之间可能会在连接过程中互相传输多条消息。理想状况是一方每发送一条消息&#xff0c;另一方就立即接收到一条&#xff0c;也就是一次write对应一次read。但是&#xff0c;现实不总…

关于延时操作的使用

延时操作主要有4种方式 1.sleep方式 [NSThread sleepForTimeInterval:1.0f]; [self delayMethod]; 使用sleep方式在主线程和子线程中均可执行,但是这是中阻塞线程的方式,所以建议放到子线程中使用,以免卡住主线程使界面卡住. 没有发现取消执行的方法. 2.NSTimer定时器方式 …

CGpoint,CGSize,CGRect,NSRange

NSRange (范围);(location,位置 length&#xff0c;长度; NSPoint /CGpoint&#xff08;点&#xff09;; NSSize /CGSize&#xff08;大小&#xff09; CGPoint p1 CGPointZero CGPointMake(0, 0)代表原点 CGSizeZero CGSizeMake(0, 0);代表大小为0 CGRect rec CGRectMake…