Exemple #1
0
  //---------------------------------------------------------------------------------------------------
  //  Public:   PerfectMatch
  //  Purpose:  Handles the degenerate case where v and this voxel
  //            have the same vertices.
  //---------------------------------------------------------------------------------------------------
  bool CXDMVoxel::PerfectMatch( const CXDMVoxel & v ) const
  {

    if ( v.nGeneration != this->nGeneration )
      return false;
    if ( v.bVoxelPointsUp != this->bVoxelPointsUp )
      return false;
  
    Float fError = fSideLength / Float( 10.0 ); 
  
    Bool pVertexMatch[3];

    for( Int i = 0; i < 3; i ++ )
    {
      pVertexMatch[i] = false;
      for( Int j = 0; j < 3; j ++ )
      {
        SVector3 oDisp = v.pVertex[i] - this->pVertex[j];
        if ( oDisp.GetLength() < fError )
          pVertexMatch[i] = true;
      }
    }
  
    return ( pVertexMatch[0] && pVertexMatch[1] && pVertexMatch[2] );
  }
Exemple #2
0
  //---------------------------------------------------------------------------------------------------
  //
  //  Private: CheckAxis
  //
  //  Return true if the axis perpendicular to u = v2 - v1 is a separating axis  (i.e., no overlap)
  //  Therefore, we project to this perpendicular axis
  //
  //  Currently only works with 2D objects on the x-y plane
  //
  //
  //---------------------------------------------------------------------------------------------------
  bool CXDMVoxel::CheckSeparatingAxis( const CXDMVoxel & oVoxel, const CXDMVoxel & oTestVoxel,
                                       const SVector3 &oV1, const SVector3 &oV2) const
  {
    SVector3 oDir = oV2 - oV1;
    oDir.Normalize();

    // rotate 90 degress y <- x, x <- -y
    Float tmp = oDir.m_fY;
    oDir.m_fY = oDir.m_fX;
    oDir.m_fX = - tmp;

    Float fMin = MAX_FLOAT;
    Float fMax = MIN_FLOAT;

    for ( int i = 0; i < 3; i ++ )
    {
      Float fAxisProjection = Dot( oTestVoxel.pVertex[i], oDir );

      if ( fAxisProjection < fMin )
        fMin = fAxisProjection;
      if ( fAxisProjection > fMax )
        fMax = fAxisProjection;
    }
  
    for ( int i = 0; i < 3; i ++ )
    {
      Float fVertex = Dot( oVoxel.pVertex[i], oDir );  
      if( fVertex <= fMax  && fVertex >= fMin )   // if intersecting
      {
        return false;
      }
    }
    return true;
  }
