示例#1
0
/*Predicts where the tracked bounding box will be in the next frame*/
Eigen::Vector4d bb_predict(Eigen::VectorXd const & bb0,
		Eigen::MatrixXd const & pt0, Eigen::MatrixXd const & pt1) {

	Eigen::MatrixXd of(pt1.rows(), pt1.cols());
	of = pt1.array() - pt0.array();
	double dx = median(of.row(0));
	double dy = median(of.row(1));
	unsigned int matCols = pt0.cols(), pos = 0, len = (matCols * (matCols - 1))
			/ 2;
	Eigen::RowVectorXd d1(len);
	Eigen::RowVectorXd d2(len);
	//calculate euclidean distance
	for (unsigned int h = 0; h < matCols - 1; h++)
		for (unsigned int j = h + 1; j < matCols; j++, pos++) {
			d1(pos) = sqrt(((pt0(0, h) - pt0(0, j)) * (pt0(0, h) - pt0(0, j)))
					+ ((pt0(1, h) - pt0(1, j)) * (pt0(1, h) - pt0(1, j))));

			d2(pos) = sqrt(((pt1(0, h) - pt1(0, j)) * (pt1(0, h) - pt1(0, j)))
					+ ((pt1(1, h) - pt1(1, j)) * (pt1(1, h) - pt1(1, j))));
		}

	Eigen::RowVectorXd ds(len);
	//calculate mean value
	ds = d2.array() / d1.array();
	double s = median(ds);
	double s1 = (0.5 * (s - 1) * bb_width(bb0));
	double s2 = (0.5 * (s - 1) * bb_height(bb0));
	Eigen::Vector4d bb1;
	//
	bb1(0) = bb0(0) - s1 + dx;
	bb1(1) = bb0(1) - s2 + dy;
	bb1(2) = bb0(2) + s1 + dx;
	bb1(3) = bb0(3) + s2 + dy;
	return bb1;
}
TEST(BoundingBox, Intersection){
	Point lb(1,2,0);
	Point ub(2,4,0);
	BoundingBox bb1(lb, ub);
	BoundingBox bb2(lb, ub);

	// Intersection should return an bounding box equal to bb2 and bb1,
	// they are the same bb
	BoundingBox bbIntersection = bb2.intersection(bb1);
	EXPECT_TRUE( bbIntersection.getLb().getX() == bb2.getLb().getX() &&
				bbIntersection.getLb().getY() == bb2.getLb().getY() &&
				bbIntersection.getLb().getZ() == bb2.getLb().getZ());

	EXPECT_TRUE( bbIntersection.getUb().getX() == bb2.getUb().getX() &&
				bbIntersection.getUb().getY() == bb2.getUb().getY() &&
				bbIntersection.getUb().getZ() == bb2.getUb().getZ());

	Point lb3(2,3,0);
	Point ub3(2,4,0);
	BoundingBox bb3(lb3, ub3);
	bbIntersection = bb2.intersection(bb3);
	// lower bound is the value of of bb3
	EXPECT_TRUE( bbIntersection.getLb().getX() == lb3.getX() &&
				bbIntersection.getLb().getY() == lb3.getY() &&
				bbIntersection.getLb().getZ() == lb3.getZ());

	// upper bound should not change
	EXPECT_TRUE( bbIntersection.getUb().getX() == bb2.getUb().getX() &&
				bbIntersection.getUb().getY() == bb2.getUb().getY() &&
				bbIntersection.getUb().getZ() == bb2.getUb().getZ());

}
示例#3
0
int main() {
  
  dump();

  for (int i=0;i<500;i++) {
    {
      flop = !flop;
      blockWipedPool().wipe();
      if (i%10==0)  blockWipedPool().clear();
      BP b1(new A1);
      BP b2(new A2);
      BP b3(new A3);
      dump();
      {
	BP bb1(b1->clone());
	BP bb2(b2->clone());
	BP bb3(b3->clone());
	dump();
      }
      dump("after clone destr");
      
      BP b11(new A1);
      BP b22(new A2);
      BP b23(new A2);
      dump();
      b1.reset();
      b2.reset();
      b3.reset();
      dump("after first destr");
    }
    dump();
    { 
      std::vector<BP> v(233);
      for_each(v.begin(),v.end(),&gen);
      dump("after 233 alloc");
      v.resize(123);
      dump("after 110 distr");
    }
    dump();
    
    for (int i=0;i<3;i++){
      std::vector<BP> v(2432);
      for_each(v.begin(),v.end(),&gen);
      std::vector<BP> v1(3213);
      for_each(v1.begin(),v1.end(),&gen);
      {
	std::vector<BP> d; d.swap(v);
      }
      // alloc disalloc
      std::vector<BP> vs(514);
      for_each(vs.begin(),vs.end(),&gen);
      for_each(vs.begin(),vs.end(),&gen);
    }
    dump("loop end");
  }
  return 0;
}
示例#4
0
int main() {
  
  dump();


  {
    BP b1(new A1);
    BP b2(new A2);
    dump();
    {
      BP bb1(b1->clone());
      BP bb2(b2->clone());
      dump();
    }
    dump("after clone destr");

    BP b11(new A1);
    BP b22(new A2);
    dump();
    b1.reset();
    b2.reset();
    dump("after first destr");
  }

  dump();
  { 
    std::vector<BP> v(233);
    for_each(v.begin(),v.end(),&gen);
    dump("after 233 alloc");
    v.resize(123);
    dump("after 110 distr");
  }
  dump();

  for (int i=0;i<100;i++){
    std::vector<BP> v(2432);
    for_each(v.begin(),v.end(),&gen);
    std::vector<BP> v1(3213);
    for_each(v1.begin(),v1.end(),&gen);
    {
      std::vector<BP> d; d.swap(v);
    }
    // alloc disalloc
    std::vector<BP> vs(514);
    for_each(vs.begin(),vs.end(),&gen);
    for_each(vs.begin(),vs.end(),&gen);
  }

  return 0;
}
TEST(BoundingBox, NoIntersection){
	Point lb(1,2,0), ub(2,4,0), lb2(3,5,0), ub2(4,6,0);
	BoundingBox bb1(lb, ub);
	BoundingBox bb2(lb2, ub2);

	// Intersection should return an bounding box equal to bb2 and bb1,
	// they are the same bb
	BoundingBox bbInter = bb2.intersection(bb1);
	EXPECT_FALSE( bb1.doesIntersect(bb2));

	// Lower bound of intersection should contain greater values
	// among lower bound of both bounding boxes (lb2)
	EXPECT_TRUE( bbInter.getLb().getX() == lb2.getX() &&
				bbInter.getLb().getY() == lb2.getY() &&
				bbInter.getLb().getZ() == lb2.getZ());

	// Upper bound of intersection should contain smaller values
	// among upper bound of both bounding boxes (ub)
	EXPECT_TRUE( bbInter.getUb().getX() == ub.getX() &&
				bbInter.getUb().getY() == ub.getY() &&
				bbInter.getUb().getZ() == ub.getZ());

}
示例#6
0
bool
GenericEllipse::isIntersectedBy(
    const GenericEllipse* e,
    SegmentPointVector& isecPoints,
    int& isecCount) const
{
    isecCount = 0;

    // Circle (Ellipse 1 scaled on y axis):
    //     (I)  (x - m1.x)^2 + (y - m1.y)^2 = r^2
    //     (II) x^2 + y^2 = r^2  --> moved to origin
    // Ellipse 2:
    //     (I)  (x - m2.x)^2 / a^2 + (y - m2.y)^2 / b^2 = 1
    //     (II) (x - (m2.x - m1.x))^2 / a^2 + (y - (m2.y - m1.y))^2 / b^2 = 1
    //           --> moved by the same vector as circle/ellipse 1

    // A scale factor that transform the first ellipse into a circle in order to
    // simplify calculation.
    // For the calculation, make ellipse 1's vertical radius equal to the
    // horizontal one such that we have a circle, and scale the coordinate
    // system accordingly
    Point2D scale(1.f, radius_.x / radius_.y);
    Point2D m1 = center_ * scale;
    Point2D r1 = radius_ * scale;
    Point2D m2 = e->center_ * scale;
    Point2D r2 = e->radius_ * scale;

    geom::GenericRect bb1(m1 - r1, m1 + r1);
    geom::GenericRect bb2(m2 - r2, m2 + r2);

    // The rectangle enclosing the area in which the intersection point(s) is
    // (are) located
    GenericRect searchRect;
    if (!bb1.isIntersectedByRect(bb2, searchRect))
    {
        return false;
    }

    // Translate whole coordinate system so ellipse (circle) 1's center is at
    // origin to simplify our calculation; don't forget to re-translate later.
    // Ellipse 2 is now: (x - c)^2 / a^2 + (y - d)^2 / b^2 = 1
    double c = m2.x - m1.x;
    double d = m2.y - m1.y;

    double a_squ = r2.x * r2.x;
    double b_squ = r2.y * r2.y;
    double b_squ_div_a_squ = b_squ / a_squ;
    double r_squ = r1.x * r1.x;
    double d_squ = d*d;

    // P = b^2 / a^2 - 1
    double pp = b_squ_div_a_squ - 1.;
    // Q = -2 * b^2 / a^2 * c
    double qq = -2. * b_squ_div_a_squ * c;
    // R = r^2 + d^2 - b^2 + b^2 / a^2 *c^2
    double rr = r_squ + d_squ - b_squ + b_squ_div_a_squ * (c*c);

    double qq_squ = qq*qq;

    // Formula:
    // 0 =
    // (P^2)x^4 + (2PQ)x^3 + (Q^2 + 2PR + 4d^2)x^2 + (2QR)x + R^2 - 4(d^2)(r^2)

    // alpha = P^2
    double alpha = pp*pp;
    // beta = 2PQ
    double beta = 2. * pp * qq;
    // gamma = Q^2 + 2PR + 4d^2
    double gamma = qq_squ + (2. * pp * rr) + (4. * d_squ);
    // delta = 2QR
    double delta = 2. * qq * rr;
    // epsilon = R^2 - 4(d^2)(r^2)
    double epsilon = (rr*rr) - (4. * d_squ * r_squ);

    // Now solve alpha*x^4 + beta*x^3 + gamma*x^2 + delta*x + epsilon = 0
    double roots[4];
    int numRoots;
    quarticPolynomialRoots(alpha, beta, gamma, delta, epsilon, roots, numRoots);


    float fx[4], fy[4];
    for (int i = 0; i != numRoots; ++i)
    {
        // Rescale and retranslate y to normal coordinate system
        // y = sqrt(r^2 - x^2)
        fy[i] = (std::sqrt(r_squ - roots[i] * roots[i]) + m1.y) / scale.y;
        fx[i] = roots[i] + m1.x;
    }

    // Handle identical ellipses case
    if ((center_ == e->center_) && (radius_ == e->radius_))
    {
        numRoots = 1;
        fx[0] = center_.x;
        fy[0] = center_.y + radius_.y;
    }
    // Handle symmetric case where every x corresponds to two roots (x, +-y).
    // For some cases (two circles intersecting only, it seems), only one or two
    // roots will be found by solving the polynomial, so we have to add the
    // missing roots.
    else if ((center_.y == e->center_.y) && ((numRoots == 1) || (numRoots == 2)))
    {
        std::cout << "numroots "<< numRoots << std::endl;
        for (int i = 0; i != numRoots; ++i)
        {
            fx[i + numRoots] = fx[i];
            fy[i + numRoots] = 2. * center_.y - fy[i];
        }
        numRoots *= 2;
    }
    else
    {
        // Check if points are valid; for those that are not, we assume that
        // their y coordinate is on the wrong side of the x axis, so mirror it
        // along that axis. If the point is invalid in general,
        // makeSegmentPoint() will finally fail (see below).
        for (int i = 0; i != numRoots; ++i)
        {
            Point2D p(fx[i], fy[i]);
            if (!e->isIntersectedByPoint(p))
            {
                fy[i] = 2. * center_.y - fy[i];
            }
        }
    }

    for (int i = 0; i != numRoots; ++i)
    {
        Point2D p(fx[i], fy[i]);
        SegmentPoint* s = makeSegmentPoint(p, e->getQuadrant(p));
        isecPoints.push_back(s);
        ++isecCount;
    }

    return isecCount;
}
int main(int argc, char *argv[])
{
  Pooma::initialize(argc, argv);
  Pooma::Tester tester(argc, argv);

  // To declare a field, you first need to set up a layout. This requires
  // knowing the physical vertex-domain and the number of external guard
  // cell layers. Vertex domains contain enough points to hold all of the
  // rectilinear centerings that POOMA is likely to support for quite
  // awhile. Also, it means that the same layout can be used for all
  // fields, regardless of centering.
  
  Interval<2> physicalVertexDomain(14, 14);
  Loc<2> blocks(3, 3);
  GridLayout<2> layout1(physicalVertexDomain, blocks, GuardLayers<2>(1),
                        LayoutTag_t());
  GridLayout<2> layout0(physicalVertexDomain, blocks, GuardLayers<2>(0),
                        LayoutTag_t());

  Centering<2> cell = canonicalCentering<2>(CellType, Continuous, AllDim);
  Centering<2> vert = canonicalCentering<2>(VertexType, Continuous, AllDim);
  Centering<2> yedge = canonicalCentering<2>(EdgeType, Continuous, YDim);

  Vector<2> origin(0.0);
  Vector<2> spacings(1.0, 2.0);

  // First basic test verifies that we're assigning to the correct areas
  // on a brick.

  typedef
    Field<UniformRectilinearMesh<2>, double,
    MultiPatch<GridTag, BrickTag_t> > Field_t;
  Field_t b0(cell, layout1, origin, spacings);
  Field_t b1(vert, layout1, origin, spacings);
  Field_t b2(yedge, layout1, origin, spacings);
  Field_t b3(yedge, layout1, origin, spacings);
  Field_t bb0(cell, layout0, origin, spacings);
  Field_t bb1(vert, layout0, origin, spacings);
  Field_t bb2(yedge, layout0, origin, spacings);

  b0.all() = 0.0;
  b1.all() = 0.0;
  b2.all() = 0.0;

  b0 = 1.0;
  b1 = 1.0;
  b2 = 1.0;

  bb0.all() = 0.0;
  bb1.all() = 0.0;
  bb2.all() = 0.0;

  bb0 = 1.0;
  bb1 = 1.0;
  bb2 = 1.0;

  // SPMD code follows.
  // Note, SPMD code will work with the evaluator if you are careful
  // to perform assignment on all the relevant contexts.  The patchLocal
  // function creates a brick on the local context, so you can just perform
  // the assignment on that context.

  int i;

  for (i = 0; i < b0.numPatchesLocal(); ++i)
  {
    Patch<Field_t>::Type_t patch = b0.patchLocal(i);
    //    tester.out() << "context " << Pooma::context() << ":  assigning to patch " << i
    //              << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since b1 and b2 are built with the same layout.
  for (i = 0; i < b1.numPatchesLocal(); ++i)
  {
    b1.patchLocal(i) += 1.5;
    b2.patchLocal(i) += 1.5;
  }

  for (i = 0; i < bb0.numPatchesLocal(); ++i)
  {
    Patch<Field_t>::Type_t patch = bb0.patchLocal(i);
    //    tester.out() << "context " << Pooma::context() << ":  assigning to patch on bb0 " << i
    //              << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since bb1 and bb2 are built with the same layout.
  for (i = 0; i < bb1.numPatchesLocal(); ++i)
  {
    bb1.patchLocal(i) += 1.5;
    bb2.patchLocal(i) += 1.5;
  }

  tester.check("cell centered field is 2.5", all(b0 == 2.5));
  tester.check("vert centered field is 2.5", all(b1 == 2.5));
  tester.check("edge centered field is 2.5", all(b2 == 2.5));

  tester.out() << "b0.all():" << std::endl << b0.all() << std::endl;
  tester.out() << "b1.all():" << std::endl << b1.all() << std::endl;
  tester.out() << "b2.all():" << std::endl << b2.all() << std::endl;

  tester.check("didn't write into b0 boundary",
               sum(b0.all()) == 2.5 * b0.physicalDomain().size());
  tester.check("didn't write into b1 boundary",
               sum(b1.all()) == 2.5 * b1.physicalDomain().size());
  tester.check("didn't write into b2 boundary",
               sum(b2.all()) == 2.5 * b2.physicalDomain().size());

  tester.check("cell centered field is 2.5", all(bb0 == 2.5));
  tester.check("vert centered field is 2.5", all(bb1 == 2.5));
  tester.check("edge centered field is 2.5", all(bb2 == 2.5));

  tester.out() << "bb0:" << std::endl << bb0 << std::endl;
  tester.out() << "bb1:" << std::endl << bb1 << std::endl;
  tester.out() << "bb2:" << std::endl << bb2 << std::endl;

  typedef
    Field<UniformRectilinearMesh<2>, double,
    MultiPatch<GridTag, CompressibleBrickTag_t> > CField_t;
  CField_t c0(cell, layout1, origin, spacings);
  CField_t c1(vert, layout1, origin, spacings);
  CField_t c2(yedge, layout1, origin, spacings);
  CField_t cb0(cell, layout0, origin, spacings);
  CField_t cb1(vert, layout0, origin, spacings);
  CField_t cb2(yedge, layout0, origin, spacings);

  c0.all() = 0.0;
  c1.all() = 0.0;
  c2.all() = 0.0;

  c0 = 1.0;
  c1 = 1.0;
  c2 = 1.0;

  cb0.all() = 0.0;
  cb1.all() = 0.0;
  cb2.all() = 0.0;

  cb0 = 1.0;
  cb1 = 1.0;
  cb2 = 1.0;

  // SPMD code follows.
  // Note, SPMD code will work with the evaluator if you are careful
  // to perform assignment on all the relevant contexts.  The patchLocal
  // function creates a brick on the local context, so you can just perform
  // the assignment on that context.

  for (i = 0; i < c0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t patch = c0.patchLocal(i);
    tester.out() << "context " << Pooma::context() << ":  assigning to patch " << i
                 << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since c1 and c2 are built with the same layout.
  for (i = 0; i < c1.numPatchesLocal(); ++i)
  {
    c1.patchLocal(i) += 1.5;
    c2.patchLocal(i) += 1.5;
  }

  for (i = 0; i < cb0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t patch = cb0.patchLocal(i);
    tester.out() << "context " << Pooma::context() << ":  assigning to patch on cb0 " << i
                 << " with domain " << patch.domain() << std::endl;
    patch += 1.5;
  }

  // This is safe to do since cb1 and cb2 are cuilt with the same layout.
  for (i = 0; i < cb1.numPatchesLocal(); ++i)
  {
    cb1.patchLocal(i) += 1.5;
    cb2.patchLocal(i) += 1.5;
  }

  tester.check("cell centered field is 2.5", all(c0 == 2.5));
  tester.check("vert centered field is 2.5", all(c1 == 2.5));
  tester.check("edge centered field is 2.5", all(c2 == 2.5));

  tester.out() << "c0.all():" << std::endl << c0.all() << std::endl;
  tester.out() << "c1.all():" << std::endl << c1.all() << std::endl;
  tester.out() << "c2.all():" << std::endl << c2.all() << std::endl;

  tester.check("didn't write into c0 boundary",
               sum(c0.all()) == 2.5 * c0.physicalDomain().size());
  tester.check("didn't write into c1 boundary",
               sum(c1.all()) == 2.5 * c1.physicalDomain().size());
  tester.check("didn't write into c2 boundary",
               sum(c2.all()) == 2.5 * c2.physicalDomain().size());

  tester.check("cell centered field is 2.5", all(cb0 == 2.5));
  tester.check("vert centered field is 2.5", all(cb1 == 2.5));
  tester.check("edge centered field is 2.5", all(cb2 == 2.5));

  tester.out() << "cb0:" << std::endl << cb0 << std::endl;
  tester.out() << "cb1:" << std::endl << cb1 << std::endl;
  tester.out() << "cb2:" << std::endl << cb2 << std::endl;

  //------------------------------------------------------------------
  // Scalar code example:
  //

  c0 = iota(c0.domain()).comp(0);
  c1 = iota(c1.domain()).comp(1);

  // Make sure all the data-parallel are done:

  Pooma::blockAndEvaluate();

  for (i = 0; i < c0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t local0 = c0.patchLocal(i);
    Patch<CField_t>::Type_t local1 = c1.patchLocal(i);
    Patch<CField_t>::Type_t local2 = c2.patchLocal(i);

    Interval<2> domain = local2.domain();  // physical domain of local y-edges

    // --------------------------------------------------------------
    // I believe the following is probably the most efficient approach
    // for sparse computations.  For data-parallel computations, the
    // evaluator will uncompress the patches and take brick views, which
    // provide the most efficient access.  If you are only performing
    // the computation on a small portion of cells, then the gains would
    // be outweighed by the act of copying the compressed value to all the
    // cells.
    //
    // The read function is used on the right hand side, because
    // operator() is forced to uncompress the patch just in case you want
    // to write to it.

    for(Interval<2>::iterator pos = domain.begin(); pos != domain.end(); ++pos)
    {
      Loc<2> edge = *pos;
      Loc<2> rightCell = edge;  // cell to right is same cell
      Loc<2> leftCell = edge - Loc<2>(1,0);
      Loc<2> topVert = edge + Loc<2>(0, 1);
      Loc<2> bottomVert = edge;

      local2(edge) =
        local0.read(rightCell) + local0.read(leftCell) +
        local1.read(topVert) + local1.read(bottomVert);
    }

    // This statement is optional, it tries to compress the patch after
    // we're done computing on it.  Since I used .read() for the local0 and 1
    // they remained in their original state. compress() can be expensive, so
    // it may not be worth trying unless space is really important.

    compress(local2);
  }

  tester.out() << "c0" << std::endl << c0 << std::endl;
  tester.out() << "c1" << std::endl << c1 << std::endl;
  tester.out() << "c2" << std::endl << c2 << std::endl;

  //------------------------------------------------------------------
  // Interfacing with a c-function:
  //
  // This example handles the corner cases, where the patches from a
  // cell centered field with no guard layers actually contain some
  // extra data.

  Pooma::blockAndEvaluate();

  for (i = 0; i < cb0.numPatchesLocal(); ++i)
  {
    Patch<CField_t>::Type_t local0 = cb0.patchLocal(i);
    Interval<2> physicalDomain = local0.physicalDomain();
    double *data;
    int size = physicalDomain.size();

    if (physicalDomain == local0.totalDomain())
    {
      uncompress(local0);
      data = &local0(physicalDomain.firsts());
      nonsense(data, size);
    }
    else
    {
      // In this case, the engine has extra storage even though the
      // field has the right domain. We copy it to a brick engine,
      // call the function and copy it back.  No uncompress is required,
      // since the assignment will copy the compressed value into the
      // brick.

      // arrayView is a work-around.  Array = Field doesn't work at
      // the moment.

      Array<2, double, Brick> brick(physicalDomain);
      Array<2, double, CompressibleBrick> arrayView(local0.engine());
      brick = arrayView(physicalDomain);
      Pooma::blockAndEvaluate();
      data = &brick(Loc<2>(0));
      nonsense(data, size);
      arrayView(physicalDomain) = brick;

      // Note that we don't need a blockAndEvaluate here, since an iterate has
      // been spawned to perform the copy.
    }

    // If you want to try compress(local0) here, you should do blockAndEvaluate
    // first in case the local0 = brick hasn't been executed yet.
  }
      
  tester.out() << "cb0.all()" << std::endl << cb0 << std::endl;

  b2 = positions(b2).comp(0);

  RefCountedBlockPtr<double> block = pack(b2);

  // The following functions give you access to the raw data from pack.
  // Note that the lifetime of the data is managed by the RefCountedBlockPtr,
  // so when "block" goes out of scope, the data goes away.  (i.e. Don't write
  // a function where you return block.beginPointer().)

  double *start = block.beginPointer();  // start of the data
  double *end = block.endPointer();      // one past the end
  int size = block.size();               // size of the data

  tester.out() << Pooma::context() << ":" << block.size() << std::endl;

  unpack(b3, block);

  tester.out() << "b2" << std::endl << b2 << std::endl;
  tester.out() << "b3" << std::endl << b3 << std::endl;

  tester.check("pack, unpack", all(b2 == b3));

  int ret = tester.results("LocalPatch");
  Pooma::finalize();
  return ret;
}