void frameConversion(vctFrm3 & result, const floatArray44 & input) {
    size_t row, col;
    for (row = 0; row < 3; row++) {
        for (col = 0; col < 3; col++) {
            result.Rotation().at(row, col) =  input[row][col];
        }
        result.Translation().at(row) = input[row][3];
    }
}
osaGLUTManipulator::osaGLUTManipulator(const std::vector<std::string>& geomfiles,
                      const vctFrm3& Rtw0,
                      const std::string& robotfn,
                      const vctDoubleVec& qinit,
                      const std::string& basefile,
                      bool rotateX90) :
  robManipulator(robotfn, 
                 vctFrame4x4<double>(Rtw0.Rotation(), Rtw0.Translation())),
  q(qinit),
  base(0)
{
    Initialize(geomfiles, basefile, rotateX90);
}
Ejemplo n.º 3
0
 double GetIntention(const vctFrm3 & cursorPosition) const {
     vct3 difference;
     difference.DifferenceOf(cursorPosition.Translation(), this->GetAbsoluteTransformation().Translation());
     double distance = difference.Norm();
     const double threshold = 5.0;  // in mm
     if (distance > threshold) {
         return 0.0;
     } else {
         return (1.0 - (distance / threshold));  // normalized between 0 and 1
     }
 }