Exemple #3
0
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates)
Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v,
        double angle_current)
{
    // get the unit normal at that point
    GFace *face = dynamic_cast<GFace*>(gf);
    if(!face) {
        Msg::Error("Entity is not a face in background mesh");
        return Pair<SVector3,SVector3>(SVector3(), SVector3());
    }

    Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v));
    SVector3 s1 = der.first();
    SVector3 s2 = der.second();
    SVector3 n = crossprod(s1,s2);
    n.normalize();

    SVector3 basis_u = s1;
    basis_u.normalize();
    SVector3 basis_v = crossprod(n,basis_u);

    // normalize vector t1 that is tangent to gf at uv
    SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ;
    t1.normalize();

    // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame
    SVector3 t2 = crossprod(n,t1);
    t2.normalize();

    return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]),
                                   SVector3(t2[0],t2[1],t2[2]));
}
Exemple #4
0
double Filler::improvement(GEntity* ge,MElementOctree* octree,SPoint3 point,double h1,SVector3 direction){
  double x,y,z;
  double average;
  double h2;
  double coeffA,coeffB;

  x = point.x() + h1*direction.x();
  y = point.y() + h1*direction.y();
  z = point.z() + h1*direction.z();
  
  if(inside_domain(octree,x,y,z)){
    h2 = get_size(x,y,z);
  }
  else h2 = h1;

  coeffA = 1.0;
  coeffB = 0.16;
  
  if(h2>h1){
    average = coeffA*h1 + (1.0-coeffA)*h2;
  }
  else{
    average = coeffB*h1 + (1.0-coeffB)*h2;
  }
	
  return average;
}
Exemple #5
0
double distMaxStraight(MElement *el)
{
  const polynomialBasis *lagrange = (polynomialBasis*)el->getFunctionSpace();
  const polynomialBasis *lagrange1 = (polynomialBasis*)el->getFunctionSpace(1);
  int nV = lagrange->points.size1();
  int nV1 = lagrange1->points.size1();
  int dim = lagrange1->dimension;
  SPoint3 sxyz[256];
  for (int i = 0; i < nV1; ++i) {
    sxyz[i] = el->getVertex(i)->point();
  }
  for (int i = nV1; i < nV; ++i) {
    double f[256];
    lagrange1->f(lagrange->points(i, 0), lagrange->points(i, 1),
                 dim < 3 ? 0 : lagrange->points(i, 2), f);
    for (int j = 0; j < nV1; ++j)
      sxyz[i] += sxyz[j] * f[j];
  }

  double maxdx = 0.0;
  for (int iV = nV1; iV < nV; iV++) {
    SVector3 d = el->getVertex(iV)->point()-sxyz[iV];
    double dx = d.norm();
    if (dx > maxdx) maxdx = dx;
  }

  return maxdx;
}
SMetric3 max_edge_curvature_metric(const GVertex *gv)
{
  SMetric3 val (1.e-12);
  std::list<GEdge*> l_edges = gv->edges();
  for (std::list<GEdge*>::const_iterator ite = l_edges.begin();
       ite != l_edges.end(); ++ite){
    GEdge *_myGEdge = *ite;
    Range<double> range = _myGEdge->parBounds(0);
    SMetric3 cc;
    if (gv == _myGEdge->getBeginVertex()) {
      SVector3 t = _myGEdge->firstDer(range.low());
      t.normalize();
      double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.low()))
				*  CTX::instance()->mesh.minCircPoints ));
      double l_n = 1.e12;
      cc = buildMetricTangentToCurve(t,l_t,l_n);
    }
    else {
      SVector3 t = _myGEdge->firstDer(range.high());
      t.normalize();
      double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.high()))
				  *  CTX::instance()->mesh.minCircPoints ));
      double l_n = 1.e12;
      cc = buildMetricTangentToCurve(t,l_t,l_n);
    }
    val = intersection(val,cc);
  }
  return val;
}
SMetric3 metric_based_on_surface_curvature(const GFace *gf, double u, double v,
					   bool surface_isotropic,
					   double d_normal ,
					   double d_tangent_max)
{
  if (gf->geomType() == GEntity::Plane)return SMetric3(1.e-12);
  double cmax, cmin;
  SVector3 dirMax,dirMin;
  cmax = gf->curvatures(SPoint2(u, v),&dirMax, &dirMin, &cmax,&cmin);
  if (cmin == 0)cmin =1.e-12;
  if (cmax == 0)cmax =1.e-12;
  double lambda1 =  ((2 * M_PI) /( fabs(cmin) *  CTX::instance()->mesh.minCircPoints ) );
  double lambda2 =  ((2 * M_PI) /( fabs(cmax) *  CTX::instance()->mesh.minCircPoints ) );
  SVector3 Z = crossprod(dirMax,dirMin);
  if (surface_isotropic)  lambda2 = lambda1 = std::min(lambda2,lambda1);
  dirMin.normalize();
  dirMax.normalize();
  Z.normalize();
  lambda1 = std::max(lambda1, CTX::instance()->mesh.lcMin);
  lambda2 = std::max(lambda2, CTX::instance()->mesh.lcMin);
  lambda1 = std::min(lambda1, CTX::instance()->mesh.lcMax);
  lambda2 = std::min(lambda2, CTX::instance()->mesh.lcMax);
  double lambda3 = std::min(d_normal, CTX::instance()->mesh.lcMax);
  lambda3 = std::max(lambda3, CTX::instance()->mesh.lcMin);
  lambda1 = std::min(lambda1, d_tangent_max);
  lambda2 = std::min(lambda2, d_tangent_max);

  SMetric3 curvMetric (1./(lambda1*lambda1),1./(lambda2*lambda2),
		       1./(lambda3*lambda3),
                       dirMin, dirMax, Z );
  return curvMetric;
}
SMetric3 max_edge_curvature_metric(const GEdge *ge, double u)
{
  SVector3 t =  ge->firstDer(u);
  t.normalize();
  double l_t = ((2 * M_PI) /( fabs(ge->curvature(u))
			      *  CTX::instance()->mesh.minCircPoints ));
  double l_n = 1.e12;
  return buildMetricTangentToCurve(t,l_t,l_n);
}
Exemple #9
0
double angle3Vertices(const MVertex *p1, const MVertex *p2, const MVertex *p3)
{
  SVector3 a(p1->x() - p2->x(), p1->y() - p2->y(), p1->z() - p2->z());
  SVector3 b(p3->x() - p2->x(), p3->y() - p2->y(), p3->z() - p2->z());
  SVector3 c = crossprod(a, b);
  double sinA = c.norm();
  double cosA = dot(a, b);
  return atan2 (sinA, cosA);
}
Exemple #10
0
bool GEdge::XYZToU(const double X, const double Y, const double Z,
                   double &u, const double relax) const
{
  const int MaxIter = 25;
  const int NumInitGuess = 11;

  double err;//, err2;
  int iter;

  Range<double> uu = parBounds(0);
  double uMin = uu.low();
  double uMax = uu.high();

  SVector3 Q(X, Y, Z), P;

  double init[NumInitGuess];

  for (int i = 0; i < NumInitGuess; i++)
    init[i] = uMin + (uMax - uMin) / (NumInitGuess - 1) * i;

  for(int i = 0; i < NumInitGuess; i++){
    u = init[i];
    double uNew = u;
    //err2 = 1.0;
    iter = 1;

    SVector3 dPQ = P - Q;
    err = dPQ.norm();

    if (err < 1.e-8 * CTX::instance()->lc) return true;

    while(iter++ < MaxIter && err > 1e-8 * CTX::instance()->lc) {
      SVector3 der = firstDer(u);
      uNew = u - relax * dot(dPQ,der) / dot(der,der);
      uNew = std::min(uMax,std::max(uMin,uNew));
      P = position(uNew);

      dPQ = P - Q;
      err = dPQ.norm();
      //err2 = fabs(uNew - u);
      u = uNew;
    }

    if (err < 1e-8 * CTX::instance()->lc) return true;
  }

  if(relax > 1.e-2) {
    //    Msg::Info("point %g %g %g on edge %d : Relaxation factor = %g",
    //              Q.x(), Q.y(), Q.z(), 0.75 * relax);
    return XYZToU(Q.x(), Q.y(), Q.z(), u, 0.75 * relax);
  }

  //  Msg::Error("Could not converge reparametrisation of point (%e,%e,%e) on edge %d",
  //             Q.x(), Q.y(), Q.z(), tag());
  return false;
}
  //--------------------------------------------------------------------------------------------------------
  //
  //  GetAlignRotation
  //  -- Given *UNIT vector* oRef, oVec, return a matrix that rotates oVec -> oRef
  //
  //--------------------------------------------------------------------------------------------------------
  SMatrix3x3 GetAlignmentRotation( const SVector3 &oVecDir, const SVector3 &oRefDir )
  {
    
    SVector3 oAxis  = Cross( oVecDir, oRefDir );
    Float    fAngle = acos( Dot( oVecDir, oRefDir ) );

    oAxis.Normalize();
    SMatrix3x3 oRes;
    oRes.BuildRotationAboutAxis( oAxis, fAngle );
    return oRes;
  }
