diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e2fa2d..182ac49 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ macro(cm_example_project project_name) - target_link_libraries(${project_name} PRIVATE CMCore CMPlatform) + target_link_libraries(${project_name} PRIVATE CMCore CMPlatform CMUtil) if(UNIX) target_link_libraries(${project_name} PRIVATE dl) @@ -53,4 +53,7 @@ cm_example_project(OSFontList) target_link_libraries(OSFontList PRIVATE CMUtil) add_executable(RuntimeAssetManagerTest RuntimeAssetManagerTest.cpp RuntimeAssetManager.h RAM_TestClass.h RAM_TestClass.cpp) -cm_example_project(RuntimeAssetManagerTest) \ No newline at end of file +cm_example_project(RuntimeAssetManagerTest) + +add_executable(DistributionChart2D DistributionChart2D.cpp) +cm_example_project(DistributionChart2D) \ No newline at end of file diff --git a/DistributionChart2D.cpp b/DistributionChart2D.cpp new file mode 100644 index 0000000..b3be99c --- /dev/null +++ b/DistributionChart2D.cpp @@ -0,0 +1,360 @@ +#include +#include +#include +#include +#include +#include + +using namespace hgl; + +bool ParseLine(Vector2i *result,const UTF8String &str) +{ + if(!result)return(false); + + if(str.Length()<=0)return(false); + + const char *sp=str.c_str(); + const char *cp; + + if(*sp!='X')return(false); + + sp+=2; + cp=hgl::strchr(sp,'Y'); + + if(!cp)return(false); + + if(!hgl::stoi(sp,result->x)) + return(false); + + sp=cp+2; + + cp=hgl::strchr(sp,'Z'); + + if(!cp)return(false); + + if(!hgl::stoi(sp,result->y)) + return(false); + + return(true); +} + +struct PositionStat +{ + uint count; + + Vector2i minp,maxp; + Vector2i gap; + + Vector2i *data; + +public: + + PositionStat(const uint c) + { + count=c; + + hgl_zero(minp); + hgl_zero(maxp); + hgl_zero(gap); + + data=new Vector2i[count]; + + hgl_zero(data,count); + } + + ~PositionStat() + { + delete[] data; + } +}; + +PositionStat *ToVector2i(const UTF8StringList &sl) +{ + const uint count=sl.GetCount(); + + PositionStat *ps=new PositionStat(count); + + Vector2i *p=ps->data; + + UTF8String str; + uint result=0; + + for(int i=0;ix>4096 + ||p->y>4096) + continue; + + (*p)/=4; + + //std::cout<<"X="<x<<",Y="<y<xminp.x)ps->minp.x=p->x; + if(p->x>ps->maxp.x)ps->maxp.x=p->x; +// if(p->yminp.y)ps->minp.y=p->y; + if(p->y>ps->maxp.y)ps->maxp.y=p->y; + + ++result; + ++p; + } + + //std::cout<<"minp: "<minp.x<<","<minp.y<maxp.x<<","<maxp.y<count=result; + + return ps; +} + +struct Chart +{ + uint width,height; + + uint min_count; + uint max_count; + uint gap; + + uint32 *count_data; + uint32 *circle_data; + uint8 *chart_data; + +public: + + Chart(const uint w,const uint h) + { + width=w; + height=h; + + count_data=new uint32[width*height]; + circle_data=new uint32[width*height]; + chart_data=new uint8[width*height*4]; + + hgl_zero(count_data,width*height); + hgl_zero(circle_data,width*height); + hgl_zero(chart_data,width*height*4); + + min_count=0; + max_count=0; + gap=0; + } + + ~Chart() + { + delete[] count_data; + delete[] circle_data; + delete[] chart_data; + } + + void Circle(uint x,uint y,uint radius) + { + uint r2=radius*radius; + uint length; + + for(int col=x-radius;col<=x+radius;col++) + { + if(col<0||col>=width)continue; + + for(int row=y-radius;row<=y+radius;row++) + { + if(row<0||row>=height)continue; + + length=(col-x)*(col-x)+(row-y)*(row-y); + + if(length<=r2) + ++circle_data[col+row*width]; + } + } + } +}; + +Chart *ToChart32(const PositionStat *ps) +{ + uint width=ps->maxp.x-ps->minp.x+1; + uint height=ps->maxp.y-ps->minp.y+1; + + std::cout<<"width: "<count_data; + + const Vector2i *p=ps->data; + + for(uint i=0;icount;i++) + { + x=p->x-ps->minp.x; + y=p->y-ps->minp.y; + + cp32=chart->count_data+(x+y*width); + + if(*cp32<0xFFFFFFFF) + ++(*cp32); + + ++p; + } + } + + //画圆 + { + uint32 *cp32=chart->count_data; + + for(uint y=0;y0) + chart->Circle(x,y,(*cp32)*10); + + ++cp32; + } + } + } + + //统计最小值、最大值 + { + uint32 *cp32=chart->circle_data; + + for(uint i=0;imin_count)chart->min_count=*cp32; + if(*cp32>chart->max_count)chart->max_count=*cp32; + + ++cp32; + } + + chart->gap=chart->max_count-chart->min_count; + + std::cout<<"min_count: "<min_count<<",max_count: "<max_count<<",gap: "<gap<circle_data; + uint8 *cp8=chart->chart_data; + + float result; + float r,g,b; + + //1.0 1 0 0 + //0.8 1 1 0 + //0.6 0 1 0 + //0.4 0 1 1 + //0.2 0 0 1 + //0.0 0 0 0 + + for(uint i=0;imin_count)/float(chart->gap); + + if(result>=0.8f) //0.8 - 1.0 + { + r=1.0f; + g=1.0f-(result-0.8f)*5.0f; + b=0.0f; + } + else + { + if(result>=0.6f) //0.6 - 0.8 + { + r=(result-0.6f)*5.0f; + g=1.0f; + b=0; + } + else + { + if(result>=0.4f) //0.4 - 0.6 + { + r=0.0f; + g=1.0f; + b=1.0f-(result-0.4f)*5.0f; + } + else + if(result>=0.2f) //0.2 - 0.4 + { + r=0.0f; + g=(result-0.2f)*5.0f; + b=1.0f; + } + else //0.0 - 0.25 + { + r=0.0f; + g=0.0f; + b=result*5.0f; + } + } + } + + cp8[0]=b*255.0f; + cp8[1]=g*255.0f; + cp8[2]=r*255.0f; + cp8[3]=result*255.0f; + + ++cp32; + cp8+=4; + } + } + + return chart; +} + +int os_main(int argc,os_char **argv) +{ + std::cout<<"Distribution Chart 2D"< ps=ToVector2i(sl); + + AutoDelete chart=ToChart32(ps); + + + { + util::TGAHeader tga_header; + + util::FillTGAHeader(&tga_header,chart->width,chart->height,4); + + io::OpenFileOutputStream fos(OS_TEXT("chart.tga"),io::FileOpenMode::CreateTrunc); + + if(!fos) + { + std::cerr<<"Create chart.tga failed!"<Write(&tga_header,util::TGAHeaderSize); + fos->Write(chart->chart_data,chart->width*chart->height*4); + fos->Close(); + } + + return 0; +} \ No newline at end of file diff --git a/RAM_TestClass.h b/RAM_TestClass.h index 2fd9a80..6bd1ed7 100644 --- a/RAM_TestClass.h +++ b/RAM_TestClass.h @@ -15,6 +15,11 @@ public: using RuntimeAsset::RuntimeAsset; + ~Instance() + { + std::cout<<"~Instance("<