- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
1、引子 。
对于一个标量场数据,我们可以描绘轮廓(Contouring),包括2D和3D。2D的情况称为轮廓线(contour lines),3D的情况称为表面(surface)。他们都是等值线或等值面.
以下是一个2D例子:
为了生成轮廓,必须使用某种形式的插值。这是因为我们只在数据集中的一个有限点集上有标量值,而我们的等高线值可能位于这两个点的值之间。由于最常见的插值技术是 线性插值 ,我们通过沿边缘的线性插值在轮廓表面上生成 点 。如果一条边在其两个端点上有标量值10和0,如果我们试图生成一条值为5的等高线,则边缘插值计算该等高线通过边缘的 中点 .
。
2、Marching cubes算法——从2D理解 。
运用了分治思想,对每个单元格(cell)独立地进行处理。该技术的基本假设是,一个轮廓只能以有限数量的方式通过一个单元格。我们可以构造一个 案例表(case table) ,它枚举一个单元的所有可能的拓扑状态(topological state)。拓扑状态的数量取决于单元格顶点的数量,以及一个顶点相对于轮廓值可以具有的内部/外部关系的数量。 标量值大于轮廓值的顶点被称为在轮廓之内。标量值小于轮廓值的顶点被称为在轮廓之外。 例如,如果一个单元格有四个顶点,并且每个顶点可以在轮廓内部或外部,则有2^4 = 16种可能的方式通过单元格(在实现时可以用bit来实现)。在案例表中, 我们不感兴趣的是轮廓通过单元格的位置(例如,geometrical intersection),感兴趣的只是它如何通过单元格(即单元格中轮廓的topology).
一旦我们选择好属于哪一种case之后,就可以使用插值来计算contour line与cell edge相交的位置。 该算法处理一个单元格,然后移动,或行进到下一个单元格。在访问所有单元格后,将完成轮廓。因此称为marching cubes.
算法的步骤如下:
4、算法需要注意的事项 。
在2D中,轮廓模糊(ambiguos cases,如Fig6.5中的Case 5和Case 10)很容易处理:对于每个模糊的情况,我们选择实现两种可能的情况中的一种。根据选择的不同,轮廓可以延伸或打破当前的轮廓,如Fig 6.9所示。任何一种选择都是可以接受的,因为产生的等高线(contour line)将是连续的和封闭的(或将在数据集(data set)边界结束).
在3D中,这个问题更为复杂。我们不能简单地选择一个独立于所有其他模糊案例的模糊案例。例如,Fig 6.9显示了如果我们不小心实现了两个相互独立的情况,会发生什么。在这个图中,我们使用了通常的情况3,但用它的互补情况替换了情况6。互补的情况是通过将“暗”顶点与“光”顶点交换而形成的。(这相当于将顶点标量值从等值面值以上切换到等值面值以下,反之亦然。)将这两种情况配对的结果是在等值面上留下了一个孔(hole).
一个简单而有效的解决方案通过添加额外的互补案例(complementary cases),扩展了原来的15个marching cubes案例。这些情况被设计成与邻近的情况兼容,并防止在等值面上产生孔。需要6个互补的情况,分别对应于行进立方体的情况3、6、7、10、12和13。互补的行进立方体案例如Fig 6.10所示.
此外,尽管我们说该算法用于规则类型,如四边形和立方体,但marching cubes可以应用于任何拓扑上等同于立方体的单元类型(例如,六面体或非立方体体素).
5、应用 。
Fig 6.11d是由marching cubes创建的等值面。图6.11b是一个来自计算机断层扫描(CT)x射线成像系统的恒定图像强度(image intensity)的表面。(图6.11a是该数据的二维子集。)其强度水平对应于人的骨骼。图6.11c为恒定流密度(flow density)的等值面。图6.11d为铁蛋白分子的电子势等值面。由于我们熟悉人体解剖学,图6.11b中所示的图像可以立即被识别出来。然而,对于计算流体动力学和分子生物学领域的从业者来说,图6.11c和图6.11d同样熟悉。正如这些例子所显示的,轮廓形成的方法是各领域可视化数据的强大而又通用的技术.
。
参考文档:VTKTextBook Scalar Algorithms 。
最后此篇关于界面重建——Marchingcubes算法的文章就讲到这里了,如果你想了解更多关于界面重建——Marchingcubes算法的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
滑动窗口限流 滑动窗口限流是一种常用的限流算法,通过维护一个固定大小的窗口,在单位时间内允许通过的请求次数不超过设定的阈值。具体来说,滑动窗口限流算法通常包括以下几个步骤: 初始化:设置窗口
表达式求值:一个只有+,-,*,/的表达式,没有括号 一种神奇的做法:使用数组存储数字和运算符,先把优先级别高的乘法和除法计算出来,再计算加法和减法 int GetVal(string s){
【算法】前缀和 题目 先来看一道题目:(前缀和模板题) 已知一个数组A[],现在想要求出其中一些数字的和。 输入格式: 先是整数N,M,表示一共有N个数字,有M组询问 接下来有N个数,表示A[1]..
1.前序遍历 根-左-右的顺序遍历,可以使用递归 void preOrder(Node *u){ if(u==NULL)return; printf("%d ",u->val);
先看题目 物品不能分隔,必须全部取走或者留下,因此称为01背包 (只有不取和取两种状态) 看第一个样例 我们需要把4个物品装入一个容量为10的背包 我们可以简化问题,从小到大入手分析 weightva
我最近在一次采访中遇到了这个问题: 给出以下矩阵: [[ R R R R R R], [ R B B B R R], [ B R R R B B], [ R B R R R R]] 找出是否有任
我正在尝试通过 C++ 算法从我的 outlook 帐户发送一封电子邮件,该帐户已经打开并记录,但真的不知道从哪里开始(对于 outlook-c++ 集成),谷歌也没有帮我这么多。任何提示将不胜感激。
我发现自己像这样编写了一个手工制作的 while 循环: std::list foo; // In my case, map, but list is simpler auto currentPoin
我有用于检测正方形的 opencv 代码。现在我想在检测正方形后,代码运行另一个命令。 代码如下: #include "cv.h" #include "cxcore.h" #include "high
我正在尝试模拟一个 matlab 函数“imfill”来填充二进制图像(1 和 0 的二维矩阵)。 我想在矩阵中指定一个起点,并像 imfill 的 4 连接版本那样进行洪水填充。 这是否已经存在于
我正在阅读 Robert Sedgewick 的《C++ 算法》。 Basic recurrences section it was mentioned as 这种循环出现在循环输入以消除一个项目的递
我正在思考如何在我的日历中生成代表任务的数据结构(仅供我个人使用)。我有来自 DBMS 的按日期排序的任务记录,如下所示: 买牛奶(18.1.2013) 任务日期 (2013-01-15) 任务标签(
输入一个未排序的整数数组A[1..n]只有 O(d) :(d int) 计算每个元素在单次迭代中出现在列表中的次数。 map 是balanced Binary Search Tree基于确保 O(nl
我遇到了一个问题,但我仍然不知道如何解决。我想出了如何用蛮力的方式来做到这一点,但是当有成千上万的元素时它就不起作用了。 Problem: Say you are given the followin
我有一个列表列表。 L1= [[...][...][.......].......]如果我在展平列表后获取所有元素并从中提取唯一值,那么我会得到一个列表 L2。我有另一个列表 L3,它是 L2 的某个
我们得到二维矩阵数组(假设长度为 i 和宽度为 j)和整数 k我们必须找到包含这个或更大总和的最小矩形的大小F.e k=7 4 1 1 1 1 1 4 4 Anwser是2,因为4+4=8 >= 7,
我实行 3 类倒制,每周换类。顺序为早类 (m)、晚类 (n) 和下午类 (a)。我固定的订单,即它永远不会改变,即使那个星期不工作也是如此。 我创建了一个函数来获取 ISO 周数。当我给它一个日期时
假设我们有一个输入,它是一个元素列表: {a, b, c, d, e, f} 还有不同的集合,可能包含这些元素的任意组合,也可能包含不在输入列表中的其他元素: A:{e,f} B:{d,f,a} C:
我有一个子集算法,可以找到给定集合的所有子集。原始集合的问题在于它是一个不断增长的集合,如果向其中添加元素,我需要再次重新计算它的子集。 有没有一种方法可以优化子集算法,该算法可以从最后一个计算点重新
我有一个包含 100 万个符号及其预期频率的表格。 我想通过为每个符号分配一个唯一(且前缀唯一)的可变长度位串来压缩这些符号的序列,然后将它们连接在一起以表示序列。 我想分配这些位串,以使编码序列的预
我是一名优秀的程序员,十分优秀!