static void CalculateOrthoShadow( const CCameraEntity& cam, Light& light )
{
	SVector3 target = gCasterBounds.getCenter();
	SVector3 size = gCasterBounds.getMax() - gCasterBounds.getMin();
	float radius = size.length() * 0.5f;
	
	// figure out the light camera matrix that encloses whole scene
	light.mWorldMat.spaceFromAxisZ();
	light.mWorldMat.getOrigin() = target - light.mWorldMat.getAxisZ() * radius;
	light.setOrthoParams( radius*2, radius*2, radius*0.1f, radius*2 );
	light.setOntoRenderContext();
}
static void _relocateVertexOfPyramid(MVertex *ver,
                                     const std::vector<MElement *> &lt,
                                     double relax)
{
  if(ver->onWhat()->dim() != 3) return;
  double x = 0.0, y = 0.0, z = 0.0;
  int N = 0;
  MElement *pyramid = NULL;

  for(std::size_t i = 0; i < lt.size(); i++) {
    double XCG = 0.0, YCG = 0.0, ZCG = 0.0;
    if(lt[i]->getNumVertices() == 5)
      pyramid = lt[i];
    else {
      for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) {
        XCG += lt[i]->getVertex(j)->x();
        YCG += lt[i]->getVertex(j)->y();
        ZCG += lt[i]->getVertex(j)->z();
      }
      x += XCG;
      y += YCG;
      z += ZCG;
      N += lt[i]->getNumVertices();
    }
  }
  x /= N;
  y /= N;
  z /= N;

  if(pyramid) {
    MFace q = pyramid->getFace(4);
    double A = q.approximateArea();
    SVector3 n = q.normal();
    n.normalize();
    SPoint3 c = q.barycenter();
    SVector3 d(x - c.x(), y - c.y(), z - c.z());
    if(dot(n, d) < 0) n = n * (-1.0);
    double H = .5 * sqrt(fabs(A));
    double XOPT = c.x() + relax * H * n.x();
    double YOPT = c.y() + relax * H * n.y();
    double ZOPT = c.z() + relax * H * n.z();
    double FULL_MOVE_OBJ =
      objective_function(1.0, ver, XOPT, YOPT, ZOPT, lt, true);
    // printf("relax %g obj %g\n",relax,FULL_MOVE_OBJ);
    if(FULL_MOVE_OBJ > 0.1) {
      ver->x() = XOPT;
      ver->y() = YOPT;
      ver->z() = ZOPT;
      return;
    }
  }
}
SMetric3 buildMetricTangentToSurface(SVector3 &t1, SVector3 &t2,
                                     double l_t1, double l_t2, double l_n)
{
  t1.normalize();
  t2.normalize();
  SVector3 n = crossprod (t1,t2);
  n.normalize();

  l_t1 = std::max(l_t1, CTX::instance()->mesh.lcMin);
  l_t2 = std::max(l_t2, CTX::instance()->mesh.lcMin);
  l_t1 = std::min(l_t1, CTX::instance()->mesh.lcMax);
  l_t2 = std::min(l_t2, CTX::instance()->mesh.lcMax);
  SMetric3 Metric (1./(l_t1*l_t1),1./(l_t2*l_t2),1./(l_n*l_n),t1,t2,n);
  return Metric;
}
Exemple #15
0
int edge_normal
(const MVertex *const vertex, const int zoneIndex, const GEdge *const gEdge,
 const CCon::FaceVector<MZoneBoundary<2>::GlobalVertexData<MEdge>::FaceDataB>
 &faces, SVector3 &boNormal, const int onlyFace = -1)
{

  double par=0.0;
  // Note: const_cast used to match MVertex.cpp interface
  if(!reparamMeshVertexOnEdge(const_cast<MVertex*>(vertex), gEdge, par)) return 1;

  const SVector3 tangent(gEdge->firstDer(par));
                                        // Tangent to the boundary face
  SPoint3 interior(0., 0., 0.);         // An interior point
  SVector3 meshPlaneNormal(0.);         // This normal is perpendicular to the
                                        // plane of the mesh

  // The interior point and mesh plane normal are computed from all elements in
  // the zone.
  int cFace = 0;
  int iFace = 0;
  int nFace = faces.size();
  if ( onlyFace >= 0 ) {
    iFace = onlyFace;
    nFace = onlyFace + 1;
  }
  for(; iFace != nFace; ++iFace) {
    if(faces[iFace].zoneIndex == zoneIndex) {
      ++cFace;
      interior += faces[iFace].parentElement->barycenter();
      // Make sure all the planes go in the same direction
      //**Required?
      SVector3 mpnt = faces[iFace].parentElement->getFace(0).normal();
      if(dot(mpnt, meshPlaneNormal) < 0.) mpnt.negate();
      meshPlaneNormal += mpnt;
    }
  }
  interior /= cFace;
  // Normal to the boundary edge (but unknown direction)
  boNormal = crossprod(tangent, meshPlaneNormal);
  boNormal.normalize();
  // Direction vector from vertex to interior (inwards).  The normal should
  // point in the same direction.
  if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.)
    boNormal.negate();
  return 0;

}
 Bool Equivilent( const CSymmetryType & oSymOps, const SVector3 &v1, const SVector3 &v2, Float fError )
 {
   const vector<SMatrix3x3> &vOperatorList = oSymOps.GetOperatorList();
   
   for( Size_Type i = 0; i < vOperatorList.size(); i ++ )
   {
     SVector3 oTmp = vOperatorList[i] * v1;
     SVector3 oDiff = oTmp - v2;
     Float fDiff = oDiff.GetLength();
     
     if( fDiff < fError )
     {
       return true;
     }
   }
   return false;
 }
