| /* |
| Copyright 2005-2010 Intel Corporation. All Rights Reserved. |
| |
| This file is part of Threading Building Blocks. |
| |
| Threading Building Blocks is free software; you can redistribute it |
| and/or modify it under the terms of the GNU General Public License |
| version 2 as published by the Free Software Foundation. |
| |
| Threading Building Blocks is distributed in the hope that it will be |
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
| of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with Threading Building Blocks; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| As a special exception, you may use this file as part of a free software |
| library without restriction. Specifically, if other files instantiate |
| templates or use macros or inline functions from this file, or you compile |
| this file and link it with other files to produce an executable, this |
| file does not by itself cause the resulting executable to be covered by |
| the GNU General Public License. This exception does not however |
| invalidate any other reasons why the executable file might be covered by |
| the GNU General Public License. |
| */ |
| |
| // Polygon overlay |
| // |
| // Don't want warnings about deprecated sscanf, getenv |
| #ifndef _CRT_SECURE_NO_DEPRECATE |
| #define _CRT_SECURE_NO_DEPRECATE |
| #endif |
| #define _MAIN_C_ 1 |
| #include <iostream> |
| #include <iomanip> |
| #include <algorithm> |
| #include <cstring> |
| |
| #include "tbb/tick_count.h" |
| #include "tbb/task_scheduler_init.h" |
| #include "pover_global.h" |
| #include "polyover.h" |
| #include "pover_video.h" |
| #include "polymain.h" |
| |
| using namespace std; |
| |
| #if _DEBUG |
| const char *faceNames[] = { "North", "East", "South", "West" }; |
| #endif |
| |
| /** |
| **/ |
| int main( int argc, char **argv) { |
| pover_video poly; |
| poly.threaded = true; |
| gVideo = &poly; |
| |
| if(!initializeVideo(argc, argv)) { |
| return 1; |
| } |
| |
| gIsGraphicalVersion = poly.graphic_display(); |
| if(argc > 1) { |
| if(!ParseCmdLine(argc, argv)) { |
| if(gIsGraphicalVersion) rt_sleep(10000); |
| // if graphical, we haven't opened the console window so all the error messages we |
| // so carefully wrote out disappeared into the ether. :( |
| exit(1); |
| } |
| } |
| |
| if(gCsvFilename != NULL) { |
| #define BUFLEN 1000 |
| std::string fname_buf = gCsvFilename; |
| fname_buf += ".csv"; |
| gCsvFile.open(fname_buf.c_str()); |
| } |
| |
| // we have gMapXSize and gMapYSize determining the number of "squares" |
| // we have g_xwinsize and g_ywinsize the total size of the window |
| // we also have BORDER_SIZE the size of the border between maps |
| // we need to determine |
| // g_polyBoxSize -- the number of pixels on each size of each square |
| |
| if(gIsGraphicalVersion) { |
| int xpixelsPerMap = (g_xwinsize - 4*BORDER_SIZE) / 3; // three maps, with borders between and outside |
| gMapXSize = xpixelsPerMap; // make the boxes one per pixel |
| gPolyXBoxSize = xpixelsPerMap / gMapXSize; |
| int ypixelsPerMap = (g_ywinsize - 2*BORDER_SIZE); // one map vertically |
| gMapYSize = ypixelsPerMap; // one pixel per box, rather. |
| |
| gPolyYBoxSize = ypixelsPerMap / gMapYSize; |
| if((gPolyXBoxSize == 0) || (gPolyYBoxSize == 0)) { |
| cout << "The display window is not large enough to show the maps" << std::endl; |
| int minxSize = 4*BORDER_SIZE + 3*gMapXSize; |
| int minySize = 2*BORDER_SIZE + gMapYSize; |
| cout << " Should be at least " << minxSize << " x " << minySize << "." << std::endl; |
| return 1; |
| } |
| map2XLoc = 2*BORDER_SIZE + gMapXSize * gPolyXBoxSize; |
| maprXLoc = 3*BORDER_SIZE + 2 * gMapXSize * gPolyXBoxSize; |
| |
| } |
| else { // not gIsGraphicalVersion |
| // gMapXSize, gMapYSize, gNPolygons defined in pover_global.h |
| } |
| |
| // create two polygon maps |
| SetRandomSeed(gMyRandomSeed); // for repeatability |
| |
| gVideo->main_loop(); |
| } |
| |
| void Usage(int argc, char **argv) { |
| char *cmdTail = strrchr(*argv, '\\'); |
| if(cmdTail == NULL) { |
| cmdTail = *argv; |
| } |
| else { |
| cmdTail++; |
| } |
| cout << cmdTail << " [threads[:threads2]] [--polys npolys] [--size nnnxnnn] [--seed nnn]" << std::endl; |
| cout << "Create polygon maps and overlay them." << std::endl << std::endl; |
| cout << "Parameters:" << std::endl; |
| cout << " threads[:threads2] - number of threads to run" << std::endl; |
| cout << " --polys npolys - number of polygons in each map" << std::endl; |
| cout << " --size nnnxnnn - size of each map (X x Y)" << std::endl; |
| cout << " --seed nnn - initial value of random number generator" << std::endl; |
| cout << " --csv filename - write timing data to CSV-format file" << std::endl; |
| cout << " --grainsize n - set grainsize to n" << std::endl; |
| cout << " --use_malloc - allocate polygons with malloc instead of scalable allocator" << std::endl; |
| cout << std::endl; |
| cout << "npolys must be smaller than the size of the map" << std::endl; |
| cout << std::endl; |
| exit(1); |
| } |
| |
| bool ParseCmdLine(int argc, char **argv ) { |
| bool error_found = false; |
| bool nPolysSpecified = false; |
| bool nMapSizeSpecified = false; |
| bool nSeedSpecified = false; |
| bool csvSpecified = false; |
| bool grainsizeSpecified = false; |
| bool mallocSpecified = false; |
| int origArgc = argc; |
| char** origArgv = argv; |
| unsigned int newnPolygons = gNPolygons; |
| unsigned int newSeed = gMyRandomSeed; |
| unsigned int newX = gMapXSize; |
| unsigned int newY = gMapYSize; |
| unsigned int newGrainSize = gGrainSize; |
| argc--; argv++; |
| if(argc > 0 && isdigit((*argv)[0])) { |
| // first argument is one or two numbers, specifying how mny threads to run |
| char* end; gThreadsHigh = gThreadsLow = (int)strtol(argv[0],&end,0); |
| switch( *end) { |
| case ':': gThreadsHigh = (int)strtol(end+1,0,0); break; |
| case '\0': break; |
| default: cout << "Unexpected character in thread specifier: " << *end << std::endl; break; |
| } |
| if(gThreadsLow > gThreadsHigh) { |
| int t = gThreadsLow; |
| gThreadsLow = gThreadsHigh; |
| gThreadsHigh = t; |
| } |
| argv++; argc--; |
| } |
| while(argc > 0) { |
| // format 1: --size nnnxnnn, where nnn in {0 .. 9}+ -- size of map in "squares" |
| if(!strncmp("--size", *argv, (size_t)6)) { |
| if(nMapSizeSpecified) { |
| cout << " Error: map size multiply specified" << std::endl; |
| error_found = true; |
| } |
| else { |
| argv++; argc--; |
| if(argc == 0) { |
| error_found = true; |
| cout << " Error: --size must have a value" << std::endl; |
| } |
| if(strchr(*argv, 'x') != strrchr(*argv,'x')) { |
| // more than one 'x' |
| cout << "Error: map size should be nnnxnnn (" << *argv << ")" << std::endl; |
| error_found = true; |
| } |
| else { |
| int rval; |
| rval = sscanf(*argv, "%ux%u", &newX, &newY); |
| if(rval != 2) { |
| cout << "Error parsing map size (format should be nnnxnnn (" << *argv << ")" << std::endl; |
| error_found = true; |
| } |
| if(newX == 0 || newY == 0) { |
| cout << "Error: size of map should be greater than 0 (" << *argv << ")" << std::endl; |
| error_found = true; |
| } |
| } |
| } |
| argc--; argv++; |
| } |
| // format 2: --seed nnn -- initial random number seed |
| else if(!strncmp("--seed", *argv, (size_t)6)) { |
| argv++; argc--; |
| if(nSeedSpecified) { |
| cout << "Error: new seed multiply specified" << std::endl; |
| error_found = true; |
| } |
| else { |
| nSeedSpecified = true; |
| int rtval = sscanf(*argv, "%u", &newSeed); |
| if(rtval == 0) { |
| cout << "Error: --seed should be an unsigned number (instead of " << *argv << ")" << std::endl; |
| error_found = true; |
| } |
| } |
| argv++; argc--; |
| } |
| // format 3: --polys n[n] -- number of polygons in each map |
| else if(!strncmp("--polys", *argv, (size_t)7)) { |
| //unsigned int newnPolygons; |
| argv++; argc--; |
| if(nPolysSpecified) { |
| cout << "Error: number of polygons multiply-specified" << std::endl; |
| error_found = true; |
| }else { |
| int rtval = sscanf(*argv, "%u", &newnPolygons); |
| if(newnPolygons == 0) { |
| cout << "Error: number of polygons must be greater than 0 (" << *argv << ")" << std::endl; |
| } |
| } |
| argv++; argc--; |
| } |
| // format 4: --csv <fileroot> -- name of CSV output file ("xxx" for "xxx.csv") |
| else if(!strncmp("--csv", *argv, (size_t)5)) { |
| argv++; argc--; |
| if(csvSpecified) { |
| cout << "Error: Multiple specification of CSV file" << std::endl; |
| error_found = true; |
| } |
| else { |
| gCsvFilename = *argv; |
| argv++; argc--; |
| csvSpecified = true; |
| } |
| } |
| else if(!strncmp("--grainsize", *argv, (size_t)11)) { |
| argv++; argc--; |
| if(grainsizeSpecified) { |
| cout << "Error: Multiple specification of grainsize" << std::endl; |
| error_found = true; |
| } |
| else { |
| int grval = sscanf(*argv, "%u", &newGrainSize); |
| grainsizeSpecified = true; |
| if(newGrainSize == 0) { |
| cout << "Error: grainsize must be greater than 0" << std::endl; |
| error_found = true; |
| } |
| } |
| argv++; argc--; |
| } |
| else if(!strncmp("--use_malloc", *argv, (size_t)12)) { |
| argv++; argc--; |
| if(mallocSpecified) { |
| cout << "Error: --use_malloc multiply-specified" << std::endl; |
| error_found = true; |
| } |
| else { |
| mallocSpecified = true; |
| gMBehavior = UseMalloc; |
| } |
| } |
| else { |
| cout << "Error: unrecognized argument: " << *argv << std::endl; |
| error_found = true; |
| argv++; argc--; |
| } |
| } |
| if(!error_found) { |
| if(newX * newY < newnPolygons) { |
| error_found = true; |
| cout << "Error: map size should not be smaller than the number of polygons (gNPolygons = " << newnPolygons << ", map size " << newX << "x" << newY << ")" << std::endl; |
| } |
| } |
| if(!error_found) { |
| gMapXSize = newX; |
| gMapYSize = newY; |
| gNPolygons = newnPolygons; |
| gMyRandomSeed = newSeed; |
| gGrainSize = (int)newGrainSize; |
| } |
| else { |
| Usage(origArgc, origArgv); |
| } |
| return !error_found; |
| } |
| |
| // create a polygon map with at least gNPolygons polygons. |
| // Usually more than gNPolygons polygons will be generated, because the |
| // process of growing the polygons results in holes. |
| bool GenerateMap(Polygon_map_t **newMap, int xSize, int ySize, int gNPolygons, colorcomp_t maxR, colorcomp_t maxG, colorcomp_t maxB) { |
| bool error_found = false; |
| int *validPolys; |
| int *validSide; |
| int maxSides; |
| RPolygon *newPoly; |
| |
| if(xSize <= 0) { |
| cout << "xSize (" << xSize << ") should be > 0." << std::endl; |
| error_found = true; |
| } |
| if(ySize <= 0) { |
| cout << "ySize (" << ySize << ") should be > 0." << std::endl; |
| error_found = true; |
| } |
| if(gNPolygons > (xSize * ySize)) { |
| cout << "gNPolygons (" << gNPolygons << ") should be less than " << (xSize * ySize) << std::endl; |
| error_found = true; |
| } |
| if(error_found) return false; |
| // the whole map is [xSize x ySize] squares |
| // the way we create the map is to |
| // 1) pick nPolygon discrete squares on an [xSize x ySize] grid |
| // 2) while there are unused squares on the grid |
| // 3) pick a polygon with a side that has unused squares on a side |
| // 4) expand the polygon by 1 to occupy the unused squares |
| // |
| // Continue until every square on the grid is occupied by a polygon |
| int *tempMap; |
| tempMap = (int *)malloc(xSize * ySize * sizeof(int)); |
| for(int i=0;i < xSize; i++) { |
| for(int j=0;j < ySize; j++) { |
| tempMap[i*ySize + j] = 0; |
| } |
| } |
| |
| // *newMap = new vector<RPolygon>; |
| *newMap = new Polygon_map_t; |
| (*newMap)->reserve(gNPolygons + 1); // how much bigger does this need to be on average? |
| newPoly = RPolygon::alloc_RPolygon(0,0,xSize-1, ySize-1); |
| (*newMap)->push_back(newPoly); |
| for(int i=0; i < gNPolygons; i++) { |
| int nX; |
| int nY; |
| do { // look for an empty square. |
| nX = NextRan(xSize); |
| nY = NextRan(ySize); |
| } while(tempMap[nX * ySize + nY] != 0); |
| int nR = (maxR * NextRan(1000)) / 999; |
| int nG = (maxG * NextRan(1000)) / 999; |
| int nB = (maxB * NextRan(1000)) / 999; |
| newPoly = RPolygon::alloc_RPolygon(nX,nY,nX,nY,nR,nG,nB); |
| (*newMap)->push_back(newPoly); |
| tempMap[nX * ySize + nY] = i+1; // index of this polygon + 1 |
| } |
| // now have to grow polygons to fill the space. |
| validPolys = (int *)malloc(4*gNPolygons * sizeof(int)); |
| validSide = (int *)malloc(4*gNPolygons * sizeof(int)); |
| for(int i=0;i<gNPolygons;i++) { |
| validPolys[4*i] = validPolys[4*i + 1] = validPolys[4*i + 2] = validPolys[4*i + 3] = i + 1; |
| validSide[4*i] = NORTH_SIDE; |
| validSide[4*i+1] = EAST_SIDE; |
| validSide[4*i+2] = SOUTH_SIDE; |
| validSide[4*i+3] = WEST_SIDE; |
| } |
| maxSides = 4*gNPolygons; |
| while(maxSides > 0) { |
| int indx = NextRan(maxSides); |
| int polyIndx = validPolys[indx]; |
| int checkSide = validSide[indx]; |
| int xlow, xhigh, ylow, yhigh; |
| int xlnew, xhnew, ylnew, yhnew; |
| (**newMap)[polyIndx]->get(&xlow,&ylow,&xhigh,&yhigh); |
| xlnew = xlow; |
| xhnew = xhigh; |
| ylnew = ylow; |
| yhnew = yhigh; |
| // can this polygon be expanded along the chosen side? |
| switch(checkSide) { |
| case NORTH_SIDE: |
| // y-1 from xlow to xhigh |
| ylow = yhigh = (ylow - 1); |
| ylnew--; |
| break; |
| case EAST_SIDE: |
| // x+1 from ylow to yhigh |
| xlow = xhigh = (xhigh + 1); |
| xhnew++; |
| break; |
| case SOUTH_SIDE: |
| // y+1 from xlow to xhigh |
| ylow = yhigh = (yhigh+1); |
| yhnew++; |
| break; |
| case WEST_SIDE: |
| // x-1 from ylow to yhigh |
| xlow = xhigh = (xlow - 1); |
| xlnew--; |
| break; |
| } |
| bool okay_to_extend = !(((xlow < 0) || (xlow >= xSize)) || ((ylow < 0) || (ylow >= ySize))); |
| for(int ii = xlow; (ii <= xhigh) && okay_to_extend; ii++) { |
| for(int jj=ylow; (jj <= yhigh) && okay_to_extend; jj++) { |
| okay_to_extend = tempMap[ii*ySize + jj] == 0; |
| } |
| } |
| if(okay_to_extend) { |
| (**newMap)[polyIndx]->set(xlnew,ylnew,xhnew,yhnew); |
| for(int ii = xlow; ii <= xhigh; ii++) { |
| for(int jj=ylow; jj <= yhigh && okay_to_extend; jj++) { |
| tempMap[ii*ySize + jj] = polyIndx; |
| } |
| } |
| } |
| else { |
| // once we cannot expand along a side, we will never be able to; remove from the list. |
| for(int i=indx + 1; i < maxSides; i++) { |
| validPolys[i-1] = validPolys[i]; |
| validSide[i-1] = validSide[i]; |
| } |
| maxSides--; |
| } |
| } |
| |
| // Once no polygons can be grown, look for unused squares, and fill them with polygons. |
| for(int j=0;j<ySize;j++) { |
| for(int i=0;i<xSize;i++) { |
| if(tempMap[i*ySize+j] == 0) { |
| // try to grow in the x direction, then the y direction |
| int ilen = i; |
| int jlen = j; |
| while(ilen < (xSize - 1) && tempMap[(ilen+1)*ySize + jlen] == 0) { |
| ilen++; |
| } |
| bool yok = true; |
| while(yok && jlen < (ySize - 1)) { |
| for(int ii = i; ii <= ilen && yok; ii++) { |
| yok = (tempMap[ii*ySize + jlen + 1] == 0); |
| } |
| if(yok) { |
| jlen++; |
| } |
| } |
| |
| // create new polygon and push it on our list. |
| int nR = (maxR * NextRan(1000)) / 999; |
| int nG = (maxG * NextRan(1000)) / 999; |
| int nB = (maxB * NextRan(1000)) / 999; |
| newPoly = RPolygon::alloc_RPolygon(i,j,ilen,jlen,nR,nG,nB); |
| (*newMap)->push_back(newPoly); |
| gNPolygons++; |
| for(int ii=i; ii<=ilen;ii++) { |
| for(int jj=j;jj<=jlen;jj++) { |
| tempMap[ii*ySize + jj] = gNPolygons; |
| } |
| } |
| } |
| } |
| } |
| |
| #if _DEBUG |
| if(!gIsGraphicalVersion) { |
| cout << std::endl << "Final Map:" << std::endl; |
| for(int j=0; j < ySize; j++ ) { |
| cout << "Row " << setw(2) << j << ":"; |
| for(int i=0;i<xSize;i++) { |
| int it = tempMap[i*ySize + j]; |
| if(it<10) { |
| cout << setw(2) << it; |
| } |
| else { |
| char ct = (int)'a' + it - 10; |
| cout << " " << ct; |
| } |
| } |
| cout << std::endl; |
| } |
| } |
| #endif // _DEBUG |
| free(tempMap); |
| free(validPolys); |
| free(validSide); |
| return true; |
| } |
| |
| void CheckPolygonMap(Polygon_map_t *checkMap) { |
| #define indx(i,j) (i*gMapYSize + j) |
| #define rangeCheck(str,n,limit) if(((n)<0)||((n)>=limit)) {cout << "checkMap error: " << str << " out of range (" << n << ")" << std::endl;anError=true;} |
| #define xRangeCheck(str,n) rangeCheck(str,n,gMapXSize) |
| #define yRangeCheck(str,n) rangeCheck(str,n,gMapYSize) |
| // The first polygon is the whole map. |
| bool anError = false; |
| int *cArray; |
| if(checkMap->size() <= 0) { |
| cout << "checkMap error: no polygons in map" << std::endl; |
| return; |
| } |
| // mapXhigh and mapYhigh are inclusive, that is, if the map is 5x5, those values would be 4. |
| int mapXhigh, mapYhigh, mapLowX, mapLowY; |
| int gMapXSize, gMapYSize; |
| checkMap->at(0)->get(&mapLowX, &mapLowY, &mapXhigh, &mapYhigh); |
| if((mapLowX !=0) || (mapLowY != 0)) { |
| cout << "checkMap error: map origin not (0,0) (X=" << mapLowX << ", Y=" << mapLowY << ")" << std::endl; |
| anError = true; |
| } |
| if((mapXhigh < 0) || (mapYhigh < 0)) { |
| cout << "checkMap error: no area in map (X=" << mapXhigh << ", Y=" << mapYhigh << ")" << std::endl; |
| anError = true; |
| } |
| if(anError) return; |
| // bounds for array. |
| gMapXSize = mapXhigh + 1; |
| gMapYSize = mapYhigh + 1; |
| cArray = (int *)malloc(sizeof(int)*(gMapXSize*gMapYSize)); |
| |
| for(int i=0; i<gMapXSize; i++) { |
| for(int j=0; j< gMapYSize; j++) { |
| cArray[indx(i,j)] = 0; |
| } |
| } |
| |
| int xlow, xhigh, ylow, yhigh; |
| for(int p=1; p < int(checkMap->size()) && !anError; p++) { |
| checkMap->at(p)->get(&xlow, &ylow, &xhigh, &yhigh); |
| xRangeCheck("xlow", xlow); |
| yRangeCheck("ylow", ylow); |
| xRangeCheck("xhigh", xhigh); |
| yRangeCheck("yhigh", yhigh); |
| if(xlow>xhigh) { |
| cout << "checkMap error: xlow > xhigh (" << xlow << "," << xhigh << ")" << std::endl; |
| anError = true; |
| } |
| if(ylow>yhigh) { |
| cout << "checkMap error: ylow > yhigh (" << ylow << "," << yhigh << ")" << std::endl; |
| anError = true; |
| } |
| for(int ii = xlow; ii <= xhigh; ii++) { |
| for(int jj = ylow; jj <= yhigh; jj++) { |
| if(cArray[indx(ii,jj)] != 0) { |
| cout << "checkMap error: polygons " << cArray[indx(ii,jj)] << " and " << p << " intersect" << std::endl; |
| anError = true; |
| } |
| cArray[indx(ii,jj)] = p; |
| } |
| } |
| } |
| for(int ii=0; ii < gMapXSize; ii++) { |
| for(int jj=0; jj < gMapYSize; jj++) { |
| if(cArray[indx(ii,jj)] == 0) { |
| cout << "checkMap error: block(" << ii << ", " << jj << ") not in any polygon" << std::endl; |
| anError = true; |
| } |
| } |
| } |
| free(cArray); |
| } |
| |
| bool CompOnePolygon(RPolygon *p1, RPolygon *p2) { |
| int xl1, xh1, yl1, yh1; |
| int xl2, xh2, yl2, yh2; |
| p1->get(&xl1, &yl1, &xh1, &yh1); |
| p2->get(&xl2, &yl2, &xh2, &yh2); |
| if(yl1>yl2) return true; |
| if(yl1<yl2) return false; |
| return (xl1 > xl2); |
| } |
| |
| bool PolygonsEqual(RPolygon *p1, RPolygon *p2) { |
| int xl1, xh1, yl1, yh1; |
| int xl2, xh2, yl2, yh2; |
| p1->get(&xl1, &yl1, &xh1, &yh1); |
| p2->get(&xl2, &yl2, &xh2, &yh2); |
| return ((xl1 == xl2) && (yl1==yl2) && (xh1 == xh2) && (yh1 == yh2)); |
| } |
| |
| bool ComparePolygonMaps(Polygon_map_t *map1, Polygon_map_t *map2) { |
| // create two new polygon maps, copy the pointers from the original to these. |
| // we have to skip the first polygon, which is the size of the whole map |
| Polygon_map_t *t1, *t2; |
| bool is_ok = true; |
| t1 = new Polygon_map_t; |
| t1->reserve(map1->size()); |
| for(unsigned int i=1;i<map1->size(); i++) { |
| t1->push_back(map1->at(i)); |
| } |
| t2 = new Polygon_map_t; |
| t2->reserve(map2->size()); |
| for(unsigned int i=1;i<map2->size();i++) { |
| t2->push_back(map2->at(i)); |
| } |
| // sort the two created maps by (xlow, ylow) |
| sort(t1->begin(), t1->end(), CompOnePolygon); |
| sort(t2->begin(), t2->end(), CompOnePolygon); |
| // compare each element of both maps. |
| if(t1->size() != t2->size()) { |
| cout << "Error: maps not the same size ( " << int(t1->size()) << " vs " << int(t2->size()) << ")." << std::endl; |
| } |
| int maxSize = (int)((t1->size() < t2->size()) ? t1->size() : t2->size()); |
| for(int i=0; i < maxSize; i++) { |
| if(!PolygonsEqual(t1->at(i), t2->at(i))) { |
| cout << "Error: polygons unequal (" << *(t1->at(i)) << " vs " << (*t2->at(i)) << std::endl; |
| is_ok = false; |
| } |
| } |
| delete t1; |
| delete t2; |
| return is_ok; |
| } |
| |
| void SetRandomSeed(int newSeed) { |
| srand((unsigned)newSeed); |
| } |
| |
| int NextRan(int n) { |
| // assert(n > 1); |
| // if we are given 1, we will just return 0 |
| //assert(n < RAND_MAX); |
| int rrand = rand() << 15 | rand(); |
| if(rrand < 0) rrand = -rrand; |
| return rrand % n; |
| } |
| |
| std::ostream& operator<<(std::ostream& s, const RPolygon &p) { |
| int xl, yl, xh, yh; |
| p.get(&xl, &yl, &xh, &yh); |
| return s << "[(" << xl << "," << yl << ")-(" << xh << "," << yh << ")] "; |
| } |