Exemple #1
0
/*
 *--------------------------------------------------
 *--------------------------------------------------
 */
void updatePositionsForFace( int whichFace, double *fMin, double *fMax, double *avgF )
{
	CELL *c, *nextCell;
	Point2D q;
	Point3D p;
	double f, maxForce, minForce, avgForce;
	int cellsCount;
	double tmpx, tmpy;
	
	maxForce = 1e-10;
	minForce = 1e+10;
	avgForce = 0;
	cellsCount = 0;
	
	int contador = 0;
	
	c = faces[whichFace].head->next;
	while( c != faces[whichFace].tail )
	{
		nextCell = c->next;
		if ( c->fx != 0 && c->fy != 0 )
		{
			cellsCount++;
			/* compute new position */
			/* wx and wy include anisotropy effect */
			/* Removed by Thompson Peter Lied in 16/07/2002 */
			/* c->fx *= wForce * wx;
			 c->fy *= wForce * wy;
			 */
			
			/* compute new position */   
			/* Modified by Fabiane Queiroz in 24/09/2009 */
			/* c->fx *= AniCommon * AniX;
			 c->fy *= AniCommon * AniY;
			 */
			
			c->fx *= AniCommon + AniX;
			c->fy *= AniCommon + AniY;
			
			//printf("c->fx= %f e c->fy= %d\n", c->fx, c->fy);
			
			/*//printf("c->fx= %f \n", c->fx);
			 /* Added by Thompson Peter Lied in 15/07/20002 */
			// tmpx = c->fx;
			//tmpy = c->fy;
			
			//printf("dix = %f, diy = %f \n", tmpx, tmpy);
			
			/* compute new position
			 include anisotropy effect */
			//c->fx = AniX + (AniCommon * tmpx);
			// c->fy = AniY + (AniCommon * tmpy);
			
			
			
			f = sqrt( c->fx * c->fx + c->fy * c->fy );
			avgForce += f;
			
			if ( f < minForce ) minForce = f;
			if ( f > maxForce ) maxForce = f;
			
			/* get cell's current position in the 2D space */
			mapOntoPolySpace(c->whichFace, c->x, c->y, c->z, &q);
			
			/* update the new position on the polygon's 2D space */
			q.x += c->fx;
			q.y += c->fy;
			
			/* p will return the point in the original 3D space */
			mapFromPolySpace(c->whichFace, q.x, q.y, &p);
			/*
			 * Finally update the new position
			 * I want to make sure that the new position
			 * passes the inside polygon test
			 */
			if ( cellInPoly( c, TRUE ) == FALSE )
			{
				contador = contador +1;
				//fprintf( stderr, "Face %d\n", c->whichFace );
				//fprintf( stderr, "cell's current position (%lg %lg %lg)\n",
					//	c->x, c->y, c->z );
				//fprintf( stderr, "cell's previous position (%lg %lg %lg)\n",
					//	c->xp, c->yp, c->zp );
				/* Added by Thompson Peter Lied in 16/07/2002 */
				//fprintf( stderr, "###ExpFileName = %s\n", outputCMfileName);  
				saveCellsFile( outputCMfileName );
				/* end */
				//errorMsg("Original cell position outside polygon!");
			}
			if ( cellInPoly( c, FALSE ) == FALSE )
			{
				contador = contador +1;
				//fprintf( stderr, "Face %d\n", c->whichFace );
				//fprintf( stderr, "cell's current position (%lg %lg %lg)\n",
				//		c->x, c->y, c->z );
				//fprintf( stderr, "cell's previous position (%lg %lg %lg)\n",
					//	c->xp, c->yp, c->zp );
				/* Added by Thompson Peter Lied in 16/07/2002 */
				saveCellsFile( outputCMfileName );
				/* end */
				//errorMsg("Previous cell position outside polygon!");
			}
			/* Assign the cell's previous position */
			c->xp = c->x;
			c->yp = c->y;
			c->zp = c->z;
			assignPosition2Cell( c, p );
			keepCellOnPlane( c );
			keepCellOnSurface( c );
		}
		c = nextCell;
	}
	if ( cellsCount != 0 )
		*avgF = avgForce / (double) cellsCount;
	else *avgF = avgForce;
	
	*fMin = minForce;
	*fMax = maxForce;
	if(contador != 0)
		printf("contador: %d\n",contador);
	
}
Exemple #2
0
/*
 *--------------------------------------------------
 *
 *--------------------------------------------------
 */
