三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码(转载)
转载: https://www.cnblogs.com/shushen/p/5251070.html
下图描述了细分的基本思想,每次细分都是在每条边上插入一个新的顶点,可以看到随着细分次数的增加,折线逐渐变成一条光滑的曲线。曲面细分需要有几何规则和拓扑规则,几何规则用于计算新顶点的位置,拓扑规则用于确定新顶点的连接关系。下面介绍两种网格细分方法:Catmull-Clark细分和Loop细分。
Catmull-Clark subdivision:
Catmull-Clark细分是一种四边形网格的细分法则,每个面计算生成一个新的顶点,每条边计算生成一个新的顶点,同时每个原始顶点更新位置。下图为Catmull-Clark细分格式的细分掩膜,对于新增加的顶点位置以及原始顶点位置更新规则如下:
1.网格内部F-顶点位置:
设四边形的四个顶点为v0、v1、v2、v3,则新增加的顶点位置为v = 1/4*(v0 + v1 + v2 + v3)。
2.网格内部V-顶点位置:
设内部顶点v0的相邻点为v1、v2,…,v2n,则该顶点更新后位置为
,其中α、β、γ分别为α = 1 - β - γ。
3.网格边界V-顶点位置:
设边界顶点v0的两个相邻点为v1、v2,则该顶点更新后位置为v = 3/4*v0 + 1/8*(v1 + v2)。
4.网格内部E-顶点位置:
设内部边的两个端点为v0、v1,与该边相邻的两个四边形顶点分别为v0、v1、v2、v3和v0、v1、v4、v5,则新增加的顶点位置为v = 1/4*(v0 + v1 + vf1 + vf2) = 3/8*(v0 + v1) + 1/16*(v2 + v3 + v4 + v5)。
5.网格边界E-顶点位置:
设边界边的两个端点为v0、v1,则新增加的顶点位置为v = 1/2*(v0 + v1)。
效果:
function [VV, FF, S] = CC_subdivision(V, F, iter)
% Catmull_Clark subdivision
if ~exist('iter','var')
iter = 1;
end
VV = V;
FF = F; for i = 1:iter
nv = size(VV,1);
nf = size(FF,1); O = outline(FF); original = 1:nv;
boundary = O(:,1)';
interior = original(~ismember(original, boundary)); no = length(original);
nb = length(boundary);
ni = length(interior); %% Sv
Etmp = sort([FF(:,1) FF(:,2);FF(:,2) FF(:,3);FF(:,3) FF(:,4);FF(:,4) FF(:,1)],2);
[E, ~, idx] = unique(Etmp, 'rows'); Aeven = sparse([E(:,1) E(:,2)], [E(:,2) E(:,1)], 1, no, no);
Aodd = sparse([FF(:,1) FF(:,2)], [FF(:,3) FF(:,4)], 1, no, no);
Aodd = Aodd + Aodd'; val_even = sum(Aeven,2);
beta = 3./(2*val_even); val_odd = sum(Aodd,2);
gamma = 1./(4*val_odd); alpha = 1 - beta - gamma; Sv = sparse(no,no);
Sv(interior,:) = ...
sparse(1:ni, interior, alpha(interior), ni, no) + ...
bsxfun(@times, Aeven(interior,:), beta(interior)./val_even(interior)) + ...
bsxfun(@times, Aodd(interior,:), gamma(interior)./val_odd(interior));
Sboundary = ...
sparse([O(:,1);O(:,2)],[O(:,2);O(:,1)],1/8,no,no) + ...
sparse([O(:,1);O(:,2)],[O(:,1);O(:,2)],3/8,no,no);
Sv(boundary,:) = Sboundary(boundary,:); %% Sf
Sf = 1/4 .* sparse(repmat((1:nf)',1 ,4), FF, 1);
i0 = no + (1:nf)'; %% Se
flaps = sparse([idx;idx], ...
[FF(:,3) FF(:,4);FF(:,4) FF(:,1);FF(:,1) FF(:,2);FF(:,2) FF(:,3)], ...
1);
onboundary = (sum(flaps,2) == 2);
flaps(onboundary,:) = 0; ne = size(E,1);
Se = sparse( ...
[1:ne 1:ne]', ...
[E(:,1); E(:,2)], ...
[onboundary;onboundary].*1/2 + ~[onboundary;onboundary].*3/8, ...
ne, ...
no) + ...
flaps*1/16; %% new faces & new vertices
i1 = no + nf + (1:nf)';
i2 = no + 2*nf + (1:nf)';
i3 = no + 3*nf + (1:nf)';
i4 = no + 4*nf + (1:nf)'; FFtmp = [i0 i4 FF(:,1) i1; ...
i0 i1 FF(:,2) i2; ...
i0 i2 FF(:,3) i3; ...
i0 i3 FF(:,4) i4]; reidx = [(1:no)'; no+(1:nf)'; no+nf+idx];
FF = reidx(FFtmp); S = [Sv; Sf; Se];
VV = S*VV;
end
end

Loop subdivision:
Loop细分是一种三角形网格的细分法则,它按照1-4三角形分裂,每条边计算生成一个新的顶点,同时每个原始顶点更新位置。下图为Loop细分格式的细分掩膜,对于新增加的顶点位置以及原始顶点位置更新规则如下:
1.网格内部V-顶点位置:
设内部顶点v0的相邻点为v1、v2,…,vn,则该顶点更新后位置为
,其中
。
2.网格边界V-顶点位置:
设边界顶点v0的两个相邻点为v1、v2,则该顶点更新后位置为v = 3/4*v0 + 1/8*(v1 + v2)。
3.网格内部E-顶点位置:
设内部边的两个端点为v0、v1,相对的两个顶点为v2、v3,则新增加的顶点位置为v = 3/8*(v0 + v1) + 1/8*(v2 + v3)。
4.网格边界E-顶点位置:
设边界边的两个端点为v0、v1,则新增加的顶点位置为v = 1/2*(v0 + v1)。
效果:

三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码(转载)的更多相关文章
- 三维网格精简算法(Quadric Error Metrics)附源码
在计算机图形应用中,为了尽可能真实呈现虚拟物体,往往需要高精度的三维模型.然而,模型的复杂性直接关系到它的计算成本,因此高精度的模型在几何运算时并不是必须的,取而代之的是一个相对简化的三维模型,那么如 ...
- 三维网格精简算法(Quadric Error Metrics)附源码(转载)
转载: https://www.cnblogs.com/shushen/p/5311828.html 在计算机图形应用中,为了尽可能真实呈现虚拟物体,往往需要高精度的三维模型.然而,模型的复杂性直接 ...
- 网格测地线算法(Geodesics in Heat)附源码
测地线又称为大地线,可以定义为空间曲面上两点的局部最短路径.测地线具有广泛的应用,例如在工业上测地线最短的性质就意味着最优最省,在航海和航空中,轮船和飞机的运行路线就是测地线.[Crane et al ...
- 卡通图像变形算法(Moving Least Squares)附源码
本文介绍一种利用移动最小二乘法来实现图像变形的方法,该方法由用户指定图像中的控制点,并通过拖拽控制点来驱动图像变形.假设p为原图像中控制点的位置,q为拖拽后控制点的位置,我们利用移动最小二乘法来为原图 ...
- 基于Zlib算法的流压缩、字符串压缩源码
原文:基于Zlib算法的流压缩.字符串压缩源码 Zlib.net官方源码demo中提供了压缩文件的源码算法.处于项目研发的需要,我需要对内存流进行压缩,由于zlib.net并无相关文字帮助只能自己看源 ...
- 三维网格细分算法(Catmull-Clark subdivision & Loop subdivision)附源码
下图描述了细分的基本思想,每次细分都是在每条边上插入一个新的顶点,可以看到随着细分次数的增加,折线逐渐变成一条光滑的曲线.曲面细分需要有几何规则和拓扑规则,几何规则用于计算新顶点的位置,拓扑规则用于确 ...
- SM4密码算法(附源码)
SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳→_→:http://www.cnnic.NET.cn/jscx/mixbz/sm4/ 具体的密码标准和算法官方有非常 ...
- arcgis api 3.x for js 共享干货系列之一自写算法实现地图量算工具(附源码下载)
0.内容概览 Geometry 地图服务方式实现地图距离以及面积的量算,简单描述 arcgis api 提供的接口类 geometryEngine 实现地图距离以及面积的量算,简单描述 自定义距离以及 ...
- sm4算法(附源码、测试代码)
from:http://blog.csdn.net/mao0514/article/details/52930944 SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳 ...
随机推荐
- 如何让Python爬虫一天抓取100万张网页
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 王平 源自:猿人学Python PS:如有需要Python学习资料的 ...
- kali linux maltego-情报收集工具
Maltego是一个交互式数据挖掘工具,它为链接分析呈现有向图.该工具用于在线调查,以发现互联网上各种来源的信息片段之间的关系. 注册Maltego账号,注册地址:https://www.paterv ...
- ICMP重定向 Redirect netwox libpcap netwag
搭建环境 两台虚拟机. 攻击者:192.168.1.8 被攻击者:192.168.1.9 网络配置 主机均采用DHCP 如果没有路由器,可以使用NAT模式来做 攻击者配置 打开转发数据包功能 # su ...
- 剑指offer 12:二进制中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 解法一:设置标志为flag=1,逐个位移至不同位置,比较是否为1. C++实现 class Solution { publi ...
- javascript 生成指定范围内的随机数
js 生成任意2个区间内的随机整数,js 生成两个数之间的随机数 function random(m,n) { return Math.floor(Math.random() * (n - m)) + ...
- Linux的启动过程的分析
Linux的启动过程 Linux系统从启动大哦提供服务的基本过程为:首先机器家电,然后通过MBR或者UEFI装载GRUB,再启动内核,再由内核启动服务,最后开始对外服务 CentOS7要经历四个主要阶 ...
- OpenGL实例:纹理映射
OpenGL实例:纹理映射 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:计算机图形学 1. 介绍 用于指定一维.二维和三维纹理的函数分别 ...
- nginx配置中root和alias的区别
例:访问http://127.0.0.1/download/*这个目录时候让他去/opt/app/code这个目录找. 方法一(使用root关键字): location / { root /usr/s ...
- FPDF_CloseDocument(doc);
FPDF_CloseDocument(doc); 创建不加载就会段错误 必须创建 doc = FPDF_CreateNewDocument();
- 3.jenkins--- 配置
一 .系统配置 Mange jenkins -------> configure system 并发数量可以调整成10个, Usage(使用): 指允许运行绑定到本机的job ,这个 ...