zoukankan      html  css  js  c++  java
  • vtkPlane和vtkPlaneSource

    1、vtkPlane

    vtkPlane provides methods for various plane computations. These include projecting points onto a plane, evaluating the plane equation, and returning plane normal. vtkPlane is a concrete implementation of the abstract class vtkImplicitFunction.

    成员函数:void EvaluateFunction(double x[3])、void EvaluateFunction(double x,double y,double z)用于估算点x[3]是否位于平面上、平面前或平面后(法线方向为前),它是从抽象类vtkImplicitFunction继承而来,在基类中它是一个纯虚函数。
           void EvaluateGradient (double x[3], double g[3])用于估算点x[3]处函数倾斜度
                  void vtkPlane::SetNormal(double x[3])、void vtkPlane::SetNormal(double x,double y,double z)  Set/get平面法向量.平面是由“点”和“法向量”定义的。 
                  void Set/GetOrigin(double x[3])与SetNormal用法类似。
                  void vtkPlane::Push(double distance)该函数可以将平面沿着法线方向移动distance距离
                  在成员函数中还定义了点、矢量向某个平面投影的功能函数,如ProjectPoint、ProjectVector等。

    隐函数的数学表达式为F(x,y,z)=w,平面的隐函数方程有点法式和一般式。在vtkPlane中采用的是点法式隐函数
    点法式平面隐函数方程为:A(x-x0)+B(y-y0)+C(z-z0)=w, (A,B,C)为平面法向量,即vtkPlane中的Normal,(x0,y0,z0)为平面上一点,即vtkPlane中的Origin。
    平面的一般式方程为:Ax+By+Cz=w

    EvaluateFunction的源代码如下:  

    double vtkPlane::EvaluateFunction(double x[3])
    {
      return ( this->Normal[0]*(x[0]-this->Origin[0]) +
               this->Normal[1]*(x[1]-this->Origin[1]) +
               this->Normal[2]*(x[2]-this->Origin[2]) );
    }
    Examples:
    vtkPlane (Examples)
    Tests:
    vtkPlane (Tests)

    vtkPlane.h源代码:

    #include "vtkCommonDataModelModule.h" // For export macro
    #include "vtkImplicitFunction.h"
    
    class VTKCOMMONDATAMODEL_EXPORT vtkPlane : public vtkImplicitFunction
    {
    public:
      // Description
      // Construct plane passing through origin and normal to z-axis.
      static vtkPlane *New();
    
      vtkTypeMacro(vtkPlane,vtkImplicitFunction);
      void PrintSelf(ostream& os, vtkIndent indent);
    
      // Description
      // Evaluate plane equation for point x[3].
      double EvaluateFunction(double x[3]);
      double EvaluateFunction(double x, double y, double z)
        {return this->vtkImplicitFunction::EvaluateFunction(x, y, z); } ;
    
      // Description
      // Evaluate function gradient at point x[3].
      void EvaluateGradient(double x[3], double g[3]);
    
      // Description:
      // Set/get plane normal. Plane is defined by point and normal.
      vtkSetVector3Macro(Normal,double);
      vtkGetVectorMacro(Normal,double,3);
    
      // Description:
      // Set/get point through which plane passes. Plane is defined by point
      // and normal.
      vtkSetVector3Macro(Origin,double);
      vtkGetVectorMacro(Origin,double,3);
    
      // Description:
      // Translate the plane in the direction of the normal by the
      // distance specified.  Negative values move the plane in the
      // opposite direction.
      void Push(double distance);
    
      // Description
      // Project a point x onto plane defined by origin and normal. The
      // projected point is returned in xproj. NOTE : normal assumed to
      // have magnitude 1.
      static void ProjectPoint(double x[3], double origin[3], double normal[3],
                               double xproj[3]);
      void ProjectPoint(double x[3], double xproj[3]);
    
      // Description
      // Project a vector v onto plane defined by origin and normal. The
      // projected vector is returned in vproj.
      static void ProjectVector(double v[3], double origin[3], double normal[3],
                               double vproj[3]);
      void ProjectVector(double v[3], double vproj[3]);
    
      // Description
      // Project a point x onto plane defined by origin and normal. The
      // projected point is returned in xproj. NOTE : normal does NOT have to
      // have magnitude 1.
      static void GeneralizedProjectPoint(double x[3], double origin[3],
                                          double normal[3], double xproj[3]);
      void GeneralizedProjectPoint(double x[3], double xproj[3]);
    
    
      // Description:
      // Quick evaluation of plane equation n(x-origin)=0.
      static double Evaluate(double normal[3], double origin[3], double x[3]);
    
      // Description:
      // Return the distance of a point x to a plane defined by n(x-p0) = 0. The
      // normal n[3] must be magnitude=1.
      static double DistanceToPlane(double x[3], double n[3], double p0[3]);
      double DistanceToPlane(double x[3]);
    
      // Description:
      // Given a line defined by the two points p1,p2; and a plane defined by the
      // normal n and point p0, compute an intersection. The parametric
      // coordinate along the line is returned in t, and the coordinates of
      // intersection are returned in x. A zero is returned if the plane and line
      // do not intersect between (0<=t<=1). If the plane and line are parallel,
      // zero is returned and t is set to VTK_LARGE_DOUBLE.
      static int IntersectWithLine(double p1[3], double p2[3], double n[3],
                                   double p0[3], double& t, double x[3]);
      int IntersectWithLine(double p1[3], double p2[3], double& t, double x[3]);
    
    protected:
      vtkPlane();
      ~vtkPlane() {}
    
      double Normal[3];
      double Origin[3];
    
    private:
      vtkPlane(const vtkPlane&);  // Not implemented.
      void operator=(const vtkPlane&);  // Not implemented.
    };
    
    inline double vtkPlane::Evaluate(double normal[3],
                                     double origin[3], double x[3])
    {
      return normal[0]*(x[0]-origin[0]) + normal[1]*(x[1]-origin[1]) +
             normal[2]*(x[2]-origin[2]);
    }
    
    inline double vtkPlane::DistanceToPlane(double x[3], double n[3], double p0[3])
    {
    #define vtkPlaneAbs(x) ((x)<0?-(x):(x))
      return (vtkPlaneAbs(n[0]*(x[0]-p0[0]) + n[1]*(x[1]-p0[1]) +
                          n[2]*(x[2]-p0[2])));
    }
    View Code

    vtkPlane.cpp源代码:

    #include "vtkPlane.h"
    #include "vtkMath.h"
    #include "vtkObjectFactory.h"
    
    vtkStandardNewMacro(vtkPlane);
    
    // Construct plane passing through origin and normal to z-axis.
    vtkPlane::vtkPlane()
    {
      this->Normal[0] = 0.0;
      this->Normal[1] = 0.0;
      this->Normal[2] = 1.0;
    
      this->Origin[0] = 0.0;
      this->Origin[1] = 0.0;
      this->Origin[2] = 0.0;
    }
    
    double vtkPlane::DistanceToPlane(double x[3])
    {
      return this->DistanceToPlane(x, this->GetNormal(), this->GetOrigin());
    }
    
    void vtkPlane::ProjectPoint(double x[3], double origin[3],
                                double normal[3], double xproj[3])
    {
      double t, xo[3];
    
      xo[0] = x[0] - origin[0];
      xo[1] = x[1] - origin[1];
      xo[2] = x[2] - origin[2];
    
      t = vtkMath::Dot(normal,xo);
    
      xproj[0] = x[0] - t * normal[0];
      xproj[1] = x[1] - t * normal[1];
      xproj[2] = x[2] - t * normal[2];
    }
    
    void vtkPlane::ProjectPoint(double x[3], double xproj[3])
    {
      this->ProjectPoint(x, this->GetOrigin(), this->GetNormal(), xproj);
    }
    
    void vtkPlane::ProjectVector(
      double v[3], double vtkNotUsed(origin)[3], double normal[3],
      double vproj[3])
    {
      double t = vtkMath::Dot(v, normal);
      double n2 = vtkMath::Dot(normal, normal);
      if (n2 == 0)
        {
        n2 = 1.0;
        }
      vproj[0] = v[0] - t * normal[0] / n2;
      vproj[1] = v[1] - t * normal[1] / n2;
      vproj[2] = v[2] - t * normal[2] / n2;
    }
    
    void vtkPlane::ProjectVector(double v[3], double vproj[3])
    {
      this->ProjectVector(v, this->GetOrigin(), this->GetNormal(), vproj);
    }
    
    
    void vtkPlane::Push(double distance)
    {
      int i;
    
      if ( distance == 0.0 )
        {
        return;
        }
      for (i=0; i < 3; i++ )
        {
        this->Origin[i] += distance * this->Normal[i];
        }
      this->Modified();
    }
    
    // Project a point x onto plane defined by origin and normal. The
    // projected point is returned in xproj. NOTE : normal NOT required to
    // have magnitude 1.
    void vtkPlane::GeneralizedProjectPoint(double x[3], double origin[3],
                                           double normal[3], double xproj[3])
    {
      double t, xo[3], n2;
    
      xo[0] = x[0] - origin[0];
      xo[1] = x[1] - origin[1];
      xo[2] = x[2] - origin[2];
    
      t = vtkMath::Dot(normal,xo);
      n2 = vtkMath::Dot(normal, normal);
    
      if (n2 != 0)
        {
        xproj[0] = x[0] - t * normal[0]/n2;
        xproj[1] = x[1] - t * normal[1]/n2;
        xproj[2] = x[2] - t * normal[2]/n2;
        }
      else
        {
        xproj[0] = x[0];
        xproj[1] = x[1];
        xproj[2] = x[2];
        }
    }
    
    void vtkPlane::GeneralizedProjectPoint(double x[3], double xproj[3])
    {
      this->GeneralizedProjectPoint(x, this->GetOrigin(), this->GetNormal(), xproj);
    }
    
    // Evaluate plane equation for point x[3].
    double vtkPlane::EvaluateFunction(double x[3])
    {
      return ( this->Normal[0]*(x[0]-this->Origin[0]) +
               this->Normal[1]*(x[1]-this->Origin[1]) +
               this->Normal[2]*(x[2]-this->Origin[2]) );
    }
    
    // Evaluate function gradient at point x[3].
    void vtkPlane::EvaluateGradient(double vtkNotUsed(x)[3], double n[3])
    {
      for (int i=0; i<3; i++)
        {
        n[i] = this->Normal[i];
        }
    }
    
    #define VTK_PLANE_TOL 1.0e-06
    
    // Given a line defined by the two points p1,p2; and a plane defined by the
    // normal n and point p0, compute an intersection. The parametric
    // coordinate along the line is returned in t, and the coordinates of
    // intersection are returned in x. A zero is returned if the plane and line
    // do not intersect between (0<=t<=1). If the plane and line are parallel,
    // zero is returned and t is set to VTK_LARGE_DOUBLE.
    int vtkPlane::IntersectWithLine(double p1[3], double p2[3], double n[3],
                                   double p0[3], double& t, double x[3])
    {
      double num, den, p21[3];
      double fabsden, fabstolerance;
    
      // Compute line vector
      //
      p21[0] = p2[0] - p1[0];
      p21[1] = p2[1] - p1[1];
      p21[2] = p2[2] - p1[2];
    
      // Compute denominator.  If ~0, line and plane are parallel.
      //
      num = vtkMath::Dot(n,p0) - ( n[0]*p1[0] + n[1]*p1[1] + n[2]*p1[2] ) ;
      den = n[0]*p21[0] + n[1]*p21[1] + n[2]*p21[2];
      //
      // If denominator with respect to numerator is "zero", then the line and
      // plane are considered parallel.
      //
    
      // trying to avoid an expensive call to fabs()
      if (den < 0.0)
        {
        fabsden = -den;
        }
      else
        {
        fabsden = den;
        }
      if (num < 0.0)
        {
        fabstolerance = -num*VTK_PLANE_TOL;
        }
      else
        {
        fabstolerance = num*VTK_PLANE_TOL;
        }
      if ( fabsden <= fabstolerance )
        {
        t = VTK_DOUBLE_MAX;
        return 0;
        }
    
      // valid intersection
      t = num / den;
    
      x[0] = p1[0] + t*p21[0];
      x[1] = p1[1] + t*p21[1];
      x[2] = p1[2] + t*p21[2];
    
      if ( t >= 0.0 && t <= 1.0 )
        {
        return 1;
        }
      else
        {
        return 0;
        }
    }
    
    int vtkPlane::IntersectWithLine(double p1[3], double p2[3], double& t, double x[3])
    {
      return this->IntersectWithLine(p1, p2, this->GetNormal(), this->GetOrigin(), t, x);
    }
    
    void vtkPlane::PrintSelf(ostream& os, vtkIndent indent)
    {
      this->Superclass::PrintSelf(os,indent);
    
      os << indent << "Normal: (" << this->Normal[0] << ", "
        << this->Normal[1] << ", " << this->Normal[2] << ")
    ";
    
      os << indent << "Origin: (" << this->Origin[0] << ", "
        << this->Origin[1] << ", " << this->Origin[2] << ")
    ";
    }
    View Code

    vtkPlaneTest代码:代码中测试了ProjectVector函数

    #ifndef INITIAL_OPENGL
    #define INITIAL_OPENGL
    #include <vtkAutoInit.h>
    VTK_MODULE_INIT(vtkRenderingOpenGL)
    VTK_MODULE_INIT(vtkInteractionStyle)
    #endif
    #include <iostream>
    using namespace std;
    #include "vtkMath.h"
    #include "vtkPlane.h"
    #include "vtkSmartPointer.h"
    #include <limits>
    /*浮点数的大小比较
     参考网址:http://blog.csdn.net/chaoi/article/details/1628331
    浮点数在转换过程中都会有误差的,所以浮点数不能直接比较其大小,一般在比较两个浮点数的时候是比较他们之间的差值,如果两个数之间的差值处于一个能接受的范围之内的话,那么,我们就认为这两个浮点数是相等的,
    一般认为A与B的差大于某个很小的数时就认为A>B,比如:
        if( A-B > 0.001 )
        {
             A>B...
        }
    一般来说这个可以接受的误差值就是计算机的转换误差,C++标准库提供了这个误差,你可以从numeric_limits模板库的epsilon函数取得:
    numeric_limits<float>::epsilon()
    **/
    #ifndef ABS
    #define ABS(x) ((x)<0?-(x):(x))//如果x小于0,返回-x,否则返回x
    #endif
    template<class A>
    bool fuzzyCompare1D(A a,A b)//比较a是否小于b
    {
        return ABS(a-b)<std::numeric_limits<A>::epsilon();
    }
    template<class A>
    fuzzyCompare3D(A a[3],A b[3])
    {
        return fuzzyCompare1D(a[0],b[0])&&
                fuzzyCompare1D(a[1],b[1])&&
                fuzzyCompare1D(a[2],b[2]);
    }
    
    int main()
    {
        //测试ProjectVector(vector在平面外)
        {
            vtkSmartPointer<vtkPlane> plane=vtkSmartPointer<vtkPlane>::New();
            plane->SetOrigin(0,0,0);
            plane->SetNormal(0,0,1);
            std::cout<<"Testing ProjectVector"<<std::endl;
            double v[3]={1,2,3};
            double projection[3];
            double correct[3]={1,2,0};
            plane->ProjectVector(v,projection);
            if(!fuzzyCompare3D(projection,correct))
            {
                std::cerr<<"ProjectVector failed!Should be (1.,2.,0) but it is ("
                        <<projection[0]<<","<<projection[1]<<","<<projection[2]<<")"
                       <<std::endl;
                return EXIT_FAILURE;
            }
        }
        //测试ProjectVector,该矢量已经在平面内了
        {
            vtkSmartPointer<vtkPlane> plane =
                    vtkSmartPointer<vtkPlane>::New();
            plane->SetOrigin(0.0, 0.0, 0.0);
            plane->SetNormal(0,0,1);
            
            std::cout << "Testing ProjectVector" << std::endl;
            double v[3] = {1,2,0};
            double projection[3];
            double correct[3] = {1., 2., 0};
            plane->ProjectVector(v, projection);
            if(!fuzzyCompare3D(projection,correct))
            {
                std::cerr << "ProjectVector failed! Should be (1., 2., 0) but it is ("
                          << projection[0] << " " << projection[1] << " " << projection[2] << ")" << std::endl;
                return EXIT_FAILURE;
            }
        }
        
        // Test ProjectVector where vector is orthogonal to plane
        {
            vtkSmartPointer<vtkPlane> plane =
                    vtkSmartPointer<vtkPlane>::New();
            plane->SetOrigin(0.0, 0.0, 0.0);
            plane->SetNormal(0,0,1);
            
            std::cout << "Testing ProjectVector" << std::endl;
            double v[3] = {0,0,1};
            double projection[3];
            double correct[3] = {0., 0., 0.};
            plane->ProjectVector(v, projection);
            if(!fuzzyCompare3D(projection,correct))
            {
                std::cerr << "ProjectVector failed! Should be (0., 0., 0) but it is ("
                          << projection[0] << " " << projection[1] << " " << projection[2] << ")" << std::endl;
                return EXIT_FAILURE;
            }
        }
        
        return 0;
    }

    2、vtkPlanes

    vtkPlanes 为一组平面计算他们的隐函数和函数梯度。这些平面必须定义一个凸空间。函数值是一点到平面所定义的凸域的最近一阶距离。函数梯度是平面法向量的函数值。注意,法向量必须指向凸域的外边。这样当函数值为负数时,表示该点在凸域内部。

    有多种方法定义一组平面。最常见的方法是,提供vtkPoints和vtkDataArray的实例。vtkPoints定义了平面上的点和平面法向量的方向。

    还有两种方法:(1)提供6个平面,定义一个相机视角平截头体( view frustrum of a camera,)
           (2)提供一个a bounding box.

    The function value is the closest first order distance of a point to the convex region defined by the planes. The function gradient is the plane normal at the function value. Note that the normals must point outside of the convex region. Thus, a negative function value means that a point is inside the convex region.

    There are several methods to define the set of planes. The most general is to supply an instance of vtkPoints and an instance of vtkDataArray. (The points define a point on the plane, and the normals corresponding plane normals.) Two other specialized ways are to 1) supply six planes defining the view frustrum of a camera, and 2) provide a bounding box.

    See also
    vtkCamera
    Examples:
    vtkPlanes (Examples)
    Tests:
    vtkPlanes (Tests)

    3、vtkAppendPolyData 

    vtkAppendPolyData is a filter that appends one of more polygonal datasets into a single polygonal dataset. All geometry is extracted and appended, but point and cell attributes (i.e., scalars, vectors, normals) are extracted and appended only if all datasets have the point and/or cell attributes available. (For example, if one dataset has point scalars but another does not, point scalars will not be appended.) 

    4、vtkGlyph3D 

    将方向、尺度缩放后的几何符号,复制到每个输入点上。copy oriented and scaled glyph geometry to every input point

    vtkGlyph3D 是一个筛选器,它可以将一个几何图形复制到输入数据(dataset)中的每个点上,这个被复制的几何图形称为符号(glyph)。向该类中传入一个source filter,比如本例中的cone,根据cone的多边形数据定义glyph。glyph的方向可以与输入的矢量或法向量一致,还可以根据标量数据(scalar data)或这矢量幅值(vector magnitude)缩放glyp的尺度。当有多个glyph时,就需要建立一个source object表,表中的每一个source object定义一个不同的glyph。如果一个glyphs表已经建立,那么可以根据scalar data或vector magnitude对表格进行检索。

    为了能够使用该类的对象,你需要为其输入一个数据集(dataset)和一个source,source用来定义glyph的形状。然后,决定是否对glyph进行尺度缩放,以及是根据scalar还是根据vector magnitude进行缩放。接下来,决定你是否想要为glyph确定方向,以及是使用vector还是normal确定方向。最后,决定是使用glyphs表还是一种简单的符号形状。如果使用符号表,你还需要决定是用scalar还是用vector magnitude对其索引。

        glyph->SetInputConnection(sphere->GetOutputPort());//将锥型符号复制到球面的每个点上,DataSet数据集,在本例中为球面上各个的点,将锥型符号复制到这些点上,并且指向该点的法向方向。
        glyph->SetSourceConnection(cone->GetOutputPort());//创建锥型符号vtkConeSource
        glyph->SetVectorModeToUseNormal();//将矢量模式改成法向量模式
        glyph->SetScaleModeToScaleByVector();//根据矢量幅值缩放锥型符号
        glyph->SetScaleFactor(0.25);//设定锥型符号的缩放比例为0.25
    Warning
    The scaling of the glyphs is controlled by the ScaleFactor ivar multiplied by the scalar value at each point (if VTK_SCALE_BY_SCALAR is set), or multiplied by the vector magnitude (if VTK_SCALE_BY_VECTOR is set), Alternatively (if VTK_SCALE_BY_VECTORCOMPONENTS is set), the scaling may be specified for x,y,z using the vector components. The scale factor can be further controlled by enabling clamping using the Clamping ivar. If clamping is enabled, the scale is normalized by the Range ivar, and then multiplied by the scale factor. The normalization process includes clamping the scale value between (0,1).
    Typically this object operates on input data with scalar and/or vector data. However, scalar and/or vector aren't necessary, and it can be used to copy data from a single source to each point. In this case the scale factor can be used to uniformly scale the glyphs.
    The object uses "vector" data to scale glyphs, orient glyphs, and/or index into a table of glyphs. You can choose to use either the vector or normal data at each input point. Use the method SetVectorModeToUseVector() to use the vector input data, andSetVectorModeToUseNormal() to use the normal input data.
    If you do use a table of glyphs, make sure to set the Range ivar to make sure the index into the glyph table is computed correctly.
    You can turn off scaling of the glyphs completely by using the Scaling ivar. You can also turn off scaling due to data (either vector or scalar) by using the SetScaleModeToDataScalingOff() method.
    You can set what arrays to use for the scalars, vectors, normals, and color scalars by using the SetInputArrayToProcess methods in vtkAlgorithm. The first array is scalars, the next vectors, the next normals and finally color scalars.
    See also
    vtkTensorGlyph
    Examples:
    vtkGlyph3D (Examples)
    Tests:
    vtkGlyph3D (Tests)

      

    #ifndef INITIAL_OPENGL
    #define INITIAL_OPENGL
    #include <vtkAutoInit.h>
    VTK_MODULE_INIT(vtkRenderingOpenGL)
    VTK_MODULE_INIT(vtkInteractionStyle)
    #endif
    #include <iostream>
    using namespace std;
    #include <vtkSphereSource.h>
    #include <vtkConeSource.h>
    #include <vtkGlyph3D.h>
    #include <vtkAppendPolyData.h>
    #include <vtkPolyDataMapper.h>
    #include <vtkLODActor.h>
    #include <vtkClipPolyData.h>
    #include <vtkRenderer.h>
    #include <vtkRenderWindow.h>
    #include <vtkRenderWindowInteractor.h>
    #include <vtkInteractorStyleTrackballCamera.h>
    #include <vtkProperty.h>
    #include <vtkBoxWidget.h>
    #include <vtkCommand.h>
    #include <vtkObject.h>
    #include <vtkPlanes.h>
    
    class myCommand:public vtkCommand
    {
    public:
        static myCommand *New(){return new myCommand;}
        void setObject(vtkBoxWidget* bw,vtkLODActor* lodActor,vtkPlanes*plan)
        {
            boxWidget=bw;
            selectActor=lodActor;
            planes=plan;
        }
        virtual void Execute(vtkObject*caller,unsigned long EventIds,void* callData)
        {
            boxWidget->GetPlanes(planes);
            selectActor->VisibilityOn();
        }
    
    
    private:
        vtkBoxWidget *boxWidget;
        vtkLODActor *selectActor;
        vtkPlanes *planes;
    };
    
    int main()
    {
    /* Demonstrate how to use the vtkBoxWidget 3D widget,
     This script uses a 3D box widget to define a "clipping box" to clip some
     simple geometry (a mace). Make sure that you hit the "W" key to activate the widget.
    */
    // Create a mace out of filters.
        vtkSmartPointer<vtkSphereSource>sphere=vtkSmartPointer<vtkSphereSource>::New();
        vtkSmartPointer<vtkConeSource> cone=vtkSmartPointer<vtkConeSource> ::New();
        vtkSmartPointer<vtkGlyph3D> glyph=vtkSmartPointer<vtkGlyph3D>::New();
        glyph->SetInputConnection(sphere->GetOutputPort());//将锥型符号复制到球面的每个点上
        glyph->SetSourceConnection(cone->GetOutputPort());//创建锥型符号
        glyph->SetVectorModeToUseNormal();//将矢量模式改成法向量模式
        glyph->SetScaleModeToScaleByVector();//根据矢量幅值缩放锥型符号
        glyph->SetScaleFactor(0.25);//设定锥型符号的缩放比例为0.25
    
        //将sphere和spikes附加到一个PolyData中,这样可以方便管理
        vtkSmartPointer<vtkAppendPolyData> apd=vtkSmartPointer<vtkAppendPolyData>::New();
        apd->AddInputConnection(glyph->GetOutputPort());
    //    apd->AddInputConnection(sphere->GetOutputPort());
        vtkSmartPointer<vtkPolyDataMapper> maceMapper=vtkSmartPointer<vtkPolyDataMapper>::New();
        maceMapper->SetInputConnection(apd->GetOutputPort());
        vtkSmartPointer<vtkLODActor> maceActor=vtkSmartPointer<vtkLODActor>::New();
        maceActor->SetMapper(maceMapper);
        maceActor->VisibilityOn();
        //下面的代码是用tkPlanes的隐函数,对mace进行裁剪。被裁剪的区域染成了绿色
        vtkSmartPointer<vtkPlanes> planes=vtkSmartPointer<vtkPlanes>::New();
        vtkSmartPointer<vtkClipPolyData> clipper=vtkSmartPointer<vtkClipPolyData>::New();
        clipper->SetInputConnection(apd->GetOutputPort());
        clipper->SetClipFunction(planes);
        clipper->InsideOutOn();
        vtkSmartPointer<vtkPolyDataMapper> selectMapper=vtkSmartPointer<vtkPolyDataMapper>::New();
        selectMapper->SetInputConnection(clipper->GetOutputPort());
        vtkSmartPointer<vtkLODActor> selectActor=vtkSmartPointer<vtkLODActor>::New();
        selectActor->SetMapper(selectMapper);
        selectActor->GetProperty()->SetColor(0,1,0);
        selectActor->VisibilityOff();
        selectActor->SetScale(1.01,1.01,1.01);
        //创建显示窗口
        vtkSmartPointer<vtkRenderer> ren1=vtkSmartPointer<vtkRenderer>::New();
        vtkSmartPointer<vtkRenderWindow> renWin=vtkSmartPointer<vtkRenderWindow>::New();
        vtkSmartPointer<vtkRenderWindowInteractor> iren=vtkSmartPointer<vtkRenderWindowInteractor>::New();
    
        renWin->AddRenderer(ren1);
        iren->SetRenderWindow(renWin);
    //SetIneractor方法,用于3Dwidgets与渲染窗口互动器vtkRenderWindowInteractor之间的链接
        vtkSmartPointer<vtkBoxWidget> boxWidget=vtkSmartPointer<vtkBoxWidget>::New();
        boxWidget->SetInteractor(iren);
        boxWidget->SetPlaceFactor(1.25);
        //将两个演员添加到renderer,并设置背景颜色和尺寸
        ren1->AddActor(maceActor);
        ren1->AddActor(selectActor);
        ren1->SetBackground(0.1,0.2,0.3);
        renWin->SetSize(300,300);
    
        ///配置初始互动器,3D widget的输入被用来初始化widget的位置和比例。
        /// 当出现EndInteractionEvent事件时,将触发回调函数 SelectPolygons callback
        vtkSmartPointer<myCommand> callback=vtkSmartPointer<myCommand>::New();
        callback->setObject(boxWidget,selectActor,planes);
        boxWidget->SetInputConnection(glyph->GetOutputPort());
        boxWidget->PlaceWidget();
        boxWidget->AddObserver(vtkCommand::EndInteractionEvent,callback);
        iren->Initialize();
        renWin->Render();
        iren->Start();
        return 0;
    }
    

      

    5、vtkPlaneSource

    vtkPlaneSource 用于创建一个 m x n的四边形数组,这些四边形以像瓷砖一样贴在一个平面上。这个平面由原点和其它两个点来确定,在平面原点还定义了两个轴(axes)。这两个轴不必正交,但必须平行,这样可以方便你创建平行四边形。平面的分辨率(即,子区间的个数)通过变量XResolution and YResolution来控制。分别通过SetXResolutionSetYResolution两个方法实现分辨率的设置,相反的也可以通过GetXResolution、GetYResolution这两个方法获取这两个分辨率值。默认情况下,平面中心位于原点,与z-axis正交,平面的width和height为1,分辨率为1。

    There are three convenience methods that allow you to easily move the plane. The first, SetNormal(), allows you to specify the plane normal. The effect of this method is to rotate the plane around the center of the plane, aligning the plane normal with the specified normal. The rotation is about the axis defined by the cross product of the current normal with the new normal. The second, SetCenter(), translates the center of the plane to the specified center point. The third method, Push(), allows you to translate the plane along the plane normal by the distance specified. (Negative Push values translate the plane in the negative normal direction.) Note that the SetNormal()SetCenter() and Push() methods modify the Origin, Point1, and/or Point2 instance variables.

    该类中有三个便利的方法(即成员函数),帮助你很容易的移动平面。首先,SetNormal(), 允许你指定平面的法向量(plane normal)。这个方法的效果,就是使平面绕着平面中心转动,指向你所规定的方向。所谓的旋转,就是通过将当前平面的法向量与你所指定的法向量叉乘来实现的。第二,SetCenter(), 可以实现平面平移到你所指定的中心点坐标。第三, Push(), 是你能够将平面沿着法向量方向平移你所指定的距离,这是个非常有用的函数方法。如果Push的参数是负值,平面就沿着法向量的反方向移动。注意, SetNormal()SetCenter() and Push() 这三个方法,修改了Origin、Point1和Point2实例变量。

    注意:平面的法向量是由两个轴的叉乘得到的,这两个轴分别是Origin->Point1和Origin->Point2。This also affects the normals to the generated polygons.
    Examples:
    vtkPlaneSource (Examples)
    Tests:
    vtkPlaneSource (Tests)

     1 #ifndef INITIAL_OPENGL
     2 #define INITIAL_OPENGL
     3 #include <vtkAutoInit.h>
     4 VTK_MODULE_INIT(vtkRenderingOpenGL)
     5 VTK_MODULE_INIT(vtkInteractionStyle)
     6 #endif
     7 #include <iostream>
     8 using namespace std;
     9 #include <vtkVersion.h>
    10 #include <vtkPlaneSource.h>
    11 #include <vtkPolyData.h>
    12 #include <vtkSmartPointer.h>
    13 #include <vtkPolyDataMapper.h>
    14 #include <vtkActor.h>
    15 #include <vtkRenderWindow.h>
    16 #include <vtkRenderer.h>
    17 #include <vtkRenderWindowInteractor.h>
    18 
    19 int main()
    20 {
    21     //创建一个平面
    22     vtkSmartPointer<vtkPlaneSource>planeSource=vtkSmartPointer<vtkPlaneSource>::New();
    23     planeSource->SetCenter(1,0,0);
    24     planeSource->SetNormal(1,1,1);
    25     planeSource->Update();
    26 //planeSource会根据上面输入数据,创建PolyData对象,并通过GetOutput输出对象指针
    27     vtkSmartPointer<vtkPolyData> polydataPlane=vtkSmartPointer<vtkPolyData>::New();
    28     polydataPlane=planeSource->GetOutput();
    29     vtkSmartPointer<vtkPolyDataMapper> mapper=vtkSmartPointer<vtkPolyDataMapper>::New();
    30     mapper->SetInputData(polydataPlane);
    31     //创建演员
    32     vtkSmartPointer<vtkActor> actor=vtkSmartPointer<vtkActor>::New();
    33     actor->SetMapper(mapper);
    34 
    35 //创建显示窗口
    36     vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    37     vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    38     renderWindow->AddRenderer(renderer);
    39     vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    40     renderWindowInteractor->SetRenderWindow(renderWindow);
    41 
    42     // Add the actors to the scene
    43     renderer->AddActor(actor);
    44     renderer->SetBackground(.1,.2,.3); // Background color dark blue
    45 
    46     // Render and interact
    47     renderWindow->Render();
    48     renderWindowInteractor->Start();
    49     return 0;
    50 }
      
  • 相关阅读:
    正则只能输入数字小数点后保留4位
    redis基础之安装和配置
    IDEA 2017下载及注册码
    springcloud zuul 使用zuulfilter 修改请求路径和响应头
    JPA 多表分页查询
    springboot整合JPA创建数据库表失败
    springboot整合fastjson 将null转成空字符串
    Go 结构体和map等数据结构转json字符串
    go项目找不到包问题
    设计模式--策略模式
  • 原文地址:https://www.cnblogs.com/phoenixdsg/p/6241318.html
Copyright © 2011-2022 走看看