Exemple #17
0
double taylorDistanceSq1D(const GradientBasis *gb, const fullMatrix<double> &nodesXYZ,
                          const std::vector<SVector3> &tanCAD)
{
  const int nV = nodesXYZ.size1();
  fullMatrix<double> dxyzdX(nV, 3);
  gb->getGradientsFromNodes(nodesXYZ, &dxyzdX, 0, 0);
//  const double dx = nodesXYZ(1, 0) - nodesXYZ(0, 0), dy = nodesXYZ(1, 1) - nodesXYZ(0, 1),
//               dz = nodesXYZ(1, 2) - nodesXYZ(0, 2), h = 0.5*sqrt(dx*dx+dy*dy+dz*dz)/double(nV-1);
  double distSq = 0.;
  for (int i=0; i<nV; i++) {
    SVector3 tanMesh(dxyzdX(i, 0), dxyzdX(i, 1), dxyzdX(i, 2));
    const double h = 0.25*tanMesh.normalize();                                            // Half of "local edge length"
    SVector3 diff = (dot(tanCAD[i], tanMesh) > 0) ?
                    tanCAD[i] - tanMesh : tanCAD[i] + tanMesh;
    distSq += h*h*diff.normSq();
  }
  return distSq;
}
Exemple #18
0
double taylorDistanceSq2D(const GradientBasis *gb, const fullMatrix<double> &nodesXYZ,
                          const std::vector<SVector3> &normCAD)
{
  const int nV = nodesXYZ.size1();
  fullMatrix<double> dxyzdX(nV, 3), dxyzdY(nV, 3);
  gb->getGradientsFromNodes(nodesXYZ, &dxyzdX, &dxyzdY, 0);
  double distSq = 0.;
  for (int i=0; i<nV; i++) {
    const double nz = dxyzdX(i, 0) * dxyzdY(i, 1) - dxyzdX(i, 1) * dxyzdY(i, 0);
    const double ny = -dxyzdX(i, 0) * dxyzdY(i, 2) + dxyzdX(i, 2) * dxyzdY(i, 0);
    const double nx = dxyzdX(i, 1) * dxyzdY(i, 2) - dxyzdX(i, 2) * dxyzdY(i, 1);
    SVector3 normMesh(nx, ny, nz);
    const double h = 0.25*sqrt(normMesh.normalize());                                     // Half of sqrt of "local area", to be adjusted w.r.t. el. type?
    SVector3 diff = (dot(normCAD[i], normMesh) > 0) ?
                    normCAD[i] - normMesh : normCAD[i] + normMesh;
    distSq += h*h*diff.normSq();
  }
  return distSq;
}
void Centerline::buildKdTree()
{
  FILE * f = Fopen("myPOINTS.pos","w");
  fprintf(f, "View \"\"{\n");

  int nbPL = 3;  //10 points per line
  //int nbNodes  = (lines.size()+1) + (nbPL*lines.size());
  int nbNodes  = (colorp.size()) + (nbPL*lines.size());

  ANNpointArray nodes = annAllocPts(nbNodes, 3);
  int ind = 0;
  std::map<MVertex*, int>::iterator itp = colorp.begin();
  while (itp != colorp.end()){
     MVertex *v = itp->first;
     nodes[ind][0] = v->x();
     nodes[ind][1] = v->y();
     nodes[ind][2] = v->z();
     itp++; ind++;
  }
  for(unsigned int k = 0; k < lines.size(); ++k){
   MVertex *v0 = lines[k]->getVertex(0);
   MVertex *v1 = lines[k]->getVertex(1);
   SVector3 P0(v0->x(),v0->y(), v0->z());
   SVector3 P1(v1->x(),v1->y(), v1->z());
   for (int j= 1; j < nbPL+1; j++){
     double inc = (double)j/(double)(nbPL+1);
     SVector3 Pj = P0+inc*(P1-P0);
     nodes[ind][0] = Pj.x();
     nodes[ind][1] = Pj.y();
     nodes[ind][2] = Pj.z();
     ind++;
   }
 }

 kdtree = new ANNkd_tree(nodes, nbNodes, 3);

 for(int i = 0; i < nbNodes; ++i){
   fprintf(f, "SP(%g,%g,%g){%g};\n",
	   nodes[i][0], nodes[i][1],nodes[i][2],1.0);
 }
 fprintf(f,"};\n");
 fclose(f);
}
Exemple #20
0
void highOrderTools::computeMetricInfo(GFace *gf,
                                       MElement *e,
                                       fullMatrix<double> &J,
                                       fullMatrix<double> &JT,
                                       fullVector<double> &D)
{
  int nbNodes = e->getNumVertices();
  //  printf("ELEMENT --\n");
  for (int j = 0; j < nbNodes; j++){
    SPoint2 param;
    reparamMeshVertexOnFace(e->getVertex(j), gf, param);
    //    printf("%g %g vs %g %g %g\n",param.x(),param.y(),
    //	   e->getVertex(j)->x(),e->getVertex(j)->y(),e->getVertex(j)->z());

    Pair<SVector3,SVector3> der = gf->firstDer(param);

    int XJ = j;
    int YJ = j + nbNodes;
    int ZJ = j + 2 * nbNodes;
    int UJ = j;
    int VJ = j + nbNodes;
    J(XJ,UJ) = der.first().x();
    J(YJ,UJ) = der.first().y();
    J(ZJ,UJ) = der.first().z();
    J(XJ,VJ) = der.second().x();
    J(YJ,VJ) = der.second().y();
    J(ZJ,VJ) = der.second().z();

    JT(UJ,XJ) = der.first().x();
    JT(UJ,YJ) = der.first().y();
    JT(UJ,ZJ) = der.first().z();
    JT(VJ,XJ) = der.second().x();
    JT(VJ,YJ) = der.second().y();
    JT(VJ,ZJ) = der.second().z();

    SVector3 ss = getSSL(e->getVertex(j));
    GPoint gp = gf->point(param);
    D(XJ) = (gp.x() - ss.x());
    D(YJ) = (gp.y() - ss.y());
    D(ZJ) = (gp.z() - ss.z());
  }
}
Exemple #21
0
void MSubLine::getGradShapeFunctions(double u, double v, double w, double s[][3], int order) const
{
  if(!_orig)
    return;

  if (_orig->getDim()==getDim())
    return _orig->getGradShapeFunctions(u, v, w, s, order);

  int nsf = _orig->getNumShapeFunctions();
  double gradsuvw[1256][3];
  _orig->getGradShapeFunctions(u, v, w, gradsuvw, order);

  double jac[3][3];
  double invjac[3][3];
  _orig->getJacobian(u, v, w, jac);
  inv3x3(jac, invjac);
  MEdge edge = getBaseElement()->getEdge(0);
  SVector3 tang = edge.tangent();

  double gradxyz[3];
  double projgradxyz[3];
  for (int i=0; i<nsf; ++i)
  {
    // (i) get the cartesian coordinates of the gradient
    gradxyz[0] = invjac[0][0] * gradsuvw[i][0] + invjac[0][1] * gradsuvw[i][1] + invjac[0][2] * gradsuvw[i][2];
    gradxyz[1] = invjac[1][0] * gradsuvw[i][0] + invjac[1][1] * gradsuvw[i][1] + invjac[1][2] * gradsuvw[i][2];
    gradxyz[2] = invjac[2][0] * gradsuvw[i][0] + invjac[2][1] * gradsuvw[i][1] + invjac[2][2] * gradsuvw[i][2];

    // (ii) projection of the gradient on edges in the cartesian space
    SVector3 grad(&gradxyz[0]);
    double prodscal = dot(tang,grad);
    projgradxyz[0] = prodscal * tang.x();
    projgradxyz[1] = prodscal * tang.y();
    projgradxyz[2] = prodscal * tang.z();

    // (iii) get the parametric coordinates of the projection in the parametric space of the parent element
    s[i][0] = jac[0][0] * projgradxyz[0] + jac[0][1] * projgradxyz[1] + jac[0][2] * projgradxyz[2];
    s[i][1] = jac[1][0] * projgradxyz[0] + jac[1][1] * projgradxyz[1] + jac[1][2] * projgradxyz[2];
    s[i][2] = jac[2][0] * projgradxyz[0] + jac[2][1] * projgradxyz[1] + jac[2][2] * projgradxyz[2];
  }
}
Exemple #22
0
  //---------------------------------------------------------------------------------------------------
  //  MinDistance calculation
  //  --  clearly this could be optimized.  Let's get it right first.
  //
  //  Precondition:  All of the Z must be exactly the same!
  //
  //---------------------------------------------------------------------------------------------------
  bool CXDMVoxel::Connected( const SVector3 & oV1, const SVector3 & oV2,
                             const SVector3 & p, Float fError )
  {
    SVector3 oDist_Top = p - oV2;
    SVector3 oDist = p - oV1;
    oDist_Top.m_fZ = 0;   // zeroing out the out of plane components
    oDist.m_fZ     = 0;
    // check for vertex overlap
    if ( (    fabs( oDist_Top.m_fX ) < fError
           && fabs( oDist_Top.m_fY ) < fError
         )
      ||
         (    fabs( oDist.m_fX ) < fError
           && fabs( oDist.m_fY ) < fError
         )
       )
    {
      return true;
    }
    
    SVector3 oLine = oV2 - oV1;
    oLine.m_fZ = 0;
    Float    fLineLength = oLine.GetLength();
    DEBUG_ASSERT( fLineLength > std::numeric_limits<Float>::epsilon(),
                  "CXDMVoxel:: MinDistance: numerical limit reached for this floaing point numbers\n" ); 

    SVector3 oLineDir = oLine / fLineLength;
    Float    fProjected = Dot( oDist, oLineDir );
    if( fProjected < 0 || fProjected > fLineLength )
      return false;
    
    SVector3 oPerpDir( -oLineDir.m_fY, oLineDir.m_fX, oLineDir.m_fZ );
    Float fPerpDist = Dot( oDist, oPerpDir );
    return ( fabs(fPerpDist) < fError );

//----------------------------------------
//  -- Also correct, but I'm afraid of dividing and sqrt-ing very small numbers
//     SVector3 oDistPerp = oDist - fProjected * oLineDir;
//     return ( oDistPerp.GetLength() < fError );
//----------------------------------------
  }
