// // RandomGridFiller.hpp // auto_fill_jewel_v3 // // Created by Red on 2024/11/26. // 随机矩形填充 // 1. 每个宝石使用其外接矩形。 // 2. 采用随机点位填充到盘子中,不考虑宝石之间重叠率问题,但是宝石必须要在盘子内部。 // 3. 尝试5次,最后选择一组重叠率最小的。 // 4. 要求效率尽量高,2帧完成一关宝石填充(?) #ifndef RandomGridFiller_hpp #define RandomGridFiller_hpp #include #include #include "FillResult.hpp" #include "contourdata.h" #include #include "BoostGeometryTools.hpp" using std::unordered_map; using std::vector; struct RandomGridFiller { //输入数据的结构 宝石的外接矩形 struct JewelBox { inline JewelBox():_cnt(0),_width(0),_height(0),_jewelTypeId(-1){} int _cnt ;//宝石个数 float _width; //外接矩形宽度(像素) float _height ;//外接矩形高度(像素) int _jewelTypeId ; } ; int _seed ; //对外接口 void fill( vector& jewelsArray , //需要填充的宝石 float bottomLeftX,float bottomLeftY,//盘子有效区域 float topRightX,float topRightY, //盘子有效区域 vector& results //尝试五组只选择一个覆盖度最小的填充结果 ); private: //潜在的点位 struct DistancePosition { bool _isTaken ; float _distance ; ContourData::Point _point ; } ; //格点占用数据 struct GridData { inline void reset(float blx,float bly,float sx,float sy,int nrows,int ncols){ _bottomLeftX = blx; _bottomLeftY = bly; _stepX = sx ; _stepY = sy ; _rows.resize(nrows); for(auto it=_rows.begin();it!=_rows.end();++it)it->resize(ncols,false); } inline void clearValues(){for(auto it=_rows.begin();it!=_rows.end();++it)it->resize(it->size(),false); } vector< vector > _rows ; float _bottomLeftX, _bottomLeftY ;//左下角原点坐标 float _stepX,_stepY ;//格点间隔 } ; // 返回未填进去的宝石数量,目前看没有填进去已经表示本次填充失败了 int randomFillOneRound( vector& jewelsArray, float bottomLeftX,float bottomLeftY,//盘子有效区域 float topRightX,float topRightY, //盘子有效区域 vector potPositions, //潜在的点位 vector& results, float& jewDistanceSum //宝石间距离求和,用于衡量宝石间的分散程度 ,const float gridWid //盘子子网格宽度 ,const float gridhei //盘子子网格高度 ,int& resultTotCov //返回全部宝石格点叠盖度之和 ) ; //随机排序索引值 vector randIndices(const int count0 ); //假定每个网格覆盖一次宝石其对应的int值加一,下面函数用于统计某个点位(x,y)(盘子内部坐标,与subGrid对齐)周边半径个网格覆盖值的求和。 //最优条件是求和值为0。虽然宝石一般使用矩形描述,这里为了将点坐标覆盖的一个区域换算到 subGrid 格子数方便,使用圆形进行计算。 [[deprecated]] int sumOfSubGridTakenCounts(const int x,const int y,const int radius,const float gridwid,const float gridhei,const vector>& rowColSubGrid); //为中心点位x,y,半径radius的覆盖范围的subgrid占用数加1。 [[deprecated]] void subGridTakenCountsAddOne(const int x,const int y,const int radius,const float gridwid,const float gridhei,vector>& rowColSubGrid); //多边形盖住的格点数量 int coverageGridCount( BoostGeometryTools::BoostPolygon& box, const GridData& grid ) ; //全部覆盖求和,excludeIndex 不做比较的索引值 int totalCoverageGridCount(BoostGeometryTools::BoostPolygon& box, const vector& grids , int excludeIndex=-1 ) ; //将覆盖的格点数据赋值 void setGridCoverageByBox( BoostGeometryTools::BoostPolygon& box, GridData& grid ) ; //按距离从外到内构建随机点位 void generateDistanceRandomSlotPositions(const float centerx,const float centery,const vector& points, vector& results ) ; } ; #endif /* RandomGridFiller_hpp */