精华内容
下载资源
问答
  • mesh函数

    2018-03-12 16:11:00
    [t,W]=meshgrid([2:0.2:7],[0:pi/6:3*pi]);... mesh(t,W/pi,real(Gs)); axis([2 7 0 3 -1/(sqrt(2*pi)*a) 1/(sqrt(2*pi)*a)]); 转载于:https://www.cnblogs.com/xiaoxuesheng993/p/8549867.html

    [t,W]=meshgrid([2:0.2:7],[0:pi/6:3*pi]); %设置时-频相平面网格点
    Gs1=(1/(sqrt(2*pi)*a))*exp(-0.5*abs((t1-t)/a).^m).*exp(-i*W*t1);
    Gs2=(1/(sqrt(2*pi)*a))*exp(-0.5*abs((t2-t)/a).^m).*exp(-i*W*t2);
    Gs=Gs1+Gs2;
    subplot(2,3,1);
    %绘制Gs的实部三维网格立体图
    mesh(t,W/pi,real(Gs));

    axis([2 7 0 3 -1/(sqrt(2*pi)*a) 1/(sqrt(2*pi)*a)]);

    转载于:https://www.cnblogs.com/xiaoxuesheng993/p/8549867.html

    展开全文
  • 功能生成由X,Y和Z指定的网线面,由C指定的颜色的三维网格图。网格图是作为视点由view(3)设定的surface图形对象。曲面的颜色与背景颜色相同...用法 mesh(X,Y,Z) 画出颜色由c指定的三维网格图,所以和曲面的高度相匹...

    功能

    生成由X,Y和Z指定的网线面,由C指定的颜色的三维网格图。网格图是作为视点由view(3)设定的surface图形对象。曲面的颜色与背景颜色相同(当要动画显示不透明曲面时,这时可用命令hidden控制),或者当画一个标准的可透视的网线图时,曲面的颜色就没有(命令shading控制渲染模式)。当前的色图决定线的颜色。

    用法 mesh(X,Y,Z) 画出颜色由c指定的三维网格图,所以和曲面的高度相匹配,

    1.若X与Y均为向量,length(X)=n,length(Y)=m,而[m,n]=size(Z),空间中的点

    (X(j),Y(I),Z(I,j)) 为所画曲面网线的交点,分别地,X对应于z的列,Y对应于z的行。

    2.若X与Y均为矩阵,则空间中的点 (X(I,j),Y(I,j),Z(I,j))为所画曲面的网线的交点。

    mesh(Z) 由[n,m] = size(Z)得,X =1:n与Y=1:m,其中z为定义在矩形划分区域上的单值函数。

    mesh(…,C)

    用由矩阵c指定的颜色画网线网格图。Matlab对矩阵c中的数据进行线性处理,以便从当前色图中获得有用的颜色。

    mesh(…,PropertyName’,PropertyValue, …)

    对指定的属性PropertyName设置属性值PropertyValue,可以在同一语句中对多个属性进行设置。

    h = mesh(…) 返回surface图形对象句柄。

    运算规则:

    1.数据X,Y和z的范围,或者是对当前轴的XLimMode,YLimMode和ZLimMode属性的设置决定坐标轴的范围。命令aXis可对这些属性进行设置。

    2.参量c的范围,或者是对当前轴的Clim和ClimMode属性的设置(可用命令caxis进行设置),决定颜色的刻度化程度。刻度化颜色值作为引用当前色图的下标。

    a4c26d1e5885305701be709a3d33442f.png3.网格图显示命令生成由于把z的数据值用当前色图表现出来的颜色值。Matlab会自动用最大值与最小值计算颜色的范围(可用命令caxis

    auto进行设置),最小值用色图中的第一个颜色表现,最大值用色图中的最后一个颜色表现。Matlab会对数据的中间值执行一个线性变换,使数据能在当前的范围内显示出来。

    例7-31

    >>[X,Y] = meshgrid(-3:.125:3);

    >>Z = peaks(X,Y);

    >>mesh(X,Y,Z);

    展开全文
  • Matlab绘制三维图mesh函数:绘制网格图例1例2mashc函数mashz函数 mesh函数:绘制网格图 mesh(x, y, z)的用法,x是n维向量,y是m维向量,z是m*n的矩阵 X = [1,2,4] Y = [3,5] Z = [4,8,10;5,9,13] mesh(X,Y,Z) % (X(j...

    mesh函数:绘制网格图

    mesh(x, y, z)的用法,x是n维向量,y是m维向量,z是m*n的矩阵

    X = [1,2,4]
    Y = [3,5]
    Z = [4,8,10;5,9,13]
    mesh(X,Y,Z)  % (X(j), Y(i), Z(i,j))是线框网格线的交点的坐标
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    

    在这里插入图片描述

    Z = [4,8,10;5,9,13]
    mesh(Z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    % 等价于
    X = 1:3
    Y = 1:2
    Z = [4,8,10;5,9,13]
    mesh(X,Y,Z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    

    在这里插入图片描述

    X = [1,10,4]
    Y = [3,5]
    Z = [4,8,10;5,9,13]
    mesh(X,Y,Z)
    alpha(0.8) % 设置透明度0-1之间
    hidden off  % 可以看到背部的图像,不会遮挡(默认是看不到的)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    

    在这里插入图片描述

    % 如果xyz都是m*n的矩阵
    X = [1,2,4;1,2,4]   
    %  X = [1,2,4;1,2,5] 
    Y = [3,3,3;5,5,5]
    Z = [4,8,10;5,9,13]
    mesh(X,Y,Z) % (X(i,j), Y(i,j), Z(i,j))是线框网格线的交点的坐标
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    

    在这里插入图片描述

    例1

    例题1:绘制 z = x2 - y 2的图像 ,其中x和y都位于[0,5]之间

    % linspace是Matlab中的一个函数,用于产生给定范围内指定数量的点数,相邻数据跨度相同,并返回一个行向量。
    % 调用方法:linspace(x1,x2,N)
    % 功能:用于产生x1,x2之间的N点行向量,相邻数据跨度相同。其中x1、x2、N分别为起始值、终止值、元素个数。
    n = 11;
    tem = linspace(0,5,n);  % 将[0,5]这个区间等分为n个点(等差数列的形式)
    x = repmat(tem,n,1);
    y = repmat(tem',1,n);
    z = x.^2 - y.^2;    % 要使用点运算符号哦~
    mesh(x,y,z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
    

    在这里插入图片描述

    例2

    z = sin(sqrt(x2+y2))/sqrt(x2+y2)的图形,其中x和y都位于[-5,5]之间

    [x,y] = meshgrid(-5:0.5:5);  % 快速生成网格所需的数据
    tem = sqrt(x.^2+y.^2)+1e-12;   % tem=sqrt(x.^2+y.^2);   % 在后面加上一个非常非常小的数字: 1e-12 = 10^(-12) ,当然你也可以单独找到值为0的地方对其修改
    z = sin(tem)./tem;  % 如果不对tem处理,那么z的最中间的一个值 0/0 = NaN
    mesh(x,y,z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
    

    在这里插入图片描述

    mashc函数

    mashc函数可以绘画出等高线

    % 在上一个代码的条件下
    meshc(x,y,z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
    

    在这里插入图片描述

    mashz函数

    meshz函数:除了mesh函数图形外,还在xy平面上绘制曲面的底座。

    meshz(x,y,z)
    xlabel('x轴');  ylabel('y轴');  zlabel('z轴');  % 加上坐标轴的标签
    axis vis3d % 冻结屏幕高宽比,使得一个三维对象的旋转不会改变坐标轴的刻度显示
    

    在这里插入图片描述

    展开全文
  • Openmesh函数库设计及与CGAL的对比

    千次阅读 2015-09-11 12:44:38
    Openmesh函数库设计及与CGAL的对比 在前面写了CGAL模板类设计的一些思路,这里尝试写一点openmesh库的设计思路以及和CGAL的对比.虽然OPENMESH代码量小,不过还是只看懂皮毛,很大部分算是翻译帮助文档吧,主要...

    Openmesh函数库设计及与CGAL的对比

    http://www.cnblogs.com/rocketfan/category/261367.html

    在前面写了CGAL模板类设计的一些思路,这里尝试写一点openmesh库的设计思路以及和CGAL的对比.虽然OPENMESH代码量小,不过还是只看懂皮毛,很大部分算是翻译帮助文档吧,主要用作笔记,

    方便以后继续分析。

    • 相对CGAL的功能强大和庞大(包含大量计算几何算法的实现),Openmesh显得更加小巧轻量化,它更专注在三维网格数据结构的表示,

    外围也提供在此基础上的网格简化算法及框架,网格细分等等应用算法。

    • 同样是在实现上大量依赖模版类,但是Openmesh源代码的可读性更好些(很大程度上也因为它的小巧,CGAL实现文件太多了,层次结构复杂),
      在提供给用户的类,
      Openmesh的设计是尽可能少的让用户去知晓模版参数,也就是除非必须,
    尽量减少模版参数甚至不带模板参数。
    • Openmesh设计的一个亮点是用户可以在程序运行时动态为网格添加属性和删除属性

      这个功能很赞的。一个典型的应用,可以写一个对网格进行光顺的smooth算法
    template <class Mesh> class SmootherT
    {
    public: 
    
      typedef typename Mesh::Point            cog_t;
      typedef OpenMesh::VPropHandleT< cog_t > Property_cog; 
    
    public: 
    
      // construct with a given mesh
      SmootherT(Mesh& _mesh) 
        : mesh_(_mesh)
      { 
        mesh_.add_property( cog_ );
      } 
    
      ~SmootherT()
      {
        mesh_.remove_property( cog_ );
      } 
    
    
    // smooth mesh _iterations times
      void smooth(unsigned int _iterations)
      {
        for (unsigned int i=0; i < _iterations; ++i)
        {
          std::for_each(mesh_.vertices_begin(), 
                        mesh_.vertices_end(), 
                        ComputeCOG(mesh_, cog_)); 
    
          std::for_each(mesh_.vertices_begin(), 
                        mesh_.vertices_end(), 
                        SetCOG(mesh_, cog_));
        }
      } 
    
    private: 
    
      //--- private classes --- 
    
      class ComputeCOG
      {
      public:
        ComputeCOG(Mesh& _mesh, Property_cog& _cog) 
          : mesh_(_mesh), cog_(_cog)
        {} 
    
        void operator()(typename Mesh::Vertex& _v)
        {
          typename Mesh::VertexHandle      vh( mesh_.handle(_v) );
          typename Mesh::VertexVertexIter  vv_it;
          typename Mesh::Scalar            valence(0.0);
          mesh_.property(cog_, vh) = typename Mesh::Point(0.0, 0.0, 0.0); 
    
          for (vv_it=mesh_.vv_iter(vh); vv_it; ++vv_it)
          {
            mesh_.property(cog_, vh) += mesh_.point( vv_it );
            ++valence;
          } 
    
          mesh_.property(cog_, mesh_.handle(_v) ) /= valence;
        } 
    
      private:
        Mesh&         mesh_;
        Property_cog& cog_;
      }; 
    
      class SetCOG
      {
      public:
        SetCOG(Mesh& _mesh, Property_cog& _cog) 
          : mesh_(_mesh), cog_(_cog)
        {} 
    
        void operator()(typename Mesh::Vertex& _v)
        {
          typename Mesh::VertexHandle vh(mesh_.handle(_v)); 
    
          if (!mesh_.is_boundary(vh))
            mesh_.set_point( vh, mesh_.property(cog_, vh) );
        } 
    
      private: 
    
        Mesh&         mesh_;
        Property_cog& cog_;
      };
    
      //--- private elements --- 
    
      Mesh&        mesh_;
      Property_cog cog_;
    };

    当用户希望对其所持有的mesh做光顺处理的时候,就可以交给SmooterT类来完成。

    // smoothing mesh argv[1] times
      SmootherT<MyMesh> smoother(mesh);
      smoother.smooth(atoi(argv[1]));
    这个实例也显示了openmesh和STL的结合,foreach,函数对象的使用。
    最酷的还是SmootherT类会给传入的mesh对象添加顶点参数,即每一个顶点添加一个cog_,记录光顺后的位置,最后
    所有顶点都计算好,原顶点位置可以改变的时候再赋值给原顶点。当完成了smooth操作后析构函数自动又把这个属性从mesh中删除,这样对于用户而言这些就是透明的,对用户而言mesh只是被光顺。
    这种实现很漂亮,如果不采用动态添加属性的话,用户就需要在定义自己的mesh的时候考虑到由于光顺操作的需要,添加一个cog_属性,但是当光顺完不需要这个属性的时候,该属性也还会存在,
    占用内存。
    如果不想这样,那也只好在调用smooth的时候建立一个一维数组,大小和顶点数目相同,将属性值记录到该数组中,不用了删除数组占用空间。但是这样的可读性就差了。
    另外一个应用,点法向的计算。(法向属性常规属性,用户也可以自由添加删除,但是调用函数和用户自定义属性有所不同)
    首先可以给网格添加顶点属性即
    mesh.request_vertex_normals(); 

    因为计算顶点法向是需要面法相的(所有相邻面法向的和),所以我们需要添加面法向属性

      mesh.request_face_normals(); 
    
    // let the mesh update the normals
       mesh.update_normals(); 
    
    // dispose the face normals, as we don't need them anymore不需要面法向了就去掉它
       mesh.release_face_normals();


    相当的灵活。

    • CGAL的网格模型数据结构部分(半边数据结构)的架构。

     

    image

    半边结构示意图。半边结构非常适合描述网格结构,因为它可以方便的改变网格拓扑形态,如删除边,分裂边等待.

    image

    上图为CGAL中的类结构设计.

    image

    各个模块关系.

    默认的顶点,边,面

    image

    这里我们只关心,最上层的Polyhedron
    用户使用默认的Polyhedron
    #include <CGAL/Simple_cartesian.h>
    #include <CGAL/Polyhedron_3.h>
    #include <iostream>
    
    typedef CGAL::Simple_cartesian<double>     Kernel;
    typedef Kernel::Point_3                    Point_3;
    typedef CGAL::Polyhedron_3<Kernel>         Polyhedron;
    typedef Polyhedron::Vertex_iterator        Vertex_iterator;
    
    int main() {
        Point_3 p( 1.0, 0.0, 0.0);
        Point_3 q( 0.0, 1.0, 0.0);
        Point_3 r( 0.0, 0.0, 1.0);
        Point_3 s( 0.0, 0.0, 0.0);
    
        Polyhedron P;
        P.make_tetrahedron( p, q, r, s);
        CGAL::set_ascii_mode( std::cout);
        for ( Vertex_iterator v = P.vertices_begin(); v != P.vertices_end(); ++v)
            std::cout << v->point() << std::endl;
        return 0;
    }
    默认情况下用的是HalfedgeDS_defualt,是基于list的,用户可以选择使用基于vector实现的半边结构。

    基于vector的半边结构适合静态的网格结构。

    typedef CGAL::Polyhedron_3< Traits, 
                                CGAL::Polyhedron_items_3, 
                                CGAL::HalfedgeDS_default>      Polyhedron;
    #include <CGAL/Cartesian.h>
    #include <CGAL/HalfedgeDS_vector.h>
    #include <CGAL/Polyhedron_3.h>
    #include <iostream>
    
    typedef CGAL::Cartesian<double>                        Kernel; //CGAL用Traits(Kernel)表示采用的数据精度类型如这里的Cartesian<double> 
    typedef Kernel::Point_3                                Point_3;
    typedef CGAL::Polyhedron_3< Kernel,
                                CGAL::Polyhedron_items_3,
                                CGAL::HalfedgeDS_vector>   Polyhedron;  //使用基于vector实现的半边结构
    
    int main() {
        Point_3 p( 1.0, 0.0, 0.0);
        Point_3 q( 0.0, 1.0, 0.0);
        Point_3 r( 0.0, 0.0, 1.0);
        Point_3 s( 0.0, 0.0, 0.0);
    
        Polyhedron P;    // alternative constructor: Polyhedron P(4,12,4);
        P.make_tetrahedron( p, q, r, s);
        CGAL::set_ascii_mode( std::cout);
        std::copy( P.points_begin(), P.points_end(),
    	       std::ostream_iterator<Point_3>( std::cout, "\n"));
        return 0;
    }
    用户如何定义自己的特定的mesh顶点,边,面属性?
    #include <CGAL/Simple_cartesian.h>
    #include <CGAL/IO/Color.h>
    #include <CGAL/Polyhedron_3.h>
    
    // A face type with a color member variable.
    template <class Refs>
    struct My_face : public CGAL::HalfedgeDS_face_base<Refs> {
        CGAL::Color color;
    };
    
    // An items type using my face.
    struct My_items : public CGAL::Polyhedron_items_3 {
        template <class Refs, class Traits>
        struct Face_wrapper {
            typedef My_face<Refs> Face;
        };
    };
    
    typedef CGAL::Simple_cartesian<double>        Kernel;
    typedef CGAL::Polyhedron_3<Kernel, My_items>  Polyhedron;
    typedef Polyhedron::Halfedge_handle           Halfedge_handle;
    
    int main() {
        Polyhedron P;
        Halfedge_handle h = P.make_tetrahedron();
        h->facet()->color = CGAL::RED;
        return 0;
    }

    注意这种方式虽然也算方便,但是对用户而言其实他不关系Refs,Traits,最好应该能够将这些模板参数去掉,尽量少的让用户接触模板参数。Openmesh做到了这一点。

    具体上面的方法怎么起到能够让程序选择使用用户自定义的结构可以看我前面关于CGAL模板类设计的文章。

    • openmesh,的设计

      • 考虑能够提供动态存储管理的基于array存储的网格。
      • 考虑提供普通的半边网格结构,和特殊的三角网格半边结构(更快,专为三角网格优化)
      • 考虑能够兼容诸如quad tree的网格表示方法,用以实现快速的细分。也可定义其它的kernal以便实现诸如允许非流形存在的网格结构。
    • Openmesh中的接口:

    网格提供的可选参数

    • Face Type

            什么样的Mesh普通的还是三角网格Mesh?

    • Kernal(WELL当前版本的OPENMESH只提供基于ARRAY(std::vector)的kernal,当然kernal还是可选)

           选择采用double linked list 还是 array作为底层的存储方式?container

    • Traits

            (注意这里和CGAL的Traits表示意义不同那里是表示采用什么精度类型的数据等等,一般不需要过多考虑)

            这里通过这个参数,

                      用户可以定义它自己的顶点类型,面,边,加入自己需要的属性,方法。

            以及修改坐标的数据类型如double , float,三维坐标还是二维坐标。

     

    Openmesh的用户接口API等待更加友好,可以对比下

    • 使用默认的网格结构

               使用默认的普通网格,array based

          typedef OpenMesh::PolyMesh_ArrayKernelT<>  MyMesh;
          使用默认的三角网格,array based
          typedef OpenMesh::TriMesh_ArrayKernelT<>  MyMesh;
    • 用户自定义自己的traits
    // Define my personal traits
    struct MyTraits : OpenMesh::DefaultTraits
    {
      // Let Point and Normal be a vector of doubles
      typedef OpenMesh::Vec3d Point;   //Point的类型被定义为3维double类型
      typedef OpenMesh::Vec3d Normal; 
    
      // Already defined in OpenMesh::DefaultTraits
      // HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge );
      // Uncomment next line to disable attribute PrevHalfedge
      // HalfedgeAttributes( OpenMesh::Attributes::None );
      //
      // or
      //
      // HalfedgeAttributes( 0 );
    }; 
    
    #endif 
    
    // Define my mesh with the new traits!
    typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits>  MyMesh; 
    
    // ------------------------------------------------------------------ main ---- 
    
    
      MyMesh mesh; 
    
      // Just make sure that point element type is double
      if ( typeid( OpenMesh::vector_traits<MyMesh::Point>::value_type ) 
           != typeid(double) )
      {
        std::cerr << "Ouch! ERROR! Data type is wrong!\n";
        return 1;
      }
    
    //另外一个例子
    
    struct MyTraits : public OpenMesh::DefaultTraits
    {
      // store barycenter of neighbors in this member
      VertexTraits
      {
      private:
        Point  cog_;
      public:
    
        VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { }
    
        const Point& cog() const { return cog_; }
        void set_cog(const Point& _p) { cog_ = _p; }
      };
    };
    
    #endif
    
    typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits>  MyMesh;
    typedef OpenMesh::TriMesh_ArrayKernelT<>          MyMesh2;
          注意和CGAL的不同这里用户自定义traits更加简单友好,没有任何的模板参数。
          以前旧版本的openmesh里面的vertex还要写成下面的形式,有模板参数,那么现在这个是如何实现的呢?
     
          template <class Base> class VertexT: public Base

     

    OPENMESH同样运用了与CGAL相同的利用前置声明的技术解决类型依赖问题,见

    Since the handle types depend on the containers used by the mesh
    kernel (e.g. a VertexHandle may be a Vertex* or an int), the
    kernel itself depends on the mesh items (in order to construct the
    handle types), and the items require the handles (a vertex must store
    a halfedge handle), we have to use template forward declarations
    to get “safe” handle types (see [7]). Using this technique, the item
    types know each other and their respective handle types, thereby
    avoiding to use and cast void pointers. This also enables us to use
    the handles types in the traits classes, e.g. if the face type should
    contain a vertex handle。

     

    不同的mesh将会是不同的类型,为了让mesh算法能够为所有类型的mesh服务,采用了泛型方法,将Mesh类型作为所有

    算法的一个模板参数。

    As we have seen, we use a custom–tailored mesh for each application.
    All these meshes will be different C++ types. If we want
    to design algorithms operating on all of these mesh types, we either
    have to derive all meshes from a common virtual base class, or do
    it the STL way and use generic programming methods. Since virtual
    functions / classes lead to a certain overhead in space and time,
    we have chosen the generic approach: every algorithm gets the type
    Mesh in form of a template parameter.

     

    对比一下CGAL看一下Openmesh是如何定义顶点,边和面的。

    /// Definition of mesh items for use in the ArrayKernel
    struct ArrayItems
    {
    
      //------------------------------------------------------ internal vertex type
    
      /// The vertex item
      class Vertex
      {
        friend class ArrayKernel;
        HalfedgeHandle  halfedge_handle_;
      };
    
    
      //---------------------------------------------------- internal halfedge type
    
    #ifndef DOXY_IGNORE_THIS
      class Halfedge_without_prev
      {
        friend class ArrayKernel;
        FaceHandle      face_handle_;
        VertexHandle    vertex_handle_;
        HalfedgeHandle  next_halfedge_handle_;
      };
    #endif
    
    #ifndef DOXY_IGNORE_THIS
      class Halfedge_with_prev : public Halfedge_without_prev
      {
        friend class ArrayKernel;
        HalfedgeHandle  prev_halfedge_handle_;
      };
    #endif
    
      //TODO: should be selected with config.h define
      typedef Halfedge_with_prev                Halfedge;
      typedef GenProg::Bool2Type<true>          HasPrevHalfedge;
    
      //-------------------------------------------------------- internal edge type
    #ifndef DOXY_IGNORE_THIS
      class Edge
      {
        friend class ArrayKernel;
        Halfedge  halfedges_[2];
      };
    #endif
    
      //-------------------------------------------------------- internal face type
    #ifndef DOXY_IGNORE_THIS
      class Face
      {
        friend class ArrayKernel;
        HalfedgeHandle  halfedge_handle_;
      };
    };

    //上面都用到了handle,

    //那么handle是怎么定义的呢?

    class BaseHandle;
    /// Handle for a vertex entity
    struct VertexHandle : public BaseHandle
    {
      explicit VertexHandle(int _idx=-1) : BaseHandle(_idx) {}
    };
    
    
    /// Handle for a halfedge entity
    struct HalfedgeHandle : public BaseHandle
    {
      explicit HalfedgeHandle(int _idx=-1) : BaseHandle(_idx) {}
    };
    
    
    /// Handle for a edge entity
    struct EdgeHandle : public BaseHandle
    {
      explicit EdgeHandle(int _idx=-1) : BaseHandle(_idx) {}
    };
    
    
    /// Handle for a face entity
    struct FaceHandle : public BaseHandle
    {
      explicit FaceHandle(int _idx=-1) : BaseHandle(_idx) {}
    };
     
    //一个具体的kernel如何定义的呢

    class ArrayKernel : public BaseKernel, public ArrayItems
    {
    public:
    
      // handles
      typedef OpenMesh::VertexHandle            VertexHandle;
      typedef OpenMesh::HalfedgeHandle          HalfedgeHandle;
      typedef OpenMesh::EdgeHandle              EdgeHandle;
      typedef OpenMesh::FaceHandle              FaceHandle;
      typedef Attributes::StatusInfo            StatusInfo;
      typedef VPropHandleT<StatusInfo>          VertexStatusPropertyHandle;
      typedef HPropHandleT<StatusInfo>          HalfedgeStatusPropertyHandle;
      typedef EPropHandleT<StatusInfo>          EdgeStatusPropertyHandle;
      typedef FPropHandleT<StatusInfo>          FaceStatusPropertyHandle;
      
      HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const
      { return HalfedgeHandle((_heh.idx() & 1) ? _heh.idx()-1 : _heh.idx()+1); } 
    private:
      // iterators
      typedef std::vector<Vertex>                VertexContainer;
      typedef std::vector<Edge>                  EdgeContainer;
      typedef std::vector<Face>                  FaceContainer;
      typedef VertexContainer::iterator          KernelVertexIter;
      typedef VertexContainer::const_iterator    KernelConstVertexIter;
      typedef EdgeContainer::iterator            KernelEdgeIter;
      typedef EdgeContainer::const_iterator      KernelConstEdgeIter;
      typedef FaceContainer::iterator            KernelFaceIter;
      typedef FaceContainer::const_iterator      KernelConstFaceIter;
      typedef std::vector<uint>                  BitMaskContainer;
    
    
      KernelVertexIter      vertices_begin()        { return vertices_.begin(); }
      KernelConstVertexIter vertices_begin() const  { return vertices_.begin(); }
      KernelVertexIter      vertices_end()          { return vertices_.end(); }
      KernelConstVertexIter vertices_end() const    { return vertices_.end(); }
    
      KernelEdgeIter        edges_begin()           { return edges_.begin(); }
      KernelConstEdgeIter   edges_begin() const     { return edges_.begin(); }
      KernelEdgeIter        edges_end()             { return edges_.end(); }
      KernelConstEdgeIter   edges_end() const       { return edges_.end(); }
    
      KernelFaceIter        faces_begin()           { return faces_.begin(); }
      KernelConstFaceIter   faces_begin() const     { return faces_.begin(); }
      KernelFaceIter        faces_end()             { return faces_.end(); }
      KernelConstFaceIter   faces_end() const       { return faces_.end(); }
    
    private:
      VertexContainer                           vertices_;
      EdgeContainer                             edges_;
      FaceContainer                             faces_;

    }

     

    事实上当前版本的OPENMESH的顶点,边,面的基本结构非常简单,就是相关的handle,而handle类型也是定死了的。 不存在模板循环依赖技术,与CGAL不同。

    OPENMESH当前只采用基于VECTOR的构架,它把其余的顶点属性其实统统存在顶点之外,用数组保存,由于有handle即index,

    所以访问的时候是用的MESH::Kernal的方法如mesh_.property(cog_, vh) += mesh_.point( vv_it ); ,mesh_根据vh找到数组中

    该cog_的值。本质上是和vertex分离的,否则应该类似调用vh->cog_了,另外包括像顶点的位置,也是如此通过mesh_.point(vh)来得到

    而不是CGAL中vh->point(),即坐标属性没有存储在vertex之中。vertex只存一个halfedge_handle。

    所以用户用traits自定义属性如cog_或者动态添加cog_本质上和自己定义一个 cog[vertex_num]数组差不多,只不过openmesh封装了实现,提供统一方便的接口,

    看上去似乎就像是给vertex本身加了个cog_域。mesh_.property(cog_, vh)还是反映了实际的存储情况。

    但是问题是如果要提供基于list的mesh kernal呢,当前的架构似乎不能支持list吧?

    不过对于自己定义traits的时候给vertex_traits加入的属性cog_,方法cog()是可以按照下面的方式访问的。(注,这个是老的版本这样支持的,

    新版本去除了这一方式,其余的属性本质上就是顶点Vertex之外,由Mesh利用顶点属性数组统一管理的)

    MyMesh::VertexIter          v_it
    v_it->cog()         //旧版本
    //新版本要用mesh.data(v_it)->cog()//看了一版本变化说明,似乎是说因为MS不支持模版的前置循环声明好像,不得已为之的。

    mesh.data(v_it).set_cog(cog / valence);

    下面是02年的修改声明。应该就是因为这个原因,就把顶点,边,面定死了,不过看CGAL应该是支持的啊,奇怪:)现在的MS VC8应该肯定支持的。

    Removed cyclic dependency between items and kernel, because MS VC++ cannot handle the resulting template forward declaration :-(.

    Therefore the Base::Refs class, given for the traits classes, no longer provides the types \c Vertex, \c Halfedge, \c Edge, and \c Face.

    It now only provides all handle types, the point and the scalar type.

    我们看下为了实现下面的应用代码,程序内部是怎么构架的。

    应用代码:
    struct MyTraits : public OpenMesh::DefaultTraits
    {
      // store barycenter of neighbors in this member
      VertexTraits
      {
      private:
        Point  cog_;
      public:
    
        VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { }
    
        const Point& cog() const { return cog_; }
        void set_cog(const Point& _p) { cog_ = _p; }
      };
    };
    
    #endif
    
    typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits>  MyMesh; //下面就可以MyMesh mesh;使用这个mesh了。
     

    //OK具体上面的代码内部是如何实现的呢。

    先看DefaultTraits

    //只显示部分内容

    struct DefaultTraits
    {
      /// The default coordinate type is OpenMesh::Vec3f.
      typedef Vec3f  Point;
    
      /// The default normal type is OpenMesh::Vec3f.
      typedef Vec3f  Normal;
      …
    #ifndef DOXY_IGNORE_THIS
      VertexTraits    {};
      HalfedgeTraits  {};
      EdgeTraits      {};
      FaceTraits      {};
    #endif
      VertexAttributes(0);
      …
    };

    先不管 Atrtributes,我们就看VertexTraits,

    这里其实是用了宏,来对用户隐藏了模板参数。

    /// Macro for defining the vertex traits. See \ref mesh_type.
    #define VertexTraits \
      template <class Base, class Refs> struct VertexT : public Base   //其余Tratis 如face,halfedge的一样的方式处理
    所以实际代码展开之后类似下面
    struct MyTraits : public OpenMesh::DefaultTraits
    {
      template <class Base, class Refs> struct VertexT : public Base
      {
        int some_additional_index;
      };
    };

    这也就是为什么构造函数要写VertexT()的原因。

    The template argument Base provides access to the mesh handles and to the Point and Scalar type by its member class Refs. 
    Adding a MyMesh::FaceHandle to the vertex class can therefore be implemented like this:
    
    下面显示如何给顶点添加面handle属性。
    struct MyTraits : public OpenMesh::DefaultTraits 
    {
      VertexTraits
      {
        int some_additional_index;
        typename Base::Refs::FaceHandle my_face_handle;
      };
    };
     
    下面再看typedef OpenMesh::TriMesh_ArrayKernelT<MyTraits> MyMesh;意味着什么呢?

     

    TriMesh_ArrayKernelT

    它的实现利用了继承TriMesh_ArrayKernel_GeneratorT<Traits>::Mesh


    template <class Traits = DefaultTraits>
    class TriMesh_ArrayKernelT
      : public TriMesh_ArrayKernel_GeneratorT<Traits>::Mesh
    {};


    template <class Traits>
    struct TriMesh_ArrayKernel_GeneratorT
    {
      typedef FinalMeshItemsT<Traits, true>               MeshItems;
      typedef AttribKernelT<MeshItems, TriConnectivity>  AttribKernel;
      typedef TriMeshT<AttribKernel>                      Mesh;  //其实就是最终使用的mesh类型
    };

    image

    代码所表示的正是如上图所示的继承关系。OPENMESH大量利用 template<class Base> class Derived: public Base的继承模式。

    1. The BaseKernel defines the basic operations on properties like add/remove/access.
    2. Next the AttribKernelT adds the standard properties all associated methods.
    3. Finally the ArrayKernelT provides the methods to add/remove/access the mesh items vertices, (half-)edges, and faces. The base class is passed as a template parameter, since depending on the underlying storage type the AttribKernel might change.

    1. The PolyMeshT inherits from the kernel and provide all necessary methods to work with polygonal meshes.
    2. Finally we derive TriMeshT from PolyMeshT to have an specialization for triangle meshes.

    1.先来看FinalMeshItemsT,为了方便去掉了一些代码如attributes的部分。

    FinalMeshItemsT<Traits, true>               MeshItems;
     
    template <class Traits, bool IsTriMesh>
    struct FinalMeshItemsT
    {
      struct Refs
      {
        typedef typename Traits::Point            Point;                 //所以用户提供的MyTraits可能会改变Point的类型
        typedef typename vector_traits<Point>::value_type Scalar;
        …
        typedef OpenMesh::VertexHandle            VertexHandle;
      };
      //--- export Refs types ---
      typedef typename Refs::Point           Point;
      class ITraits
      {};
      
      typedef typename Traits::template VertexT<ITraits, Refs>      VertexData;     //这里用到了VertexT(可能由用户修改提供)
      typedef typename Traits::template HalfedgeT<ITraits, Refs>    HalfedgeData;
      …
    };
    } // namespace OpenMesh


    2.再看AttribKernelT

    AttribKernelT<MeshItems, TriConnectivity>  AttribKernel;通过继承Connectivity继承TriConnectivity->PolyConnectivity->ArrayKernel->BaseKernel + ArrayItems

    template <class MeshItems, class Connectivity>
    class AttribKernelT : public Connectivity       // class TriConnectivity : public PolyConnectivity
    
    {                                               //class PolyConnectivity : public ArrayKernel
    public:
    
      //---------------------------------------------------------------- item types
    
      typedef typename Connectivity::Vertex     Vertex;
      typedef typename Connectivity::Halfedge   Halfedge;
      typedef typename Connectivity::Edge       Edge;
      typedef typename Connectivity::Face       Face;
    
      typedef typename MeshItems::Point         Point;
      typedef typename MeshItems::Normal        Normal;
      …
      typedef typename MeshItems::VertexData    VertexData;
      typedef typename MeshItems::HalfedgeData  HalfedgeData;
      typedef typename MeshItems::EdgeData      EdgeData;
      typedef typename MeshItems::FaceData      FaceData;
    
      typedef AttribKernelT<MeshItems,Connectivity>  AttribKernel;
    
      enum Attribs  {
        VAttribs = MeshItems::VAttribs,
        HAttribs = MeshItems::HAttribs,
        EAttribs = MeshItems::EAttribs,
        FAttribs = MeshItems::FAttribs
      };
    
      typedef VPropHandleT<VertexData>              DataVPropHandle;    
      typedef HPropHandleT<HalfedgeData>            DataHPropHandle;
      typedef EPropHandleT<EdgeData>                DataEPropHandle;
      typedef FPropHandleT<FaceData>                DataFPropHandle;
    
    public:
    
      //-------------------------------------------------- constructor / destructor
    
      AttribKernelT()
      : refcount_vnormals_(0),
        refcount_vcolors_(0),
        …
       {
        add_property( points_, "v:points" );
    
        if (VAttribs & Attributes::Normal)
          request_vertex_normals();
        …
        //FIXME: data properties might actually cost storage even
        //if there are no data traits??
        add_property(data_vpph_);
        add_property(data_fpph_);
        add_property(data_hpph_);
        add_property(data_epph_);
      }
    
      virtual ~AttribKernelT()
      {
        // should remove properties, but this will be done in
        // BaseKernel's destructor anyway...
      }
    
      /** Assignment from another mesh of \em another type.
          \note All that's copied is connectivity and vertex positions.
          All other information (like e.g. attributes or additional
          elements from traits classes) is not copied.
          \note If you want to copy all information, including *custom* properties,
          use PolyMeshT::operator=() instead.
          TODO: version which copies standard properties specified by the user
      */
      template <class _AttribKernel>
      void assign(const _AttribKernel& _other)
      {
        assign_connectivity(_other);
        for (typename Connectivity::VertexIter v_it = Connectivity::vertices_begin();
             v_it != Connectivity::vertices_end(); ++v_it)
        {//assumes Point constructor supports cast from _AttribKernel::Point
          set_point(v_it, (Point)_other.point(v_it));
        }
      }
      …
      //------------------------------------------------ request / alloc properties
    
      void request_vertex_normals()
      {
        if (!refcount_vnormals_++)
          add_property( vertex_normals_, "v:normals" );
      }
    
      …
      //------------------------------------------------- release / free properties
    
      void release_vertex_normals()
      {
        if ((refcount_vnormals_ > 0) && (! --refcount_vnormals_))
          remove_property(vertex_normals_);
      }
    
      ….
      //---------------------------------------------- dynamic check for properties
    
      bool has_vertex_normals()       const { return vertex_normals_.is_valid();      }
    
      public:
    
      typedef VPropHandleT<Point>               PointsPropertyHandle;
      typedef VPropHandleT<Normal>              VertexNormalsPropertyHandle;
      …
    public:
      //standard vertex properties
      PointsPropertyHandle                      points_pph() const
      { return points_; }
      …
      VertexData&                               data(VertexHandle _vh)
      { return property(data_vpph_, _vh); }
    
      …
    private:
      //standard vertex properties
      PointsPropertyHandle                      points_;
      VertexNormalsPropertyHandle               vertex_normals_;
      …
      //data properties handles
      DataVPropHandle                           data_vpph_;
      DataHPropHandle                           data_hpph_;
      DataEPropHandle                           data_epph_;
      DataFPropHandle                           data_fpph_;
      …
    };
    

    关于add_property在class BaseKernel中。

    template <class T>
    void add_property( VPropHandleT<T>& _ph, const std::string& _name="<vprop>")
    {
      _ph = VPropHandleT<T>( vprops_.add(T(), _name) );
      vprops_.resize(n_vertices());         //in BaseKernel  PropertyContainer  vprops_;
    }

     

    //

    class ArrayKernel : public BaseKernel, public ArrayItems
    {
    public: 
    
      // handles
      typedef OpenMesh::VertexHandle            VertexHandle;
      typedef OpenMesh::HalfedgeHandle          HalfedgeHandle;
      typedef OpenMesh::EdgeHandle              EdgeHandle;
      typedef OpenMesh::FaceHandle              FaceHandle;
      typedef std::vector<Vertex>                VertexContainer;
     
    Vertex& vertex(VertexHandle _vh)
    {
      assert(is_valid_handle(_vh));
      return vertices_[_vh.idx()];
    }
    private:
    VertexContainer                           vertices_;
      EdgeContainer                             edges_;
      FaceContainer                             faces_;
    }
    class BaseKernel
    {
    private: 
      PropertyContainer  vprops_;
      PropertyContainer  hprops_;
      PropertyContainer  eprops_;
      PropertyContainer  fprops_;
      PropertyContainer  mprops_;
    };


    3.最后看TriMeshT

    TriMeshT<AttribKernel>                      Mesh;

    template <class Kernel>
    class TriMeshT : public PolyMeshT<Kernel>
    {
    public:
      // self
      typedef TriMeshT<Kernel>                      This;
      typedef PolyMeshT<Kernel>                     PolyMesh;
      //--- items ---
      typedef typename PolyMesh::Scalar             Scalar;
      typedef typename PolyMesh::Point              Point;
      …
      //--- handles ---
      typedef typename PolyMesh::VertexHandle       VertexHandle;
      typedef typename PolyMesh::HalfedgeHandle     HalfedgeHandle;
      typedef typename PolyMesh::EdgeHandle         EdgeHandle;
      typedef typename PolyMesh::FaceHandle         FaceHandle;
    
      //--- iterators ---
      typedef typename PolyMesh::VertexIter         VertexIter;
      …
      //--- circulators ---
      typedef typename PolyMesh::VertexVertexIter         VertexVertexIter;
      …
    }
     

    template <class Kernel>
    class PolyMeshT : public Kernel 

     

    看一下具体执行Mesh mesh;的时候构造函数的调用,其中PorpertyContainer是BaseKernel类的一个成员变量被初始化,其余都是代表类的默认初始化。可以看出类的层次关系。

    (gdb) bt
    #0  new_allocator (this=0xbfc56563) at /usr/include/c++/4.2/ext/new_allocator.h:68
    #1  0xb7f4f07b in allocator (this=0xbfc56563) at /usr/include/c++/4.2/bits/allocator.h:100
    #2  0xb7f50a81 in PropertyContainer (this=0xbfc566ac) at /home/allen/study/OpenMesh/src/OpenMesh/Core/../../OpenMesh/Core/Utils/PropertyContainer.hh:66
    #3  0xb7f56a76 in BaseKernel (this=0xbfc566a8) at /home/allen/study/OpenMesh/src/OpenMesh/Core/../../OpenMesh/Core/Mesh/BaseKernel.hh:95
    #4  0xb7f4ce46 in ArrayKernel (this=0xbfc566a8) at /home/allen/study/OpenMesh/src/OpenMesh/Core/Mesh/ArrayKernel.cc:49
    #5  0x0805854f in PolyConnectivity (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/PolyConnectivity.hh:164
    #6  0x0805856d in TriConnectivity (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriConnectivity.hh:55
    #7  0x08061720 in AttribKernelT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/AttribKernelT.hh:124
    #8  0x08061c21 in PolyMeshT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/PolyMeshT.hh:181
    #9  0x08061c3f in TriMeshT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriMeshT.hh:164
    #10 0x08061c5d in TriMesh_ArrayKernelT (this=0xbfc566a8) at ../../../../src/OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh:93
    #11 0x080503fa in main (argc=1, argv=0xbfc56934) at smooth.cc:50

     

    TODO

    1.关于动态添加属性,究竟是如何实现的

    template <class T>
    typename VPropHandleT<T>::reference
    property(VPropHandleT<T> _ph, VertexHandle _vh) {
       return vprops_.property(_ph)[_vh.idx()];
    }

    vprops_是PropertyContainer类型的

    mesh.property(cogs,v_it) += mesh.point( vv_it );

    调用 property(cogs,v_it)    ->调用 vprops_.property(cogs)[v_it.idx()]

      template <class T> PropertyT<T>& property(BasePropHandleT<T> _h)
      {
        assert(_h.idx() >= 0 && _h.idx() < (int)properties_.size());
        assert(properties_[_h.idx()] != NULL);
    #ifdef OM_FORCE_STATIC_CAST
        return *static_cast  <PropertyT<T>*> (properties_[_h.idx()]);
    #else
        PropertyT<T>* p = dynamic_cast<PropertyT<T>*>(properties_[_h.idx()]);
        assert(p != NULL);
        return *p;
    #endif
      }

    大概是mesh根据cogs找到它的属性数组,然后利用v_it的顶点索引,找到具体的值,

    不过太复杂了,有时间再弄清细节吧。

    2.用array的话,如何能够在拓扑变化的情况下,如点的删除,保证高效率的。

    3.简化和细分模块是如何架构的。

    展开全文
  • 所用的函数非常简单,只需要用到mesh函数,示例代码如下: Ima=imread('F:\pathto\test.jpg'); surf_ima = surf(rgb2gray(Ima)); %黑色的3D图 title('3D') mesh_ima = mesh(rgb2gray(Ima)); %有色彩的3D图 ...
  • Matlab中mesh函数的用法

    万次阅读 2017-07-27 19:58:39
    在使用mesh语句的时候经常会出现一些理解上的问题,在这里谈一谈个人的理解: mesh语句画网格图片,实际上就是给出一对坐标(x,y),来画矩阵z(x,y)的值。 下面将给出实例进行解释: 当给出值 x=[1.1 ,1.2 ,1.3 ,1.4 ,...
  • mesh(X,Y,Z) 源码如上,出现的图如下 现在不清楚的就是 第一:如何改变想x,y坐标轴pi为阿拉伯度数 第二:x,y存在一个x>=y的关系怎么加进去 最后使这个结果变成下面的图 欢迎使用Markdown编辑器 你好!...
  • 一、二维网格、 ...1、mesh 函数绘制网格、 2、代码示例、 三、绘制平面、 1、surf 函数绘制平面、 2、代码示例、 四、绘制等高线、 1、contour 函数绘制等高线、 2、代码示例、 3、绘制彩色等高线并标注高度值、
  • mesh和surf函数

    千次阅读 2016-08-15 17:47:04
    1. mesh我们来看看这样一段代码:[X,Y] = meshgrid(-8:.5:8); R = sqrt(X.^2 + Y.^2) + eps; Z = sin(R)./R; C = gradient(Z); figure(1),mesh(Z); figure(2),mesh(X,Y,Z); figure(3),mesh(X,Y,Z,C)这里我们分别得到...
  • mesh() 函数——绘制参数网状表面图 【功能】绘制三维曲面网格图。三维曲面网格图的最大优点是较好地解决了数据在三维空间的可视化问题。 【语法】mesh( z ),z 为待绘制函数。 示例代码如下: x=-8:0.5:8; y=x'; X=...
  • 1、首先要检查是不是函数...2、打开安装包中mesh.m这个函数,检查是不是函数本身的问题 我遇到这个问题检查函数发现是函数自身的问题 第一行代码function h=mesh(varargin) 中function前多了一个字母c,删掉即可 ...
  • matlab中的mesh()函数和meshgrid()函数

    千次阅读 2019-10-31 22:17:08
    mesh: https://blog.csdn.net/kobesdu/article/details/8640648 https://blog.csdn.net/Zz501306162/article/details/54287593 (mesh+meshgrid) meshgrid: ...
  • MATLAB 函数 mesh()用法

    万次阅读 2016-10-21 20:50:48
    mesh是画三维图,我是某次做图像处理时用到它画频谱图,先给出一个简单的例程: clc,clear; m=(1:10);%x轴的长度 n=(1:10);...meshgrid函数形成(x,y)的方阵,是m*n*2的一个矩阵,z=f(x,y)可以在[u,v]
  • matlab函数——meshgrid、mesh、surf函数

    万次阅读 多人点赞 2015-09-07 15:46:49
    meshgrid 函数 用来生成网格矩阵,只能生成二维三维网格矩阵。对于生成二维网格,用法为:[X Y]=meshgrid(x y); % x 和y是一维数组,如x=[1 2 3]; y= [2 3 4 ]; 则生成的 X 和 Y都是二维的矩阵,X 的每行都是 1 2 ...
  • openmesh库部分函数API

    2020-07-30 18:08:37
    it++)//对面的遍历 函数格式为:mesh.XXX_begin() ##2.2 获取网格信息` mesh.n_vertices()//获取顶点个数 mesh.n_halfedges()//获取边的个数 .idx()//获取当前点/边/面的ID 函数格式为:mesh.n_XXX() ##2.3删除网格...
  • MATLAB中mesh()函数

    千次阅读 2014-03-22 19:53:20
    MATLAB中mesh()函数   转载▼ mesh(Z): mesh(X,Y,Z,C):其中C是用来定义相应点颜色等属性的数组 例:求x^2+y^2=z的空间曲面 x=-4:4; y=x; [X,Y]=meshgrid(x,y);%生成x,y坐标 Z=X.^2+Y.^2; mesh(X,Y,Z)
  • MATLAB中函数mesh()用法

    万次阅读 多人点赞 2013-03-06 09:42:09
    功能 生成由X,Y和Z指定的网线面,由C指定的颜色的三维网格图。网格图是作为视点由view(3)设定的surface图形对象。曲面的颜色与背景颜色相同(当要动画...用法 mesh(X,Y,Z) 画出颜色由c指定的三维网格图,所以和曲面
  • 今天使用Unity的时候,需要自己创建Mesh,然后对Mesh里的vertices进行赋值,我发现了有两种写法: List<int>vertices = new List<int>(); //写法1 mesh.vertices = vertices.ToArray(); //写法2 mesh....
  • Matlab之peaks,mesh,meshgrid函数

    万次阅读 多人点赞 2013-08-26 11:02:09
    Matlab之peaks,mesh,meshgrid函数 peaks: Matlab提供了一个peaks函数,可产生一个凹凸有致的曲面,包含了三个局部极大点及三个局部极小点,其方程式为: 一: peaks:默认取4
  • 功能 生成由X,Y和Z指定的网线面,由C指定的颜色的三维网格图。网格图是作为视点由view(3)设定的surface图形对象。曲面的颜色与背景颜色相同...用法 mesh(X,Y,Z) 画出颜色由c指定的三维网格图,所以和曲面的高度相...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,961
精华内容 9,984
关键字:

mesh函数