zoukankan      html  css  js  c++  java
  • 细分生成球面三角网格(matlab)

    论文需要生成一个球面网格,最简单的想法是通过正多面体的细分来逼近球面。我们知道柏拉图多面体有五个,三个是由正三角形组成(正四,八,二十面体),一个由正方形组成(正六面体),一个由正五边形组成(正十二面体)。三角形的细分比较简单,而且保持拓扑可以连续细分。

    由于只是为了得到图片,就直接用matlab来实现了,方便,matlab中画着三角网格可以用trimesh或者patch

           Syntax

    trimesh(Tri,X,Y,Z)
    trimesh(Tri,X,Y,Z,C)
    trimesh(...'PropertyName',PropertyValue...) 

    patch(X,Y,C)
    patch(X,Y,Z,C)
    patch(FV)
    patch(...'PropertyName',propertyvalue...)
    patch('PropertyName',propertyvalue,...)

    但是都要用一个参数来指定每个三角面是由那些点组成(比如trimesh中的Tri)。我们用vertex储存点,face指定面由哪些点构成,细分的函数如下:

     1 function [vertex, face] = Subdivision(vertex, face)
     2 face_num = size(face, 1);
     3 vertex_num = size(vertex, 1);
     4 new_vertexs = zeros(face_num*3, 3);
     5 new_faces = zeros(face_num*3, 3);
     6 for i = 1 : face_num
     7     new_vertexs(3*(i-1)+1, :)=(vertex(face(i, 1), :)+vertex(face(i, 2), :))/2;
     8     new_vertexs(3*(i-1)+1, :)= new_vertexs(3*(i-1)+1, :)/norm(new_vertexs(3*(i-1)+1, :),2);
     9     new_vertexs(3*(i-1)+2, :)=(vertex(face(i, 2), :)+vertex(face(i, 3), :))/2;
    10     new_vertexs(3*(i-1)+2, :)= new_vertexs(3*(i-1)+2, :)/norm(new_vertexs(3*(i-1)+2, :),2);
    11     new_vertexs(3*(i-1)+3, :)=(vertex(face(i, 3), :)+vertex(face(i, 1), :))/2;
    12     new_vertexs(3*(i-1)+3, :)= new_vertexs(3*(i-1)+3, :)/norm(new_vertexs(3*(i-1)+3, :),2);
    13     new_faces(3*(i-1)+1, :) = [face(i, 1), vertex_num+3*(i-1)+1, vertex_num+3*(i-1)+3];
    14     new_faces(3*(i-1)+2, :) = [face(i, 2), vertex_num+3*(i-1)+2, vertex_num+3*(i-1)+1];
    15     new_faces(3*(i-1)+3, :) = [face(i, 3), vertex_num+3*(i-1)+3, vertex_num+3*(i-1)+2];
    16     face(i, :) = [vertex_num+3*(i-1)+1, vertex_num+3*(i-1)+2, vertex_num+3*(i-1)+3];
    17 end
    18 face = [face; new_faces];
    19 vertex = [vertex; new_vertexs];
    

    先选择正四面体来细分,以下是正四面体,以及细分了两次三次四次的结果:

    可以看到,用正四面体细分效果不太好,四次细分后虽然比较像球面,但是三角网格大小差别很大,因此改用正二十面体细分,获得正二十面体的数据比较麻烦,我在百度知道上找到一个matlab的代码,但是上面的细分函数要求细分对象是单位的,所以加上了平移和单位化。原来的face的顺序不一致,在画图的时候明暗会有问题,可以计算每个面的有向面积来判断点的顺序,不对的话反一下反向。

     1 function [vertexs, faces]=GetRegularIcosahedron
     2 t = 0:2*pi/5:(2*pi-2*pi/5);
     3 vertexs = [cos(t'),sin(t'),zeros(5,1)];
     4 t = t'+pi/5;
     5 a = 2*sin(pi/5);
     6 vertexs=[vertexs;cos(t),sin(t),a*sqrt(3)*ones(5,1)/2];
     7 h = sqrt(0.75*a^2-cos(pi/5)^2);
     8 vertexs = [0 0 -h;vertexs;0 0 a*sqrt(3)/2+h];
     9 vertexs = vertexs - [zeros(12,2), ones([12,1])*0.5];
    10 for i = 1 :12
    11     vertexs(i, :) = vertexs(i, :)/norm(vertexs(i, :), 2);
    12 end
    13 faces = [1 2 3
    14        1 3 4
    15        1 4 5
    16        1 5 6
    17        1 6 2
    18        2 3 7
    19        2 6 11
    20        2 7 11
    21        3 7 8
    22        3 4 8
    23        4 8 9
    24        4 5 9
    25        5 9 10
    26        5 6 10
    27        6 10 11
    28        7 8 12
    29        8 9 12
    30        9 10 12
    31        10 11 12
    32        7 11 12];
    33 change = 0;
    34 for i =1 : 20
    35     if(det([vertexs(faces(i, 1), :);
    36             vertexs(faces(i, 2), :);
    37             vertexs(faces(i, 3), :)])<0);
    38         change = change+1;
    39         faces(i, :) = [faces(i, 1);faces(i, 3);faces(i, 2)];
    40     end
    41 end
    

    以下是正二十面体以及细分一次两次三次的图像:

    这就比较漂亮了。

  • 相关阅读:
    [转载]Centos7.x下环境搭建(一)--yum方式安装mysql5.7
    树上分治
    [SPOJ2666]QTREE4
    [SPOJ375]QTREE
    [SPOJ1825]FTOUR2
    [POJ1741]Tree
    [LG-P5350]序列
    [COCI 2014/2015 #3]KAMIONI
    [SHOI2014]神奇化合物
    [GXOI/GZOI2019]旧词
  • 原文地址:https://www.cnblogs.com/yezhangxiang/p/1991323.html
Copyright © 2011-2022 走看看