Ejemplo n.º 1
0
const ValVec<htmRange> &
htmInterface::doHull() {

  if(polyCorners_.length() < 3)
    throw SpatialInterfaceError("htmInterface:convexHull: empty hull: points on one line");

  SpatialVector v;
  SpatialConvex x;
  SpatialDomain d;

  // The constraint we have for each side is a 0-constraint (great circle)
  // passing through the 2 corners. Since we are in counterclockwise order,
  // the vector product of the two successive corners just gives the correct
  // constraint.
  size_t i, len = polyCorners_.length();
  for(i = 0; i < len; i++) {
    v = polyCorners_[i].c_ ^ polyCorners_[ i == len-1 ? 0 : i + 1].c_;
#ifdef DIAG
    cerr << v << " " << i << "," << i+1 << "\n";
#endif
    v.normalize();
    SpatialConstraint c(v,0);
    x.add(c);
  }
  d.add(x);
  d.intersect(index_, idList_);

  range_.cut(range_.length());
  makeRange();

  return range_;
}
Ejemplo n.º 2
0
const ValueVector &
htmInterface::doHull() {

	if(polyCorners_.size() < 3)
		throw SpatialInterfaceError("htmInterface:convexHull: empty hull: points on one line");

	SpatialVector v;

	RangeConvex cvx;

	SpatialDomain dom;

	// The constraint we have for each side is a 0-constraint (great circle)
	// passing through the 2 corners. Since we are in counterclockwise order,
	// the vector product of the two successive corners just gives the correct
	// constraint.
	size_t i, len = polyCorners_.size();
	for(i = 0; i < len; i++) {
		v = polyCorners_[i].c_ ^ polyCorners_[ i == len-1 ? 0 : i + 1].c_;
#ifdef DIAG
		cerr << "doHull:: " << v << " " << i << "," << i+1 << endl;
#endif
		v.normalize();
		SpatialConstraint c(v,0);
		cvx.add(c); // [ed:RangeConvex::add]
	}
	dom.add(cvx);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%
//	dom.convexes_[0].boundingCircle_.write(cout);
//	dom.write(cout);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%
	return domain(dom);
}
Ejemplo n.º 3
0
/////////////TESTBOUNDINGCIRCLE///////////////////////////
// testBoundingCircle: test for boundingCircles intersecting with constraint
//
bool
RangeConvex::testBoundingCircle(const SpatialVector & v0,
				  const SpatialVector & v1,
				  const SpatialVector & v2) {

  // Set the correct direction: The normal vector to the triangle plane
  SpatialVector c = ( v1 - v0 ) ^ ( v2 - v1 );
  c.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 = acos (c * v0);

  // for zero convexes, we have calculated a bounding circle for the convex.
  // only test with this single bounding circle.

  if(sign_ == zERO) {
    float64 tst;
    if ( ( (tst = c * boundingCircle_.a_) < -1.0L + gEpsilon ? gPi :
	   acos(tst) ) >
	 ( d + boundingCircle_.s_) ) return false;
    return true;
  }

  // for all other convexes, test every constraint. If the bounding
  // circle lies completely outside of one of the constraints, reject.
  // else, accept.

  size_t i;
  for(i = 0; i < constraints_.size(); i++) {
      if ( ( (c * constraints_[i].a_) < -1.0L + gEpsilon ? gPi :
	   acos(c * constraints_[i].a_) ) >
	  ( d + constraints_[i].s_) ) return false;
  }
  return true;
}
Ejemplo n.º 4
0
void
RangeConvex::simplify0() {

  size_t i,j,k;
  SpatialVector vi1, vi2;
  typedef std::vector<size_t> ValueVectorSzt;
  ValueVectorSzt cornerConstr1, cornerConstr2, removeConstr;
  ValueVectorSpvec corner;
  if (constraints_.size() == 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_.size() == 2) {
    // test for constraints being identical - rule 1 out
	if(constraints_[0].a_ == constraints_[1].a_){
	  constraints_.erase(constraints_.end()-1);
      boundingCircle_ = constraints_[0];
      return;
    }
    // test for constraints being two disjoint half spheres - empty convex!
	if(constraints_[0].a_ == (-1.0)*constraints_[1].a_){
	  constraints_.clear();
      return;
    }
    boundingCircle_ = SpatialConstraint(constraints_[0].v() +
					constraints_[1].v(),0);
    return;
  }

  // Go over all pairs of constraints
  for(i = 0; i < constraints_.size() - 1; i++) {
    bool ruledout = true;
	for(j = i+1; j < constraints_.size(); j ++) {
      // test for constraints being identical - rule i out
	  if(constraints_[i].a_ == constraints_[j].a_) break;
      // test for constraints being two disjoint half spheres - empty convex!
	  if(constraints_[i].a_ == (-1.0)*constraints_[j].a_){
		constraints_.clear();
		return;
      }
      // vi1 and vi2 are their intersection points
	  vi1 = constraints_[i].a_ ^ constraints_[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_.size(); k++) {
		if(k == i || k == j) continue;
		if(vi1ok && vi1 * constraints_[k].a_ <= 0.0) vi1ok = false;
		if(vi2ok && vi2 * constraints_[k].a_ <= 0.0) vi2ok = false;
		if(!vi1ok && !vi2ok) break;
      }
      if(vi1ok) {
	    corner.push_back(vi1);
		cornerConstr1.push_back(i);
		cornerConstr2.push_back(j);
		ruledout = false;
      }
      if(vi2ok) {
		corner.push_back(vi2);
		cornerConstr1.push_back(i);
		cornerConstr2.push_back(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.push_back(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_.clear();
  corners_.push_back(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,c2,k1,k2;
  // 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.size(); 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_.push_back(vi1);
    c = c1;
    currentCorner = k1;
  } else {
	corners_.push_back(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.size(); k++) {
      if(k == currentCorner)continue;
      if(cornerConstr1[k] == c) {
		if( (currentCorner = k) == 0) break;
		corners_.push_back(corner[k]);
		c = cornerConstr2[k];
		break;
      }
      if(cornerConstr2[k] == c) {
		if( (currentCorner = k) == 0) break;
		corners_.push_back(corner[k]);
		c = cornerConstr1[k];
		break;
      }
    }
  }
  // Remove all redundant constraints
  for ( i = 0; i < removeConstr.size(); i++)
		 constraints_.erase(constraints_.end()-removeConstr[i]-1);

  // 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_.size() >=3 ) {
	for(i = 0; i < corners_.size(); i++)
    for(j = i+1; j < corners_.size(); j++)
	for(k = j+1; k < corners_.size(); 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_.size(); i++) {
    cout << corners_[i].ra() << "," << corners_[i].dec() << ":" << corners_[i] << endl;
  }
#endif
}