Exemple #23
0
double goldenSectionSearch(const GEdge *ge, const SPoint3 &q, double x1,
                           double x2, double x3, double tau)
{
  // Create a new possible center in the area between x2 and x3, closer to x2
  double x4 = x2 + GOLDEN2 * (x3 - x2);

  // Evaluate termination criterion
  if (fabs(x3 - x1) < tau * (fabs(x2) + fabs(x4)))
    return (x3 + x1) / 2;

  const SVector3 dp4 = q - ge->position(x4);
  const SVector3 dp2 = q - ge->position(x2);

  const double d4 = dp4.norm();
  const double d2 = dp2.norm();

  if (d4 < d2)
    return goldenSectionSearch(ge, q, x2, x4, x3, tau);
  else
    return goldenSectionSearch(ge,q , x4, x2, x1, tau);
}
SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n)
{
  if (l_t == 0.0) return SMetric3(1.e-22);
  SVector3 a;
  if (fabs(t(0)) <= fabs(t(1)) && fabs(t(0)) <= fabs(t(2))){
    a = SVector3(1,0,0);
  }
  else if (fabs(t(1)) <= fabs(t(0)) && fabs(t(1)) <= fabs(t(2))){
    a = SVector3(0,1,0);
  }
  else{
    a = SVector3(0,0,1);
  }
  SVector3 b = crossprod (t,a);
  SVector3 c = crossprod (b,t);
  b.normalize();
  c.normalize();
  t.normalize();
  SMetric3 Metric (1./(l_t*l_t),1./(l_n*l_n),1./(l_n*l_n),t,b,c);
  //  printf("bmttc %g %g %g %g %g\n",l_t,l_n,Metric(0,0),Metric(0,1),Metric(1,1));
  return Metric;
}
Exemple #25
0
static void gTryPositionViewer( const SVector3& newPos, const SVector3& finalPos )
{
	// if we're in megamap mode - allow it!
	if( !gAppSettings.followMode ) {
		gViewer.getOrigin() = newPos;
		return;
	}

	// else, if the final needed position is very far away - allow it
	SVector3 toFinal = gViewer.getOrigin() - finalPos;
	const float FAR_AWAY = 20.0f;
	if( toFinal.lengthSq() > FAR_AWAY * FAR_AWAY ) {
		gViewer.getOrigin() = newPos;
		return;
	}

	// else, check the new position for collisions
	const CLevelMesh& level = CGameInfo::getInstance().getLevelMesh();
	SVector3 targetPos = newPos;
	level.fitSphere( targetPos, VIEWER_R );
	gViewer.getOrigin() = targetPos;
}
Exemple #26
0
GPoint GEdge::closestPoint(const SPoint3 &q, double &t) const
{
  // printf("looking for closest point in curve %d to point %g %g\n",tag(),q.x(),q.y());

  const int nbSamples = 100;

  Range<double> interval = parBounds(0);

  double tMin = std::min(interval.high(), interval.low());
  double tMax = std::max(interval.high(), interval.low());

  double DMIN = 1.e22;
  double topt = tMin;
  const double DT = (tMax - tMin) / (nbSamples - 1.) ;
  for (int i = 0; i < nbSamples; i++){
    t = tMin + i * DT;
    const SVector3 dp = q - position(t);
    const double D = dp.norm();
    if (D < DMIN) {
      topt = t;
      DMIN = D;
    }
  }

  // printf("parameter %g as an initial guess (dist = %g)\n",topt,DMIN);

  if (topt == tMin)
    t = goldenSectionSearch (this, q, topt, topt + DT/2, topt + DT,  1.e-9);
  else if (topt == tMax)
    t = goldenSectionSearch (this, q, topt - DT, topt - DT/2 , topt, 1.e-9);
  else
    t = goldenSectionSearch (this, q, topt - DT, topt, topt + DT, 1.e-9);

  const SVector3 dp = q - position(t);
  // const double D = dp.norm();
  // printf("after golden section parameter %g  (dist = %g)\n",t,D);

  return point(t);
}
void CActorEntity::update( float timeAlpha )
{
	bool alive = mGameEntity->isAlive();
	if( alive ) {
		// fade out the outline
		float dt = CSystemTimer::getInstance().getDeltaTimeS();
		mOutlineTTL -= dt;
		if( mOutlineTTL < 0.0f )
			mOutlineTTL = 0.0f;

		SMatrix4x4& m = mWorldMat;
		SVector3 pos = samplePos( timeAlpha );
		SVector3 dir = samplePos( timeAlpha + 0.1f ) - pos;
		if( dir.lengthSq() < 1.0e-3f )
			dir = m.getAxisZ();
		else
			dir.normalize();

		if( mGameEntity->getType() == ENTITY_BLOCKER ) {
			double tt = CSystemTimer::getInstance().getTimeS();
			D3DXMatrixRotationY( &m, tt * 0.2f );
			m.getOrigin() = pos;
			m.getOrigin().y += sinf( tt * 0.6f ) * 0.2f;
		} else {
			m.getOrigin() = pos;
			m.getAxisZ() = dir;
			m.getAxisZ().y *= 0.2f;
			m.getAxisZ().normalize();
			m.getAxisY().set( 0, 1, 0 );
			m.getAxisX() = m.getAxisY().cross( m.getAxisZ() );
			m.getAxisX().normalize();
			m.getAxisY() = m.getAxisZ().cross( m.getAxisX() );
		}
	} else {
		mOutlineTTL = 0.0f;
	}
}
Exemple #28
0
  //------------------------------
  //
  //  ReadFundamentalZoneFile
  //
  //------------------------------
  bool ReadFundamentalZoneFile( vector<SVector3> & vFZEulerAngleList,
                                const string & sFilename )
  {
    char *pBuffer = NULL;
    Size_Type nBufSize = 0;
    vector< vector<string> > vsTokens;
	
    pBuffer = ReadFileToBuf(nBufSize, sFilename);
    if(pBuffer == NULL){
      return false;
    }

    string sBuffStr( pBuffer, nBufSize );
    
    GeneralLib::Tokenize( vsTokens, sBuffStr, ",# \t\n");
    
    for(Size_Type i = 0; i < vsTokens.size(); i ++){
      
      RUNTIME_ASSERT( (vsTokens[i].size() >= 3), 
                      "[ReadFundamentalZoneFile] ERROR: Invalid Euler Angles\n");
      
      
      Float fPhi   = DEGREE_TO_RADIAN( atof( vsTokens[i][0].c_str() ) );
      Float fTheta = DEGREE_TO_RADIAN( atof( vsTokens[i][1].c_str() ) );
      Float fPsi   = DEGREE_TO_RADIAN( atof( vsTokens[i][2].c_str() ) );

      SVector3 newAngles;

      newAngles.Set( fPhi, fTheta, fPsi );

      vFZEulerAngleList.push_back( newAngles );
    }


    delete [] pBuffer;
    return true;
  }