void keepCellOnSurface( CELL *c )
{
//printf("KeepecellOnSuerface!\n");	
#define N_OF_TRIES 30
	
	int whichEdge, newFace, direction;
	int nOfTries = 0, originalFace;
	Point3D p, intersec, originalPos;
	double d = 0, t;
	
	/*
	 * At this point, the previous cell position (xp,yp,zp)
	 * contains the cell position BEFORE the force has
	 * been applied. In case we cannot find a new position
	 * for this cell, it will return to its original
	 * position. That's why I am keeping the record of
	 * the cell's original position here
	 */
	originalFace  = c->whichFace;
	originalPos.x = c->xp;
	originalPos.y = c->yp;
	originalPos.z = c->zp;
	
	
#ifdef VERBOSE
	fprintf( stderr, "\nStarting point!\n");
	fprintf( stderr, "Previous position %f %f %f in face %d\n",
			c->xp, c->yp, c->zp, c->whichFace );
	fprintf( stderr, "Current position %f %f %f\n",
			c->x, c->y, c->z );
#endif
	
	/*
	 * The routine 'cellInPolyAndEdge' will return either -1, if the cell
	 * new position is INSIDE the polygon, OR the edge index for the
	 * edge crossed. We keep doing this until either the cell finds
	 * a position to rest, or a given number of tries has been reached
	 */
	//printf("primeiro if!!\n");
	if ( (whichEdge = cellInPolyAndEdge( c, &direction, &intersec, &t, -1 )) == -1 )
	{
		//printf("ufa passei!!!\n");	
		return;
	}
	else if((whichEdge = cellInPolyAndEdge( c, &direction, &intersec, &t, -1 )) == -2){
		killCell(c);
	}
	else
	{
		//fprintf( stderr, "uffa passei mas fui pro else!!!!\n");
		while ( whichEdge != -1 && nOfTries < N_OF_TRIES )
		{
			
			nOfTries++;
			
			/*
			 * Computes the distance between cell's current and
			 * previous position. I am not yet using this distance
			 * as a metric to check if the cell is going to rest
			 */
			d = sqrt((c->x - c->xp) * (c->x - c->xp) +
					 (c->y - c->yp) * (c->y - c->yp) +
					 (c->z - c->zp) * (c->z - c->zp));
			//fprintf( stderr, "d = %f \n", d );
			
#ifdef VERBOSE
			fprintf( stderr, "Intersection w/ edge %d pface %d nface %d\n",
					whichEdge, edges[whichEdge].pf, edges[whichEdge].nf );
			fprintf( stderr, "%f %f %f at t = %f dir = %d\n",
					intersec.x, intersec.y, intersec.z, t, direction );
			fprintf( stderr, "distance %f\n", d );
#endif
			
			/* if point no longer in polygon then we need to move it
			 to an adjacent one */
			p.x = c->x;
			p.y = c->y;
			p.z = c->z;
			/*
			 * Direction TRUE means that we found an edge in the
			 * 'right' direction, ie, the cell is going from
			 * a 'p' face to a 'n' face
			 */
			if ( direction )
			{
				V3PreMul( &p, &(edges[whichEdge].pn) );
				V3PreMul( &intersec, &(edges[whichEdge].pn) );
				newFace = edges[whichEdge].nf;
			//	printf("Entrei no direction!\n");
			}
			else
			{
				V3PreMul( &p, &(edges[whichEdge].np) );
				V3PreMul( &intersec, &(edges[whichEdge].np) );
				newFace = edges[whichEdge].pf;
				//printf("Entrei no else do direction!\n");
			}
			
			/* this should be the point's position in the new adjacent face */
			assignPosition2Cell( c, p );
			
			/* the new previous position is the intersection just computed */
			assignPrevPosition2Cell( c, intersec );
			
			/* change the face information attached to the cell */
			changeFacesList(c, newFace, c->whichFace);
			c->whichFace = newFace;
			nChangeFaces++;
			
#ifdef VERBOSE
			fprintf( stderr, "Went to %f %f %f and face %d\n",
					c->x, c->y, c->z, c->whichFace);
#endif
			
			if ( cellInPoly( c, FALSE ) == FALSE )
			{
				fprintf( stderr, "Face %d\n", c->whichFace );
				errorMsg("Previous cell position outside the face! (keepCellOnSurface)");
			}
			//printf("Vou computar!!!\n");
			whichEdge = cellInPolyAndEdge( c, &direction, &intersec, &t, whichEdge );
			//printf("Computei!\n");
		}
		/*
		 * At this point I am assuming that the cell has found a new
		 * polygon to live and this polygon is different from
		 * the original polygon. It is very likely that the primitive
		 * information also changed and I need therefore to recompute it
		 * here
		 */
		if ( whichEdge == -1 )
		{
			//fprintf( stderr, "I am recomputing primitive information for a cell!\n" );
			assignPrim2Cell( c );
		}
		
	}
	/*
	 * If nOfTries >= N_OF_TRIES it means that the cell travelled more than
	 * N_OF_TRIES polygons and still could not find a polygon to rest.
	 * N_OF_TRIES is an arbitrary number which seems to be working now
	 * I might need to review this later. The idea here is to
	 * make the cell go back to its original position in case it cannot
	 * find a polygon to rest
	 */
	if ( nOfTries >= N_OF_TRIES ){
		/* Assign the old position of this cell as its current
		 and previous position */
		assignPosition2Cell( c, originalPos );
		assignPrevPosition2Cell( c, originalPos );
		/* update which face this cell belongs to */
		changeFacesList(c, originalFace, newFace );
		c->whichFace = originalFace;
		fprintf( stderr, "Could not map cell! (distance = %lg)\n", d );
		return;
	}
	
}
Exemple #3
0
std::vector<Circle> CirclePacker::getCirclesFromPoly(Polygon poly)
{
  //std::cout<<"\n# of edges: "<<poly.edges.size();
  std::vector<Circle> result;
  std::vector<cv::Point> vertices;
  
  // Push on all vertices
  for(int i=0;i<poly.edges.size();i++)
  {
    vertices.push_back(poly.edges[i].start);
    vertices.push_back(poly.edges[i].end);
  }
  
  double MAX_LENGTH= vertices[0].y;
  double MAX_WIDTH = vertices[0].x;
  double MIN_LENGTH= vertices[0].y;
  double MIN_WIDTH = vertices[0].x;
  for(int i=0;i<vertices.size();i++)
  {
    if(vertices[i].y > MAX_LENGTH)
    {
      MAX_LENGTH = vertices[i].y;
    }
    if(vertices[i].y < MIN_LENGTH)
    {
      MIN_LENGTH = vertices[i].y;
    }
    
    if(vertices[i].x > MAX_WIDTH)
    {
      MAX_WIDTH = vertices[i].x;
    }
    if(vertices[i].x < MIN_WIDTH)
    {
      MIN_WIDTH = vertices[i].x;
    }
  }

  double round = 1;
  int width_count = (MAX_WIDTH - MIN_WIDTH) / round;
  int length_count = (MAX_LENGTH - MIN_LENGTH) / round;
  double start_x = MIN_WIDTH + round/2.f;
  double start_y = MIN_LENGTH + round/2.f;

  //std::cout<<"\nMAX_WIDTH: "<<MAX_WIDTH<<" MAX_LENGTH: "<<MAX_LENGTH<<" width_count: "<<width_count<<" length_count: "<<length_count;

  std::vector<Cell> cells;
 
  for(int i=0;i<width_count;i++)
  {
    for(int j=0;j<length_count;j++)
    {
      //std::cout<<"\ni: "<<i<<" j: "<<j<<" round: "<<round;
      double x = start_x + (round * (i)); 
      double y = start_y + (round * (j));
      Cell temp;
      temp.p.x = x;
      temp.p.y = y;
    
      //std::cout<<"\n("<<temp.p.x<<", "<<temp.p.y<<")";

      if(cellInPoly(poly, temp.p))
      {
        cells.push_back(temp);
      }
    }
  }
  

  std::vector<Cell> reduced_cells = cells;


  while(cells.size() > 0)
  {
    //std::cout<<"\nIn while cells.size(): "<<cells.size()<<" result.size(): "<<result.size();
    cells = reduced_cells;

    std::priority_queue<Cell, std::vector<Cell>, CompareDist> updated_pq;

    // Delete all cells whose centers lie in the largest circle
    if(result.size() > 0)
    {
      reduced_cells.clear();
      deleteCellsInCir(cells, result[result.size()-1], reduced_cells);
    }

    // Recalculate the distance, include existing circles!
    // For each cell, compute distance to the closest polygon edge
    for(int i=0;i<reduced_cells.size();i++)
    {
      Cell& cell = reduced_cells[i];

      double min_d=getMinDistToPoly(poly, cell);
      double min_cir=getMinDistToCirs(result,cell);

      if(min_d < min_cir || min_cir < 0)
      {
        cell.dist = min_d;
      }
      else
      {
        cell.dist = min_cir;
      }

      updated_pq.push(cell);
    } // end for each cell

    if(!updated_pq.empty())
    {
      Cell c = updated_pq.top();
      Circle temp;

      temp.center.x = c.p.x;
      temp.center.y = c.p.y;
      temp.radius = c.dist;

      result.push_back(temp);
    }
  }
  
  /*std::cout<<"\nFinal number of circles: "<<result.size();
  for(int i=0;i<result.size();i++)
  {
    std::cout<<"\nCircle "<<i<<" ("<<result[i].center.x<<", "<<result[i].center.y<<") radius: "<<result[i].radius;
  }*/

  return result;
}