MATLAB中二十面体上采样:新增边中点顶点后重构面的技术问题
解决MATLAB中二十面体上采样的面重构问题
嘿,我之前折腾过网格细分的活儿,二十面体的上采样面重构其实不用纠结最近邻——它有固定的拆分规则,比找最近邻靠谱多了!核心逻辑就是把每个原始三角形面拆成4个新的小三角形面,完全不用靠距离计算,按边中点的连接关系来就行。
先搞懂拆分规则
二十面体的每个原始面都是三角形,假设某个面的三个顶点是V1、V2、V3,对应的三条边中点是M12(V1-V2中点)、M23(V2-V3中点)、M31(V3-V1中点)。那这个原始面要拆成4个新面:
- 面1:
V1→M12→M31 - 面2:
V2→M23→M12 - 面3:
V3→M31→M23 - 面4:
M12→M23→M31
MATLAB代码实现步骤
假设你已经完成了这些准备工作:
original_vertices:12×3的矩阵,存储二十面体原始12个顶点的坐标midpoints:30×3的矩阵,存储30条边中点的坐标(二十面体共30条边,每个面3条,20个面去重后就是30条)original_faces:20×3的矩阵,存储原始20个面的顶点索引(每行对应一个面的三个原始顶点序号)
1. 合并顶点并构建边到中点的映射
首先把原始顶点和中点合并成完整的顶点列表,然后建立一个映射,方便快速找到每条边对应的中点索引:
% 合并原始顶点和中点,新顶点总数是12+30=42 vertices = [original_vertices; midpoints]; % 构建边到中点索引的映射(用有序键避免重复) edge_to_midpoint = containers.Map(); % 先从原始面中提取所有边并去重 all_edges = []; for i = 1:size(original_faces,1) v1 = original_faces(i,1); v2 = original_faces(i,2); v3 = original_faces(i,3); % 每条边按小索引在前的顺序存储,避免重复 all_edges = [all_edges; sort([v1,v2]); sort([v2,v3]); sort([v3,v1])]; end % 去重得到唯一的30条边 all_edges = unique(all_edges, 'rows'); % 给每条边绑定对应的中点索引 for k = 1:size(all_edges,1) edge_key = all_edges(k,:); edge_to_midpoint(edge_key) = 12 + k; % 原始12个顶点,中点从13开始计数 end
2. 遍历原始面生成新面
接下来逐个处理原始面,按照拆分规则生成4个新面:
new_faces = []; for i = 1:size(original_faces,1) v1 = original_faces(i,1); v2 = original_faces(i,2); v3 = original_faces(i,3); % 获取三个边对应的中点索引 m12 = edge_to_midpoint(sort([v1,v2])); m23 = edge_to_midpoint(sort([v2,v3])); m31 = edge_to_midpoint(sort([v3,v1])); % 添加四个新面到结果中 new_faces = [new_faces; v1, m12, m31]; new_faces = [new_faces; v2, m23, m12]; new_faces = [new_faces; v3, m31, m23]; new_faces = [new_faces; m12, m23, m31]; end
验证结果
完成后你可以检查这几个数值是否符合预期:
- 新面的数量应该是20×4=80个,即
size(new_faces,1)等于80 - 总顶点数是42个,即
size(vertices,1)等于42
用这个方法生成的网格绝对是规整的上采样二十面体,比靠最近邻连接靠谱多了——毕竟最近邻可能会把中点和不相邻的顶点连起来,破坏网格结构。
内容的提问来源于stack exchange,提问作者Poelie
相关产品推荐
相关产品推荐