Exemple #29
0
void elasticitySolver::setLagrangeMultipliers(int phys, double tau,
                                              const SVector3 &d, int tag,
                                              simpleFunction<double> *f)
{
  LagrangeMultiplierField field;
  field._tau = tau;
  field._tag = tag;
  field._f = f;
  field._d = d.unit();
  field.g = new groupOfElements(
    _dim - 1, phys); // LM applied on entity of dimension = dim-1!
  LagrangeMultiplierFields.push_back(field);
  LagrangeMultiplierSpaces.push_back(
    new ScalarLagrangeFunctionSpaceOfElement(tag));
}
Exemple #30
0
static void gInitiallyPlaceViewer()
{
	// TBD
	/*
	const CGameInfo& gi = CGameInfo::getInstance();
	const CGameMap& gmap = gi.getGameMap();
	const CGameReplay& replay = gi.getReplay();
	const CLevelMesh& level = gi.getLevelMesh();

	const CReplayEntity::SState& pl1st = replay.getEntity( replay.getPlayer(0).entityAI ).getTurnState( 0 );
	int posx = pl1st.posx;
	int posy = pl1st.posy;

	const int XOFF[4] = { 2, 2, -2, -2 };
	const int YOFF[4] = { 2, -2, 2, -2 };
	const float ROT[4] = { D3DX_PI/4*7, D3DX_PI/4*5, D3DX_PI/4*1, D3DX_PI/4*3 };
	*/
	gViewer.identify();
	/*
	gViewer.getOrigin().set( posx, VIEWER_Y, -posy );
	for( int i = 0; i < 4; ++i ) {
		int px = posx+XOFF[i];
		int py = posy+YOFF[i];
		//if( gmap.isBlood( gmap.getCell(px,py).type ) ) {
		if( !level.collideSphere( SVector3(px,VIEWER_Y,-py), VIEWER_R ) ) {
			D3DXMatrixRotationY( &gViewer, ROT[i] );
			gViewer.getOrigin().set( px, VIEWER_Y, -py );
			break;
		}
	}
	*/
	gLastViewerValidPos = gViewer.getOrigin();

	gViewerVel.set(0,0,0);
	gViewerZVel.set(0,0,0);
}