/* *-------------------------------------------------- *-------------------------------------------------- */ 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); }
/* *-------------------------------------------------- * *-------------------------------------------------- */ 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; } }
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; }