예제 #1
0
void 
PlaneGeometry::InitializePlane( const Point3D &origin,
  const Vector3D &normal )
{
  VnlVector rightVectorVnl(3), downVectorVnl;

  if( Equal( normal[1], 0.0f ) == false )
  {
    FillVector3D( rightVectorVnl, 1.0f, -normal[0]/normal[1], 0.0f ); 
    rightVectorVnl.normalize();
  }
  else
  {
    FillVector3D( rightVectorVnl, 0.0f, 1.0f, 0.0f );
  }
  downVectorVnl = vnl_cross_3d( normal.Get_vnl_vector(), rightVectorVnl );
  downVectorVnl.normalize();

  InitializeStandardPlane( rightVectorVnl, downVectorVnl );

  SetOrigin(origin);
}
예제 #2
0
  void
  PlaneGeometry::InitializeStandardPlane( mitk::ScalarType width, ScalarType height,
                                          const VnlVector &rightVector, const VnlVector &downVector,
                                          const Vector3D *spacing )
  {
    assert(width > 0);
    assert(height > 0);

    VnlVector rightDV = rightVector; rightDV.normalize();
    VnlVector downDV  = downVector;  downDV.normalize();
    VnlVector normal  = vnl_cross_3d(rightVector, downVector);
    normal.normalize();
    // Crossproduct vnl_cross_3d is always righthanded, but that is okay here
    // because in this method we create a new IndexToWorldTransform and
    // spacing with 1 or 3 negative components could still make it lefthanded.

    if(spacing!=nullptr)
    {
      rightDV *= (*spacing)[0];
      downDV  *= (*spacing)[1];
      normal  *= (*spacing)[2];
    }

    AffineTransform3D::Pointer transform = AffineTransform3D::New();
    Matrix3D matrix;
    matrix.GetVnlMatrix().set_column(0, rightDV);
    matrix.GetVnlMatrix().set_column(1, downDV);
    matrix.GetVnlMatrix().set_column(2, normal);
    transform->SetMatrix(matrix);
    transform->SetOffset(this->GetIndexToWorldTransform()->GetOffset());

    ScalarType bounds[6] = { 0, width, 0, height, 0, 1 };
    this->SetBounds( bounds );

    this->SetIndexToWorldTransform( transform );
  }
