コード例 #1
0
// =============================================================================
NOX::Abstract::Group::ReturnType
Ginla::FDM::Constraint::MinDist::
computeConstraints()
{
  if (!isValidConstraints_)
  {
    // the dot() method is indeed smart enough to compute
    // conjugate the first complex vector psiRef_
    constraints_(0,0) = std::imag( psiRef_->dot(*psi_) );
    isValidConstraints_ = true;
  }

  return NOX::Abstract::Group::Ok;
}
コード例 #2
0
// =============================================================================
// The first column of dgdp should be filled with the constraint
// residuals g if isValidG is false.
// If isValidG is true, then the dgdp contains g on input.
NOX::Abstract::Group::ReturnType
Ginla::FDM::Constraint::MinDist::
computeDP( const vector<int> & paramIDs,
           NOX::Abstract::MultiVector::DenseMatrix & dgdp, 
           bool isValidG
         )
{
  if (!isValidG)
      dgdp(0,0) = constraints_(0,0);

  for (unsigned int i=0; i<paramIDs.size(); i++)
      dgdp(0,i+1) = 0.0; // no dependence on constraints in the phase condition

  return NOX::Abstract::Group::Ok;
}
コード例 #3
0
ファイル: SpatialConvex.cpp プロジェクト: esheldon/sdssidl
void
SpatialConvex::simplify() {

  if(sign_ == zERO) {
    simplify0();	// treat zERO convexes separately
    return;
  }

  size_t i,j;
  size_t clen;
  bool redundancy = true;

  while(redundancy) {
    redundancy = false;
    clen = constraints_.length();

  for(i = 0; i < clen; i++) {
    for(j = 0; j < i; j++) {
      int test;

      // don't bother with two zero constraints
      if( constraints_[i].sign_ == zERO && constraints_[j].sign_ == zERO)
	continue;

      // both pos or zero
      if( ( constraints_[i].sign_ == pOS || constraints_[i].sign_ == zERO ) &&
	  ( constraints_[j].sign_ == pOS || constraints_[j].sign_ == zERO ) ) {
	if ( (test = testConstraints(i,j)) == 0 ) continue; // intersection
	if ( test < 0 ) { // disjoint ! convex is empty
	  constraints_.cut(constraints_.length());
	  return;
	}
	// one is redundant
	if(test == 1)   constraints_.cut(1, clen - 1 - i);
	else if(test==2)constraints_.cut(1, clen - 1 - j);
	else continue;     // intersection
	redundancy = true; // we did cut out a constraint -> do the loop again
	break;
      }

      // both neg or zero
      if( ( constraints_[i].sign_ == nEG ) &&
	  ( constraints_[j].sign_ == nEG ) ) {
	if ( (test = testConstraints(i,j)) <= 0 ) continue; // ok
	// one is redundant
	if(test == 1)   constraints_.cut(1, clen - 1 - j);
	else if(test==2)constraints_.cut(1, clen - 1 - i);
	else continue; // intersection
	redundancy = true; // we did cut out a constraint -> do the loop again
	break;
      }

      // one neg, one pos/zero
      if( (test = testConstraints(i,j)) == 0) continue; // ok: intersect
      if( test < 0 ) { // neg is redundant
	if ( constraints_[i].sign_ == nEG ) constraints_.cut(1, clen - 1 - i);
	else    constraints_.cut(1, clen - 1 - j);
	redundancy = true; // we did cut out a constraint -> do the loop again
	break;
      }
      // if the negative constraint is inside the positive: continue
      if ( (constraints_[i].sign_ == nEG && test == 2) || 
	   (constraints_[j].sign_ == nEG && test == 1) )continue;
      // positive constraint in negative: convex is empty!
      constraints_.cut(constraints_.length());
      return;
    }
    if(redundancy)break;
  }

  }

  // reset the sign of the convex
  sign_ = constraints_[0].sign_;
  for(i = 1; i < constraints_.length(); i++) {
    switch (sign_) {
    case nEG:
      if(constraints_[i].sign_ == pOS) sign_ = mIXED;
      break;
    case pOS:
      if(constraints_[i].sign_ == nEG) sign_ = mIXED;
      break;
    case zERO:
      sign_ = constraints_[i].sign_;
      break;
    }
  }

  if (constraints_.length() == 1) // for one constraint, it is itself the BC
    boundingCircle_ = constraints_(0);
  else if (sign_ == pOS)
    boundingCircle_ = constraints_(0);
    
}
コード例 #4
0
ファイル: SpatialConvex.cpp プロジェクト: esheldon/sdssidl
void
SpatialConvex::simplify0() {

  size_t i,j,k;
  SpatialVector vi1, vi2;
  ValVec<size_t> cornerConstr1, cornerConstr2, removeConstr;
  ValVec<SpatialVector> corner;
  if (constraints_.length() == 1) { // for one constraint, it is itself the BC
    boundingCircle_ = constraints_(0);
    return;
  // For 2 constraints, take the bounding circle a 0-constraint...
  // this is by no means optimal, but the code is optimized for at least
  // 3 zERO constraints... so this is acceptable.
  } else if(constraints_.length() == 2) {
    // test for constraints being identical - rule 1 out
    if(constraints_.vector_[0].a_ == constraints_.vector_[1].a_){
      constraints_.cut(1);
      boundingCircle_ = constraints_(0);
      return;
    }
    // test for constraints being two disjoint half spheres - empty convex!
    if(constraints_.vector_[0].a_ == (-1.0)*constraints_.vector_[1].a_){
      constraints_.cut(constraints_.length());
      return;
    }
    boundingCircle_ = SpatialConstraint(constraints_(0).v() + 
					constraints_(1).v(),0);
    return;
  }

  // Go over all pairs of constraints
  for(i = 0; i < constraints_.length() - 1; i++) {
    bool ruledout = true;
    for(j = i+1; j < constraints_.length(); j ++) {
      // test for constraints being identical - rule i out
      if(constraints_.vector_[i].a_ == constraints_.vector_[j].a_)break;
      // test for constraints being two disjoint half spheres - empty convex!
      if(constraints_.vector_[i].a_ == (-1.0)*constraints_.vector_[j].a_){
	constraints_.cut(constraints_.length());
	return;
      }
      // vi1 and vi2 are their intersection points
      vi1 = constraints_.vector_[i].a_ ^ constraints_.vector_[j].a_ ;
      vi1.normalize();
      vi2 = (-1.0) * vi1;
      bool vi1ok = true, vi2ok = true;
      // now test whether vi1 or vi2 or both are inside every other constraint.
      // if yes, store them in the corner array.
      for(k = 0; k < constraints_.length(); k++) {
	if(k == i || k == j) continue;
	if(vi1ok && vi1 * constraints_.vector_[k].a_ <= 0.0) vi1ok = false;
	if(vi2ok && vi2 * constraints_.vector_[k].a_ <= 0.0) vi2ok = false;
	if(!vi1ok && !vi2ok)break;
      }
      if(vi1ok) { 
	corner.append(vi1); 
	cornerConstr1.append(i);
	cornerConstr2.append(j);
	ruledout = false; 
      }
      if(vi2ok) { 
	corner.append(vi2); 
	cornerConstr1.append(i);
	cornerConstr2.append(j);
	ruledout = false; 
      }
    }
    // is this constraint ruled out? i.e. none of its intersections
    // with other constraints are corners... remove it from constraints_ list.
    if(ruledout) removeConstr.append(i);
  }

  // Now set the corners into their correct order, which is an
  // anti-clockwise walk around the polygon.
  //
  // start at any corner. so take the first.

  corners_.cut(corners_.length());
  corners_.append(corner(0));
  // The trick is now to start off into the correct direction.
  // this corner has two edges it can walk. we have to take the
  // one where the convex lies on its left side.
  i = cornerConstr1(0);		// the i'th constraint and j'th constraint
  j = cornerConstr2(0);		// intersect at 0'th corner
  size_t c1=0,c2=0,k1=0,k2=0;
  // Now find the other corner where the i'th and j'th constraints intersect.
  // Store the corner in vi1 and vi2, and the other constraint indices 
  // in c1,c2.
  for( k = 1; k < cornerConstr1.length(); k ++) {
    if(cornerConstr1(k) == i) {
      vi1 = corner(k);
      c1 = cornerConstr2(k);
      k1 = k;
    }
    if(cornerConstr2(k) == i) {
      vi1 = corner(k);
      c1 = cornerConstr1(k);
      k1 = k;
    }
    if(cornerConstr1(k) == j) {
      vi2 = corner(k);
      c2 = cornerConstr2(k);
      k2 = k;
    }
    if(cornerConstr2(k) == j) {
      vi2 = corner(k);
      c2 = cornerConstr1(k);
      k2 = k;
    }
  }
  // Now test i'th constraint-edge ( corner 0 and corner k ) whether
  // it is on the correct side (left)
  //
  //  ( (corner(k) - corner(0)) x constraint(i) ) * corner(0)
  //
  // is >0 if yes, <0 if no...
  //
  size_t c,currentCorner;
  if( ((vi1 - corner(0)) ^ constraints_(i).a_) * corner(0) > 0 ) {
    corners_.append(vi1);
    c = c1;
    currentCorner = k1;
  } else {
    corners_.append(vi2);
    c = c2;
    currentCorner = k2;
  }
  // now append the corners that match the index c until we got corner 0 again
  // currentCorner holds the current corners index
  // c holds the index of the constraint that has just been intersected with
  // So:
  // x We are on a constraint now (i or j from before), the second corner
  //   is the one intersecting with constraint c.
  // x Find other corner for constraint c.
  // x Save that corner, and set c to the constraint that intersects with c
  //   at that corner. Set currentcorner to that corners index.
  // x Loop until 0th corner reached.
  while( currentCorner ) {
    for (k = 0; k < cornerConstr1.length(); k++) {
      if(k == currentCorner)continue;
      if(cornerConstr1(k) == c) {
	if( (currentCorner = k) == 0) break;
	corners_.append(corner(k));
	c = cornerConstr2(k);
	break;
      }
      if(cornerConstr2(k) == c) {
	if( (currentCorner = k) == 0) break;
	corners_.append(corner(k));
	c = cornerConstr1(k);
	break;
      }
    }
  }
  // Remove all redundant constraints
  for ( i = 0; i < removeConstr.length(); i++)
    constraints_.remove(removeConstr(i));

  // Now calculate the bounding circle for the convex.
  // We take it as the bounding circle of the triangle with
  // the widest opening angle. All triangles made out of 3 corners
  // are considered.
  boundingCircle_.d_ = 1.0;
  if (constraints_.length() >=3 ) {
    for(i = 0; i < corners_.length(); i++)
      for(j = i+1; j < corners_.length(); j++)
	for(k = j+1; k < corners_.length(); k++) {
	  SpatialVector v = ( corners_(j) - corners_(i) ) ^ 
	                    ( corners_(k) - corners_(j) );
	  v.normalize();
	  // Set the correct opening angle: Since the plane cutting
	  // out the triangle also correctly cuts out the bounding cap
	  // of the triangle on the sphere, we can take any corner to
	  // calculate the opening angle
	  float64 d = v * corners_(i);
	  if(boundingCircle_.d_ > d) boundingCircle_ = SpatialConstraint(v,d);
	}
  }

#ifdef DIAGNOSE
  for(i = 0; i < corners_.length(); i++) {
    //cout << corners_(i).ra() << "," << corners_(i).dec() << ":" << corners_(i) << "\n";
  }
#endif
    
}