Ejemplo n.º 4
0
void cisstAlgorithmICP_IMLP::UpdateNoiseModel_SamplesXfmd(vctFrm3 &Freg)
{
  // update noise models of the transformed sample points
  static vctRot3 R;
  R = Freg.Rotation();
  for (unsigned int s = 0; s < nSamples; s++)
  {
    R_Mxi_Rt[s] = R*Mxi[s] * R.Transpose();
  }
#ifdef DEBUG_IMLP
  std::cout << "ComputeParameters_PostReg():" << std::endl
    << "Mx0: " << std::endl << Mxi[0] << std::endl
    << "Mx1: " << std::endl << Mxi[1] << std::endl
    << "R_Mx0_Rt: " << std::endl << R_Mxi_Rt[0] << std::endl
    << "R_Mx1_Rt: " << std::endl << R_Mxi_Rt[1] << std::endl;
#endif
}
// Test intersection between an ellipsoid and oriented bounding box
//  Given an Ellipsoid defined by:   x'*Minv*x = NodeErrorBound
//  N is the decomposition of Minv:  Minv = N'*N
//  Dmin is the inverse sqrt of the largest eigenvalue of M (used for quick escape test)
//    Dmin = 1/sqrt(D[0])  where D = diag(D[0],D[1],D[2]) is the diagonal matrix of 
//    eigenvalues of M arranged largest to smallest
//    In other words, Dmin is the sqrt of the smallest eigenvalue of Minv
//  Note:  Minv = R*D^2*R' = N'*N     M = R*Dinv^2*R' => R' = V', Dinv = sqrt(S)
//         N = D*R'
//         Ninv = R*inv(D)
int Ellipsoid_OBB_Intersection_Solver::Test_Ellipsoid_OBB_Intersection( 
                                           const vct3 &v, 
                                           const BoundingBox &OBB, const vctFrm3 &Fobb,
                                           double NodeErrorBound,
                                           const  vct3x3 &N,
                                           double Dmin )
{
  // Algorithm is a modification of:
  //  Thomas Larsson, "An Efficient Ellipsoid-OBB Intersection Test"
  // 
  // Method:
  //  1) determine faces of oriented bounding box (OBB) visible from ellipse center
  //  2) affine transform to convert: ellipsoid -> sphere and OBB -> parallelpiped
  //  3) Sphere-Parallelpiped intersection test
  //
  // Define Bounding Box face indexes as:
  //  F1: X+  F2: X-
  //  F3: Y+  F4: Y-
  //  F5: Z+  F6: Z-
  //
  // Define Bounding Box vertex positions as:
  //   p[0] = m + Vx + Vy + Vz;       where  m = geometric center
  //   p[1] = m + Vx + Vy - Vz;             Vx = extent along local x axis (Vy & Vz similar)
  //   p[2] = m + Vx - Vy + Vz;
  //   p[3] = m + Vx - Vy - Vz;
  //   p[4] = m - Vx + Vy + Vz;
  //   p[5] = m - Vx + Vy - Vz;
  //   p[6] = m - Vx - Vy + Vz;
  //   p[7] = m - Vx - Vy - Vz;
  //
  // Define edge numbering for each face as:
  //   Note:  edge numbers progress in counterclockwise order around
  //          each face, meaning adjacent edges on a face have adjacent numbers
  //          in the edge numbering assigned below:
  //
  //         Edge0   Edge1   Edge2   Edge3
  //   F1:  [p0,p2] [p2,p3] [p3,p1] [p1,p0]
  //   F2:  [p6,p4] [p4,p5] [p5,p7] [p7,p6]
  //   F3:  [p4,p0] [p0,p1] [p1,p5] [p5,p4]
  //   F4:  [p2,p6] [p6,p7] [p7,p3] [p3,p2]
  //   F5:  [p4,p6] [p6,p2] [p2,p0] [p0,p4]
  //   F6:  [p1,p3] [p3,p7] [p7,p5] [p5,p1]
  //
  //  Note:  to understand this code, it helps to draw a picture of a bounding box
  //         using the face, vertex, and edge numbering as defined above
  //  Note:  face, vertex, and edge numbers for parallelpiped elements are derived
  //         directly from the affine mapped bounding box elements
  //
  static vct3 Fv;
  static vctFrm3 Finv;
  static vct3x3 Ns;
  static vct3 m;
  static vct3 nx,ny,nz;
  static vct3 Vx_,Vy_,Vz_;
  static vct3 Vxpos,Vypos,Vzpos;
  static vct3 Vxneg,Vyneg,Vzneg;
  static vct3 m_Vxp, m_Vxn;
  static vct3 Vyp_Vzp, Vyp_Vzn, Vyn_Vzn, Vyn_Vzp;
  static vct3 Nx,Ny,Nz;
  static vct3 p0,p1,p2,p3,p4,p5,p6,p7;
  //static vct3x3 Anode_sphere;
  //static vct3 Tnode_sphere;
  //static vct3 Edge0Norm, Edge1Norm;
  double S0,S1,S2;
  int vsblFaces[3], numFacesProcessed, Fi;
  bool rv;
  
  double sqrtNodeErrorBound = sqrt(NodeErrorBound);


  // === Determine Visible Faces of OBB === //
  //  (and quick escape test)

  // Determine visible faces of OBB by projecting ellipsoid center
  //  onto each axis of the bounding box
  int numVsblFaces = 0;
  bool bVsblFaceFound = 0;
  Fv = Fobb*v;    // center of ellipsoid in OBB coords
  
#ifdef QUICK_ESCAPE_SPHERE
  // Quick Escape: Sphere projection
  //  project ellipsoid bounding sphere onto the node axis
  S0 = S1 = S2 = (sqrtNodeErrorBound/Dmin);
#else
  std::cout << "ERROR: quick escape by ellipsoid projection no longer supported" << std::endl;
  assert(0);
  //// Quick Escape: Ellipsoid projection
  ////  project ellipsoid itself onto the node axis
  //Ns = sqrtNodeErrorBound * NinvT * node->F.Rotation().Transpose();
  //// since we are working in the node coords, the projections
  ////  values are easy to compute as multiplications of
  ////  Ns and the standard axis unit vectors
  ////S0 = (Ns*vct3(1,0,0)).Norm();
  //S0 = Ns.Column(0).Norm();
  //S1 = Ns.Column(1).Norm();
  //S2 = Ns.Column(2).Norm();
#endif

  if (Fv[0] >= OBB.MaxCorner[0])
  { // Face Fx+ is visible from sample point
    if (Fv[0] > OBB.MaxCorner[0] + S0)
    { // visible face is out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 1;
  }
  else if (Fv[0] <= OBB.MinCorner[0])
  { // Face Fx- is visible
    if (Fv[0] < OBB.MinCorner[0] - S0)
    { // visible face out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 2;
  }    
  if (Fv[1] >= OBB.MaxCorner[1])
  { // Face Fy+ is visible
    if (Fv[1] > OBB.MaxCorner[1] + S1)
    { // visible face out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 3;
  }
  else if (Fv[1] <= OBB.MinCorner[1]) 
  { // Face Fy- is visible
    if (Fv[1] < OBB.MinCorner[1] - S1)
    { // visible face out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 4;
  }
  if (Fv[2] >= OBB.MaxCorner[2])
  { // Face Fz+ is visible
    if (Fv[2] > OBB.MaxCorner[2] + S2)
    { // visible face out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 5;
  }
  else if (Fv[2] <= OBB.MinCorner[2])
  { // Face Fz- is visible
    if (Fv[2] < OBB.MinCorner[2] - S2)
    { // visible face out-of-range
      return 0;
    }
    vsblFaces[numVsblFaces++] = 6;
  }
  if (numVsblFaces == 0)
  { // sample point lies w/in node => ellipsoid intersects OBB
    return 1;
  }


  //=== Affine Xfm Ellipsoid -> Sphere ===//

  // Apply affine transform to convert ellipsoid to a sphere 
  //  and convert OBB to a parallelpiped;
  //  then apply translation to move center of sphere to the origin
  Finv = Fobb.Inverse();
  nx = Finv.Rotation().Column(0);   // OBB axis in world coords
  ny = Finv.Rotation().Column(1);   //  ''
  nz = Finv.Rotation().Column(2);   //  ''
  m = Finv.Translation();           // OBB origin in world coords
  m = N*(m - v);                // OBB origin in sphere coords

  //// Transforms points from sphere coords to node coords [A,t]
  //Anode_sphere = node->F.Rotation()*Ninv;                       // affine
  //Tnode_sphere = node->F.Rotation()*v + node->F.Translation();  // offset

  // parallelpiped axis
  //  Note: axis unit vectors are no longer oriented to the face normals
  //        due to the skewed nature of the parallelpiped (i.e. due to affine skew)
  Vx_ = N*nx;     // affine xfmd OBB axis (do not make these unit vectors!)
  Vy_ = N*ny;
  Vz_ = N*nz;

  //  Note: we cannot assume that the OBB have equal extents along the +/- dir
  //        of each coordinate axis, because the origin for the node is based
  //        on statistics of a single vertex from each triangle.
  //        We may, however, assume that the extents are positive along each
  //        axis direction, i.e. that the origin lies within the node.
  Vxpos = OBB.MaxCorner[0]*Vx_;  // parallelpiped extents along each axis
  Vypos = OBB.MaxCorner[1]*Vy_;  //  ''
  Vzpos = OBB.MaxCorner[2]*Vz_;  //  ''
  Vxneg = OBB.MinCorner[0]*Vx_;  //  ''
  Vyneg = OBB.MinCorner[1]*Vy_;  //  ''
  Vzneg = OBB.MinCorner[2]*Vz_;  //  ''
  m_Vxp = m + Vxpos;              // precompute these for efficiency
  m_Vxn = m + Vxneg;              //  ''
  Vyp_Vzp = Vypos + Vzpos;        //  ''
  Vyp_Vzn = Vypos + Vzneg;        //  ''
  Vyn_Vzp = Vyneg + Vzpos;        //  ''
  Vyn_Vzn = Vyneg + Vzneg;        //  ''
  p0 = m_Vxp + Vyp_Vzp;           // parallelpiped vertices
  p1 = m_Vxp + Vyp_Vzn;           //  ''
  p2 = m_Vxp + Vyn_Vzp;           //  ''
  p3 = m_Vxp + Vyn_Vzn;           //  ''
  p4 = m_Vxn + Vyp_Vzp;           //  ''
  p5 = m_Vxn + Vyp_Vzn;           //  ''
  p6 = m_Vxn + Vyn_Vzp;           //  ''
  p7 = m_Vxn + Vyn_Vzn;           //  ''

  // face normals of parallelpiped
  Nx.Assign( vctCrossProduct(Vy_,Vz_).Normalized() );
  Ny.Assign( vctCrossProduct(Vz_,Vx_).Normalized() );
  Nz.Assign( vctCrossProduct(Vx_,Vy_).Normalized() );


  //=== Check for Sphere/Parallelpiped Intersection ===//

  // Check for Sphere-Parallelpiped Overlap
  //  Note: the code below assumes that visible faces are added to
  //        the queue in order from lowest to highest face index
  numFacesProcessed = 0;
  Fi = vsblFaces[numFacesProcessed++];
  
  //if (Fi == 1 || Fi == 2)
  //{ 
    // compute in-plane edge normals for this face pair
    //  Note: these need not be unit vectors
    //Edge0Norm =  Nz - vctDotProduct(Nz,Nx)*Nx;  // in-plane component of Nz
    //Edge1Norm = -Ny + vctDotProduct(Ny,Nx)*Nx;  // in-plane component of -Ny
    if (Fi == 1)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( Nx, p0,p2,p3,p1,
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //Edge0Norm,Edge1Norm,-Edge0Norm,-Edge1Norm,
      if (rv) return 1;
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
      Fi = vsblFaces[numFacesProcessed++];
    }
    if (Fi == 2)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( -Nx, p6,p4,p5,p7,
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //Edge0Norm,-Edge1Norm,-Edge0Norm,Edge1Norm,
      if (rv) return 1;
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
      Fi = vsblFaces[numFacesProcessed++];
    }
  //}
  //if (Fi == 3 || Fi == 4)
  //{ 
    // compute in-plane edge normals for this face pair
    //  Note: these need not be unit vectors
    //Edge0Norm = Nz - vctDotProduct(Nz,Ny)*Ny; // in-plane component of Nz
    //Edge1Norm = Nx - vctDotProduct(Nx,Ny)*Ny; // in-plane component of Nx
    if (Fi == 3)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( Ny, p4,p0,p1,p5,
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //Edge0Norm,Edge1Norm,-Edge0Norm,-Edge1Norm,
      if (rv){
        //std::cout << "--> Intersection" << std::endl; 
        return 1;
      }
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
      Fi = vsblFaces[numFacesProcessed++];
    }
    if (Fi == 4)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( -Ny, p2,p6,p7,p3,
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //Edge0Norm,-Edge1Norm,-Edge0Norm,Edge1Norm,
      if (rv) return 1;
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
      Fi = vsblFaces[numFacesProcessed++];
    }
  //}
  //if (Fi == 5 || Fi == 6)
  //{ 
    // compute in-plane edge normals for this face pair
    //  Note: these need not be unit vectors
    //Edge0Norm = -Nx + vctDotProduct(Nx,Nz)*Nz;  // in-plane component of -Nx
    //Edge1Norm = -Ny + vctDotProduct(Ny,Nz)*Nz;  // in-plane component of -Ny
    if (Fi == 5)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( Nz, p4,p6,p2,p0,
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //Edge0Norm,Edge1Norm,-Edge0Norm,-Edge1Norm,
      if (rv) return 1;
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
      Fi = vsblFaces[numFacesProcessed++];
    }
    if (Fi == 6)
    { // check sphere-face intersection
      rv = IntersectionSphereFace( -Nz, p1,p3,p7,p5,                                   
                                   sqrtNodeErrorBound, NodeErrorBound);
                                   //-Edge0Norm,Edge1Norm,Edge0Norm,-Edge1Norm,
      if (rv) return 1;
      // no intersection => get next visible face
      if (numFacesProcessed == numVsblFaces) return 0;
    }
  //}

  // should never arrive here
    std::cout << "ERROR: execution should never arrive here" << std::endl;
  assert(0);
  return 0;
}