예제 #3
0
void mitk::ExtrudedContour::BuildGeometry()
{
  if(m_Contour.IsNull())
    return;

//  Initialize(1);

  Vector3D nullvector; nullvector.Fill(0.0);
  float xProj[3];
  unsigned int i;
  unsigned int numPts = 20; //m_Contour->GetNumberOfPoints();
  mitk::Contour::PathPointer path = m_Contour->GetContourPath();
  mitk::Contour::PathType::InputType cstart = path->StartOfInput();
  mitk::Contour::PathType::InputType cend   = path->EndOfInput();
  mitk::Contour::PathType::InputType cstep  = (cend-cstart)/numPts;
  mitk::Contour::PathType::InputType ccur;

  // Part I: guarantee/calculate legal vectors

  m_Vector.Normalize();
  itk2vtk(m_Vector, m_Normal);
  // check m_Vector
  if(mitk::Equal(m_Vector, nullvector) || m_AutomaticVectorGeneration)
  {
    if ( m_AutomaticVectorGeneration == false)
      itkWarningMacro("Extrusion vector is 0 ("<< m_Vector << "); trying to use normal of polygon");

    vtkPoints *loopPoints = vtkPoints::New();
    //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin();
    double vtkpoint[3];

    unsigned int i=0;
    for(i=0, ccur=cstart; i<numPts; ++i, ccur+=cstep)
    {
      itk2vtk(path->Evaluate(ccur), vtkpoint);
      loopPoints->InsertNextPoint(vtkpoint);
    }

    // Make sure points define a loop with a m_Normal
    vtkPolygon::ComputeNormal(loopPoints, m_Normal);
    loopPoints->Delete();

    vtk2itk(m_Normal, m_Vector);
    if(mitk::Equal(m_Vector, nullvector))
    {
      itkExceptionMacro("Cannot calculate normal of polygon");
    }
  }
  // check m_RightVector
  if((mitk::Equal(m_RightVector, nullvector)) || (mitk::Equal(m_RightVector*m_Vector, 0.0)==false))
  {
    if(mitk::Equal(m_RightVector, nullvector))
    {
      itkDebugMacro("Right vector is 0. Calculating.");
    }
    else
    {
      itkWarningMacro("Right vector ("<<m_RightVector<<") not perpendicular to extrusion vector "<<m_Vector<<": "<<m_RightVector*m_Vector);
    }
    // calculate a legal m_RightVector
    if( mitk::Equal( m_Vector[1], 0.0f ) == false )
    {
      FillVector3D( m_RightVector, 1.0f, -m_Vector[0]/m_Vector[1], 0.0f );
      m_RightVector.Normalize();
    }
    else
    {
      FillVector3D( m_RightVector, 0.0f, 1.0f, 0.0f );
    }
  }

  // calculate down-vector
  VnlVector rightDV = m_RightVector.GetVnlVector(); rightDV.normalize(); vnl2vtk(rightDV, m_Right);
  VnlVector downDV  = vnl_cross_3d( m_Vector.GetVnlVector(), rightDV ); downDV.normalize();  vnl2vtk(downDV,  m_Down);

  // Part II: calculate plane as base for extrusion, project the contour
  // on this plane and store as polygon for IsInside test and BoundingBox calculation

  // initialize m_ProjectionPlane, yet with origin at 0
  m_ProjectionPlane->InitializeStandardPlane(rightDV, downDV);

  // create vtkPolygon from contour and simultaneously determine 2D bounds of
  // contour projected on m_ProjectionPlane
  //mitk::Contour::PointsContainerIterator pointsIt = m_Contour->GetPoints()->Begin();
  m_Polygon->Points->Reset();
  m_Polygon->Points->SetNumberOfPoints(numPts);
  m_Polygon->PointIds->Reset();
  m_Polygon->PointIds->SetNumberOfIds(numPts);
  mitk::Point2D pt2d;
  mitk::Point3D pt3d;
  mitk::Point2D min, max;
  min.Fill(ScalarTypeNumericTraits::max());
  max.Fill(ScalarTypeNumericTraits::min());
  xProj[2]=0.0;
  for(i=0, ccur=cstart; i<numPts; ++i, ccur+=cstep)
  {
    pt3d.CastFrom(path->Evaluate(ccur));
    m_ProjectionPlane->Map(pt3d, pt2d);
    xProj[0]=pt2d[0];
    if(pt2d[0]<min[0]) min[0]=pt2d[0];
    if(pt2d[0]>max[0]) max[0]=pt2d[0];
    xProj[1]=pt2d[1];
    if(pt2d[1]<min[1]) min[1]=pt2d[1];
    if(pt2d[1]>max[1]) max[1]=pt2d[1];
    m_Polygon->Points->SetPoint(i, xProj);
    m_Polygon->PointIds->SetId(i, i);
  }
  // shift parametric origin to (0,0)
  for(i=0; i<numPts; ++i)
  {
    double * pt = this->m_Polygon->Points->GetPoint(i);

    pt[0]-=min[0]; pt[1]-=min[1];
    itkDebugMacro( << i << ": (" << pt[0] << "," << pt[1] << "," << pt[2] << ")" );
  }
  this->m_Polygon->GetBounds(m_ProjectedContourBounds);
  //m_ProjectedContourBounds[4]=-1.0; m_ProjectedContourBounds[5]=1.0;

  // calculate origin (except translation along the normal) and bounds
  // of m_ProjectionPlane:
  //  origin is composed of the minimum x-/y-coordinates of the polygon,
  //  bounds from the extent of the polygon, both after projecting on the plane
  mitk::Point3D origin;
  m_ProjectionPlane->Map(min, origin);
  ScalarType bounds[6]={0, max[0]-min[0], 0, max[1]-min[1], 0, 1};
  m_ProjectionPlane->SetBounds(bounds);
  m_ProjectionPlane->SetOrigin(origin);

  // Part III: initialize geometry
  if(m_ClippingGeometry.IsNotNull())
  {
    ScalarType min_dist=ScalarTypeNumericTraits::max(), max_dist=ScalarTypeNumericTraits::min(), dist;
    unsigned char i;
    for(i=0; i<8; ++i)
    {
      dist = m_ProjectionPlane->SignedDistance( m_ClippingGeometry->GetCornerPoint(i) );
      if(dist<min_dist) min_dist=dist;
      if(dist>max_dist) max_dist=dist;
    }
    //incorporate translation along the normal into origin
    origin = origin+m_Vector*min_dist;
    m_ProjectionPlane->SetOrigin(origin);
    bounds[5]=max_dist-min_dist;
  }
  else
    bounds[5]=20;

  itk2vtk(origin, m_Origin);

  mitk::Geometry3D::Pointer g3d = GetGeometry( 0 );
  assert( g3d.IsNotNull() );
  g3d->SetBounds(bounds);
  g3d->SetIndexToWorldTransform(m_ProjectionPlane->GetIndexToWorldTransform());
  g3d->TransferItkToVtkTransform();

  ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
  timeGeometry->Initialize(g3d,1);
  SetTimeGeometry(timeGeometry);

}
예제 #4
0
SEXP invariantSimilarityHelper(
  typename itk::Image< float , ImageDimension >::Pointer image1,
  typename itk::Image< float , ImageDimension >::Pointer image2,
  SEXP r_thetas, SEXP r_lsits, SEXP r_WM, SEXP r_scale,
  SEXP r_doreflection, SEXP r_txfn  )
{
  unsigned int mibins = 20;
  unsigned int localSearchIterations =
    Rcpp::as< unsigned int >( r_lsits ) ;
  std::string whichMetric = Rcpp::as< std::string >( r_WM );
  std::string txfn = Rcpp::as< std::string >( r_txfn );
  bool useprincaxis = true;
  typedef typename itk::ImageMaskSpatialObject<ImageDimension>::ImageType
    maskimagetype;
  typename maskimagetype::Pointer mask = ITK_NULLPTR;
  Rcpp::NumericVector thetas( r_thetas );
  Rcpp::NumericVector vector_r( r_thetas ) ;
  Rcpp::IntegerVector dims( 1 );
  Rcpp::IntegerVector doReflection( r_doreflection );
  unsigned int vecsize = thetas.size();
  dims[0]=0;
  typedef float  PixelType;
  typedef double RealType;
  RealType bestscale = Rcpp::as< RealType >( r_scale ) ;
  typedef itk::Image< PixelType , ImageDimension > ImageType;
  if( image1.IsNotNull() & image2.IsNotNull() )
    {
    typedef typename itk::ImageMomentsCalculator<ImageType> ImageCalculatorType;
    typedef itk::AffineTransform<RealType, ImageDimension> AffineType0;
    typedef itk::AffineTransform<RealType, ImageDimension> AffineType;
    typedef typename ImageCalculatorType::MatrixType       MatrixType;
    typedef itk::Vector<float, ImageDimension>  VectorType;
    VectorType ccg1;
    VectorType cpm1;
    MatrixType cpa1;
    VectorType ccg2;
    VectorType cpm2;
    MatrixType cpa2;
    typename ImageCalculatorType::Pointer calculator1 =
      ImageCalculatorType::New();
    typename ImageCalculatorType::Pointer calculator2 =
      ImageCalculatorType::New();
    calculator1->SetImage(  image1 );
    calculator2->SetImage(  image2 );
    typename ImageCalculatorType::VectorType fixed_center;
    fixed_center.Fill(0);
    typename ImageCalculatorType::VectorType moving_center;
    moving_center.Fill(0);
    try
      {
      calculator1->Compute();
      fixed_center = calculator1->GetCenterOfGravity();
      ccg1 = calculator1->GetCenterOfGravity();
      cpm1 = calculator1->GetPrincipalMoments();
      cpa1 = calculator1->GetPrincipalAxes();
      try
        {
        calculator2->Compute();
        moving_center = calculator2->GetCenterOfGravity();
        ccg2 = calculator2->GetCenterOfGravity();
        cpm2 = calculator2->GetPrincipalMoments();
        cpa2 = calculator2->GetPrincipalAxes();
        }
      catch( ... )
        {
        fixed_center.Fill(0);
        }
      }
    catch( ... )
      {
      // Rcpp::Rcerr << " zero image1 error ";
      }
    if ( vnl_math_abs( bestscale - 1.0 ) < 1.e-6 )
      {
      RealType volelt1 = 1;
      RealType volelt2 = 1;
      for ( unsigned int d=0; d<ImageDimension; d++)
        {
        volelt1 *= image1->GetSpacing()[d];
        volelt2 *= image2->GetSpacing()[d];
        }
      bestscale =
        ( calculator2->GetTotalMass() * volelt2 )/
        ( calculator1->GetTotalMass() * volelt1 );
      RealType powlev = 1.0 / static_cast<RealType>(ImageDimension);
      bestscale = vcl_pow( bestscale , powlev );
    }
    unsigned int eigind1 = 1;
    unsigned int eigind2 = 1;
    if( ImageDimension == 3 )
      {
      eigind1 = 2;
      }
    typedef vnl_vector<RealType> EVectorType;
    typedef vnl_matrix<RealType> EMatrixType;
    EVectorType evec1_2ndary = cpa1.GetVnlMatrix().get_row( eigind2 );
    EVectorType evec1_primary = cpa1.GetVnlMatrix().get_row( eigind1 );
    EVectorType evec2_2ndary  = cpa2.GetVnlMatrix().get_row( eigind2 );
    EVectorType evec2_primary = cpa2.GetVnlMatrix().get_row( eigind1 );
    /** Solve Wahba's problem http://en.wikipedia.org/wiki/Wahba%27s_problem */
    EMatrixType B = outer_product( evec2_primary, evec1_primary );
    if( ImageDimension == 3 )
      {
      B = outer_product( evec2_2ndary, evec1_2ndary )
        + outer_product( evec2_primary, evec1_primary );
      }
    vnl_svd<RealType>    wahba( B );
    vnl_matrix<RealType> A_solution = wahba.V() * wahba.U().transpose();
    A_solution = vnl_inverse( A_solution );
    RealType det = vnl_determinant( A_solution  );
    if( ( det < 0 ) )
      {
      vnl_matrix<RealType> id( A_solution );
      id.set_identity();
      for( unsigned int i = 0; i < ImageDimension; i++ )
        {
        if( A_solution( i, i ) < 0 )
          {
          id( i, i ) = -1.0;
          }
        }
      A_solution =  A_solution * id.transpose();
      }
    if ( doReflection[0] == 1 ||  doReflection[0] == 3 )
      {
        vnl_matrix<RealType> id( A_solution );
        id.set_identity();
        id = id - 2.0 * outer_product( evec2_primary , evec2_primary  );
        A_solution = A_solution * id;
      }
    if ( doReflection[0] > 1 )
      {
        vnl_matrix<RealType> id( A_solution );
        id.set_identity();
        id = id - 2.0 * outer_product( evec1_primary , evec1_primary  );
        A_solution = A_solution * id;
      }
    typename AffineType::Pointer affine1 = AffineType::New();
    typename AffineType::OffsetType trans = affine1->GetOffset();
    itk::Point<RealType, ImageDimension> trans2;
    for( unsigned int i = 0; i < ImageDimension; i++ )
      {
      trans[i] = moving_center[i] - fixed_center[i];
      trans2[i] =  fixed_center[i] * ( 1 );
      }
    affine1->SetIdentity();
    affine1->SetOffset( trans );
    if( useprincaxis )
      {
      affine1->SetMatrix( A_solution );
      }
    affine1->SetCenter( trans2 );
    if( ImageDimension > 3  )
      {
      return EXIT_SUCCESS;
      }
    vnl_vector<RealType> evec_tert;
    if( ImageDimension == 3 )
      { // try to rotate around tertiary and secondary axis
      evec_tert = vnl_cross_3d( evec1_primary, evec1_2ndary );
      }
    if( ImageDimension == 2 )
      { // try to rotate around tertiary and secondary axis
      evec_tert = evec1_2ndary;
      evec1_2ndary = evec1_primary;
      }
    itk::Vector<RealType, ImageDimension> axis2;
    itk::Vector<RealType, ImageDimension> axis1;
    for( unsigned int d = 0; d < ImageDimension; d++ )
      {
      axis1[d] = evec_tert[d];
      axis2[d] = evec1_2ndary[d];
      }
    typename AffineType::Pointer simmer = AffineType::New();
    simmer->SetIdentity();
    simmer->SetCenter( trans2 );
    simmer->SetOffset( trans );
    typename AffineType0::Pointer affinesearch = AffineType0::New();
    affinesearch->SetIdentity();
    affinesearch->SetCenter( trans2 );
    typedef  itk::MultiStartOptimizerv4         OptimizerType;
    typename OptimizerType::MetricValuesListType metricvalues;
    typename OptimizerType::Pointer  mstartOptimizer = OptimizerType::New();
    typedef itk::CorrelationImageToImageMetricv4
      <ImageType, ImageType, ImageType> GCMetricType;
    typedef itk::MattesMutualInformationImageToImageMetricv4
      <ImageType, ImageType, ImageType> MetricType;
    typename MetricType::ParametersType newparams(  affine1->GetParameters() );
    typename GCMetricType::Pointer gcmetric = GCMetricType::New();
    gcmetric->SetFixedImage( image1 );
    gcmetric->SetVirtualDomainFromImage( image1 );
    gcmetric->SetMovingImage( image2 );
    gcmetric->SetMovingTransform( simmer );
    gcmetric->SetParameters( newparams );
    typename MetricType::Pointer mimetric = MetricType::New();
    mimetric->SetNumberOfHistogramBins( mibins );
    mimetric->SetFixedImage( image1 );
    mimetric->SetMovingImage( image2 );
    mimetric->SetMovingTransform( simmer );
    mimetric->SetParameters( newparams );
    if( mask.IsNotNull() )
      {
      typename itk::ImageMaskSpatialObject<ImageDimension>::Pointer so =
        itk::ImageMaskSpatialObject<ImageDimension>::New();
      so->SetImage( const_cast<maskimagetype *>( mask.GetPointer() ) );
      mimetric->SetFixedImageMask( so );
      gcmetric->SetFixedImageMask( so );
      }
    typedef  itk::ConjugateGradientLineSearchOptimizerv4 LocalOptimizerType;
    typename LocalOptimizerType::Pointer  localoptimizer =
      LocalOptimizerType::New();
    RealType     localoptimizerlearningrate = 0.1;
    localoptimizer->SetLearningRate( localoptimizerlearningrate );
    localoptimizer->SetMaximumStepSizeInPhysicalUnits(
      localoptimizerlearningrate );
    localoptimizer->SetNumberOfIterations( localSearchIterations );
    localoptimizer->SetLowerLimit( 0 );
    localoptimizer->SetUpperLimit( 2 );
    localoptimizer->SetEpsilon( 0.1 );
    localoptimizer->SetMaximumLineSearchIterations( 50 );
    localoptimizer->SetDoEstimateLearningRateOnce( true );
    localoptimizer->SetMinimumConvergenceValue( 1.e-6 );
    localoptimizer->SetConvergenceWindowSize( 5 );
    if( true )
      {
      typedef typename MetricType::FixedSampledPointSetType PointSetType;
      typedef typename PointSetType::PointType              PointType;
      typename PointSetType::Pointer      pset(PointSetType::New());
      unsigned int ind=0;
      unsigned int ct=0;
      itk::ImageRegionIteratorWithIndex<ImageType> It(image1,
        image1->GetLargestPossibleRegion() );
      for( It.GoToBegin(); !It.IsAtEnd(); ++It )
        {
        // take every N^th point
        if ( ct % 10 == 0  )
          {
          PointType pt;
          image1->TransformIndexToPhysicalPoint( It.GetIndex(), pt);
          pset->SetPoint(ind, pt);
          ind++;
          }
          ct++;
        }
      mimetric->SetFixedSampledPointSet( pset );
      mimetric->SetUseFixedSampledPointSet( true );
      gcmetric->SetFixedSampledPointSet( pset );
      gcmetric->SetUseFixedSampledPointSet( true );
    }
    if ( whichMetric.compare("MI") == 0  ) {
      mimetric->Initialize();
      typedef itk::RegistrationParameterScalesFromPhysicalShift<MetricType>
      RegistrationParameterScalesFromPhysicalShiftType;
      typename RegistrationParameterScalesFromPhysicalShiftType::Pointer
      shiftScaleEstimator =
      RegistrationParameterScalesFromPhysicalShiftType::New();
      shiftScaleEstimator->SetMetric( mimetric );
      shiftScaleEstimator->SetTransformForward( true );
      typename RegistrationParameterScalesFromPhysicalShiftType::ScalesType
      movingScales( simmer->GetNumberOfParameters() );
      shiftScaleEstimator->EstimateScales( movingScales );
      mstartOptimizer->SetScales( movingScales );
      mstartOptimizer->SetMetric( mimetric );
      localoptimizer->SetMetric( mimetric );
      localoptimizer->SetScales( movingScales );
    }
    if ( whichMetric.compare("MI") != 0  ) {
      gcmetric->Initialize();
      typedef itk::RegistrationParameterScalesFromPhysicalShift<GCMetricType>
        RegistrationParameterScalesFromPhysicalShiftType;
      typename RegistrationParameterScalesFromPhysicalShiftType::Pointer
        shiftScaleEstimator =
        RegistrationParameterScalesFromPhysicalShiftType::New();
      shiftScaleEstimator->SetMetric( gcmetric );
      shiftScaleEstimator->SetTransformForward( true );
      typename RegistrationParameterScalesFromPhysicalShiftType::ScalesType
      movingScales( simmer->GetNumberOfParameters() );
      shiftScaleEstimator->EstimateScales( movingScales );
      mstartOptimizer->SetScales( movingScales );
      mstartOptimizer->SetMetric( gcmetric );
      localoptimizer->SetMetric( gcmetric );
      localoptimizer->SetScales( movingScales );
    }
    typename OptimizerType::ParametersListType parametersList =
      mstartOptimizer->GetParametersList();
    affinesearch->SetIdentity();
    affinesearch->SetCenter( trans2 );
    affinesearch->SetOffset( trans );
    for ( unsigned int i = 0; i < vecsize; i++ )
      {
      RealType ang1 = thetas[i];
      RealType ang2 = 0; // FIXME should be psi
      vector_r[ i ]=0;
      if( ImageDimension == 3 )
        {
        for ( unsigned int jj = 0; jj < vecsize; jj++ )
        {
        ang2=thetas[jj];
        affinesearch->SetIdentity();
        affinesearch->SetCenter( trans2 );
        affinesearch->SetOffset( trans );
        if( useprincaxis )
          {
          affinesearch->SetMatrix( A_solution );
          }
        affinesearch->Rotate3D(axis1, ang1, 1);
        affinesearch->Rotate3D(axis2, ang2, 1);
        affinesearch->Scale( bestscale );
        simmer->SetMatrix(  affinesearch->GetMatrix() );
        parametersList.push_back( simmer->GetParameters() );
        }
        }
      if( ImageDimension == 2 )
        {
        affinesearch->SetIdentity();
        affinesearch->SetCenter( trans2 );
        affinesearch->SetOffset( trans );
        if( useprincaxis )
          {
          affinesearch->SetMatrix( A_solution );
          }
        affinesearch->Rotate2D( ang1, 1);
        affinesearch->Scale( bestscale );
        simmer->SetMatrix(  affinesearch->GetMatrix() );
        typename AffineType::ParametersType pp =
          simmer->GetParameters();
        //pp[1]=ang1;
        //pp[0]=bestscale;
        parametersList.push_back( simmer->GetParameters() );
        }
      }
    mstartOptimizer->SetParametersList( parametersList );
    if( localSearchIterations > 0 )
      {
      mstartOptimizer->SetLocalOptimizer( localoptimizer );
      }
    mstartOptimizer->StartOptimization();
    typename AffineType::Pointer bestaffine = AffineType::New();
    bestaffine->SetCenter( trans2 );
    bestaffine->SetParameters( mstartOptimizer->GetBestParameters() );
    if ( txfn.length() > 3 )
      {
      typename AffineType::Pointer bestaffine = AffineType::New();
      bestaffine->SetCenter( trans2 );
      bestaffine->SetParameters( mstartOptimizer->GetBestParameters() );
      typedef itk::TransformFileWriter TransformWriterType;
      typename TransformWriterType::Pointer transformWriter =
        TransformWriterType::New();
      transformWriter->SetInput( bestaffine );
      transformWriter->SetFileName( txfn.c_str() );
      transformWriter->Update();
      }
    metricvalues = mstartOptimizer->GetMetricValuesList();
    for ( unsigned int k = 0; k < metricvalues.size(); k++ )
      {
      vector_r[k] = metricvalues[k];
      }
    dims[0] = vecsize;
    vector_r.attr( "dim" ) = vecsize;
    return Rcpp::wrap( vector_r );
    }
  else
    {
    return Rcpp::wrap( vector_r );
    }
}
예제 #5
0
void SlicesRotator::RotateToPoint( SliceNavigationController *rotationPlaneSNC,
                                   SliceNavigationController *rotatedPlaneSNC,
                                   const Point3D &point, bool linked )
{
    MITK_WARN << "Deprecated function! Use SliceNavigationController::ReorientSlices() instead";

    SliceNavigationController *thirdSNC = NULL;

    SNCVector::iterator iter;
    for ( iter = m_RotatableSNCs.begin(); iter != m_RotatableSNCs.end(); ++iter )
    {
        if ( ((*iter) != rotationPlaneSNC)
                && ((*iter) != rotatedPlaneSNC) )
        {
            thirdSNC = *iter;
            break;
        }
    }

    if ( thirdSNC == NULL )
    {
        return;
    }

    const PlaneGeometry *rotationPlane = rotationPlaneSNC->GetCurrentPlaneGeometry();
    const PlaneGeometry *rotatedPlane = rotatedPlaneSNC->GetCurrentPlaneGeometry();
    const PlaneGeometry *thirdPlane = thirdSNC->GetCurrentPlaneGeometry();

    if ( (rotationPlane == NULL) || (rotatedPlane == NULL)
            || (thirdPlane == NULL) )
    {
        return;
    }

    if ( rotatedPlane->DistanceFromPlane( point ) < 0.001 )
    {
        // Skip irrelevant rotations
        return;
    }

    Point3D projectedPoint;
    Line3D intersection;
    Point3D rotationCenter;

    if ( !rotationPlane->Project( point, projectedPoint )
            || !rotationPlane->IntersectionLine( rotatedPlane, intersection )
            || !thirdPlane->IntersectionPoint( intersection, rotationCenter ) )
    {
        return;
    }

    // All pre-requirements are met; execute the rotation

    Point3D referencePoint = intersection.Project( projectedPoint );

    Vector3D toProjected = referencePoint - rotationCenter;
    Vector3D toCursor    = projectedPoint - rotationCenter;

    // cross product: | A x B | = |A| * |B| * sin(angle)
    Vector3D axisOfRotation;
    vnl_vector_fixed< ScalarType, 3 > vnlDirection =
        vnl_cross_3d( toCursor.GetVnlVector(), toProjected.GetVnlVector() );
    axisOfRotation.SetVnlVector( vnlDirection );

    // scalar product: A * B = |A| * |B| * cos(angle)
    // tan = sin / cos
    ScalarType angle = - atan2(
                           (double)(axisOfRotation.GetNorm()),
                           (double)(toCursor * toProjected) );
    angle *= 180.0 / vnl_math::pi;

    // create RotationOperation and apply to all SNCs that should be rotated
    RotationOperation op(OpROTATE, rotationCenter, axisOfRotation, angle);

    if ( !linked )
    {
        BaseRenderer *renderer = rotatedPlaneSNC->GetRenderer();
        if ( renderer == NULL )
        {
            return;
        }

        DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();

        Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
        displayGeometry->Map( rotationCenter, point2DWorld );
        displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );

        TimeGeometry *timeGeometry= rotatedPlaneSNC->GetCreatedWorldGeometry();
        if ( !timeGeometry )
        {
            return;
        }

        timeGeometry->ExecuteOperation( &op );

        displayGeometry->Map( rotationCenter, point2DWorld );
        displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
        Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;

        //Vector2D origin = displayGeometry->GetOriginInMM();

        displayGeometry->MoveBy( vector2DDisplayDiff );

        rotatedPlaneSNC->SendCreatedWorldGeometryUpdate();
    }
    else
    {
        SNCVector::iterator iter;
        for ( iter = m_RotatableSNCs.begin(); iter != m_RotatableSNCs.end(); ++iter )
        {
            BaseRenderer *renderer = (*iter)->GetRenderer();
            if ( renderer == NULL )
            {
                continue;
            }

            DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();

            Point2D point2DWorld, point2DDisplayPre, point2DDisplayPost;
            displayGeometry->Map( rotationCenter, point2DWorld );
            displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPre );

            TimeGeometry* timeGeometry = (*iter)->GetCreatedWorldGeometry();
            if ( !timeGeometry )
            {
                continue;
            }

            timeGeometry->ExecuteOperation( &op );

            displayGeometry->Map( rotationCenter, point2DWorld );
            displayGeometry->WorldToDisplay( point2DWorld, point2DDisplayPost );
            Vector2D vector2DDisplayDiff = point2DDisplayPost - point2DDisplayPre;

            //Vector2D origin = displayGeometry->GetOriginInMM();

            displayGeometry->MoveBy( vector2DDisplayDiff );

            (*iter)->SendCreatedWorldGeometryUpdate();
        }
    }
} // end RotateToPoint
예제 #6
0
bool SlicesRotator::DoRotationStep(Action*, const StateEvent* e)
{
    const DisplayPositionEvent* posEvent = dynamic_cast<const DisplayPositionEvent*>(e->GetEvent());
    if (!posEvent) return false;

    Point3D cursor = posEvent->GetWorldPosition();

    Vector3D toProjected = m_LastCursorPosition - m_CenterOfRotation;
    Vector3D toCursor    = cursor - m_CenterOfRotation;

    // cross product: | A x B | = |A| * |B| * sin(angle)
    Vector3D axisOfRotation;
    vnl_vector_fixed< ScalarType, 3 > vnlDirection = vnl_cross_3d( toCursor.GetVnlVector(), toProjected.GetVnlVector() );
    axisOfRotation.SetVnlVector(vnlDirection);

    // scalar product: A * B = |A| * |B| * cos(angle)
    // tan = sin / cos
    ScalarType angle = - atan2( (double)(axisOfRotation.GetNorm()), (double)(toCursor * toProjected) );
    angle *= 180.0 / vnl_math::pi;
    m_LastCursorPosition = cursor;

    // create RotationOperation and apply to all SNCs that should be rotated
    RotationOperation rotationOperation(OpROTATE, m_CenterOfRotation, axisOfRotation, angle);

    // iterate the OTHER slice navigation controllers: these are filled in DoDecideBetweenRotationAndSliceSelection
    for (SNCVector::iterator iter = m_SNCsToBeRotated.begin(); iter != m_SNCsToBeRotated.end(); ++iter)
    {
        //  - remember the center of rotation on the 2D display BEFORE rotation
        //  - execute rotation
        //  - calculate new center of rotation on 2D display
        //  - move display IF the center of rotation has moved slightly before and after rotation

        // DM 2012-10: this must probably be due to rounding errors only, right?
        //             We don't have documentation on if/why this code is needed
        BaseRenderer *renderer = (*iter)->GetRenderer();
        if ( !renderer ) continue;

        DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();

        Point2D rotationCenter2DWorld, point2DDisplayPreRotation, point2DDisplayPostRotation;
        displayGeometry->Map( m_CenterOfRotation, rotationCenter2DWorld );
        displayGeometry->WorldToDisplay( rotationCenter2DWorld, point2DDisplayPreRotation );

        TimeGeometry* timeGeometry = (*iter)->GetCreatedWorldGeometry();
        if (!timeGeometry) continue;

        timeGeometry->ExecuteOperation(&rotationOperation);

        displayGeometry->Map( m_CenterOfRotation, rotationCenter2DWorld );
        displayGeometry->WorldToDisplay( rotationCenter2DWorld, point2DDisplayPostRotation );
        Vector2D vector2DDisplayDiff = point2DDisplayPostRotation - point2DDisplayPreRotation;

        displayGeometry->MoveBy( vector2DDisplayDiff );

        (*iter)->SendCreatedWorldGeometryUpdate();
    }

    RenderingManager::GetInstance()->RequestUpdateAll();

    this->InvokeEvent( SliceRotationEvent() ); // notify listeners

    return true;
}