online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
//диаграмма Вороного + вывод на битмап #include "s_bmp.h" #include <iostream> #include <cmath> #include <algorithm> #include <random> #include <optional> #include <utility> int main() { auto file_name = "DV.bmp"; s_bmp bmp; bmp.SetSize(200,200); constexpr size_t points_count=20; constexpr bool borders=true; constexpr RGBTRIPLE borders_color{40,40,40}; const auto wid=bmp.Wid(); const auto hig=bmp.Hig(); std::random_device rd; std::mt19937 gen{rd()}; std::uniform_int_distribution<unsigned int> dist_x(0, wid-1); std::uniform_int_distribution<unsigned int> dist_y(0, hig-1); std::uniform_int_distribution<unsigned int> dist_r(50, 230);//0...255 std::uniform_int_distribution<unsigned int> dist_g(50, 230);//0...255 std::uniform_int_distribution<unsigned int> dist_b(50, 230);//0...255 using s_point = s_bmp::s_point; using s_point_colored = s_bmp::s_point_colored; using COORDTYPE = s_bmp::COORDTYPE; std::vector<s_point_colored> points(points_count); for(auto& p : points) { p.p.x=dist_x(gen); p.p.y=dist_y(gen); p.color.R=dist_r(gen); p.color.G=dist_g(gen); p.color.B=dist_b(gen); } if(!points.empty()) { //хранит квадраты расстояний std::vector<COORDTYPE> distances(points.size()); auto GetMinDistanceIndex=[&distances,&points,wid,hig](s_point p_pix)->size_t { //assert(distances.size()==points.size()); for(size_t i=0; i<distances.size(); ++i) { auto dx1=std::abs(p_pix.x - points[i].p.x); auto dx2=wid-dx1; auto dx = std::min(dx1,dx2); auto dy1=std::fabs(p_pix.y - points[i].p.y); auto dy2=hig-dy1; auto dy = std::min(dy1,dy2); distances[i] = dx*dx+dy*dy; } //assert(points.size()); auto it_d = std::min_element(distances.begin(),distances.end()); return it_d - distances.begin(); }; std::vector<size_t> distances_prev_y; if(borders) { distances_prev_y.reserve(wid); } for(COORDTYPE y = 0; y<hig; ++y) { std::optional<size_t> index_L; size_t p_index{}; for(COORDTYPE x = 0; x<wid; index_L=p_index, ++x) { const s_point p_pix{x,y}; p_index =GetMinDistanceIndex(p_pix); if(borders) { //точка левее границы if(index_L) { if(*index_L!=p_index){bmp.DrawPoint({p_pix.x-1,p_pix.y}, borders_color); continue;} } //точка выше границы if(y==0) { distances_prev_y[x]=p_index; } else { auto prev_y_index=std::exchange(distances_prev_y[x],p_index); s_point pT{x,y-1}; if(prev_y_index!=p_index){bmp.DrawPoint(p_pix, borders_color); continue;} } } //точка с цветом локального центра bmp.DrawPoint(p_pix, points[p_index].color); } } } //локальные центры #if 0 for(auto& p : points) { bmp.DrawEllipse(p.p, 1, {}); } #endif bmp.SaveToFile(file_name); }
#pragma once #include <cstdint> using BYTE = uint8_t; using WORD = uint16_t; using DWORD = uint32_t; using LONG = uint32_t; #pragma pack(push, 1) struct BITMAPFILEHEADER { WORD bfType;//'B', 'M' DWORD bfSize;//574 WORD bfReserved1;//==0 WORD bfReserved2;//==0 DWORD bfOffBits;//54 }; #pragma pack(pop) static_assert( sizeof(BITMAPFILEHEADER) == 14); #pragma pack(push, 1) struct BITMAPINFOHEADER { DWORD biSize;//40 LONG biWidth;//17 LONG biHeight;//10 WORD biPlanes;//1 WORD biBitCount;//24 DWORD biCompression;//0 DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; }; #pragma pack(pop) static_assert( sizeof(BITMAPINFOHEADER) == 40); #pragma pack(push, 1) struct RGBTRIPLE { BYTE B; BYTE G; BYTE R; }; #pragma pack(pop) static_assert( sizeof(RGBTRIPLE) == 3);
#pragma once #include "bitmap_headers.h" #include <vector> #include <string> #include <cmath> #include <cassert> #include <climits> #include <fstream> class s_bmp { public: using COORDTYPE = float; inline static const COORDTYPE accur = 0.00001; private: using PHISCOORDTYPE=uint32_t; PHISCOORDTYPE m_wid{}; PHISCOORDTYPE m_hig{}; std::vector<RGBTRIPLE> m_pixels; public: struct s_point { COORDTYPE x; COORDTYPE y; }; struct s_point_colored { s_point p; RGBTRIPLE color; }; struct s_line { s_point p1; s_point p2; bool IsHor()const { return std::fabs(p1.y-p2.y)<accur; } bool IsVer()const { return std::fabs(p1.x-p2.x)<accur; } bool IsPoint()const { return IsHor() && IsVer(); } auto DeltaX()const { return p2.x-p1.x; } auto DeltaY()const { return p2.y-p1.y; } }; struct s_rect { s_point p1; s_point p2; auto Wid()const { return p2.x-p1.x; } auto Hig()const { return p2.y-p1.y; } }; public: auto Wid()const{return m_wid;} auto Hig()const{return m_hig;} auto Center()const{return s_point{Wid()/2.0f, Hig()/2.0f};} auto Rect()const { return s_rect{{0,0},{ static_cast<COORDTYPE>(Wid()-1), static_cast<COORDTYPE>(Hig()-1)}}; } void SetSize(PHISCOORDTYPE w, PHISCOORDTYPE h) { m_wid = std::min(w,PHISCOORDTYPE{400}); m_hig = std::min(h,PHISCOORDTYPE{400}); m_pixels.resize(m_wid*m_hig, RGBTRIPLE{0,0,0}); } void DrawPoint(s_point p, RGBTRIPLE color) { auto x_ph=static_cast<PHISCOORDTYPE>(p.x); if(x_ph>=Wid())return; auto y_ph=static_cast<PHISCOORDTYPE>(p.y); if(y_ph>=Hig())return; auto plain = map_xy_to_plain(x_ph,y_ph); assert(plain<m_pixels.size()); m_pixels[plain]=color; } void DrawPoint(s_point_colored p) { DrawPoint(p.p, p.color); } void DrawLine(s_line line, RGBTRIPLE color) { /*if(line.IsHor()) [[unlikely]]//C++20 { //слева направо if(line.p1.x > line.p2.x) { std::swap(line.p1, line.p2); } for(PHISCOORDTYPE x0 = 0; x0 <= (line.p2.x-line.p1.x); ++x0) { DrawPoint({x0+line.p1.x,line.p1.y},color); } } else if(line.IsVer()) [[unlikely]] { //сверху вниз if(line.p1.y > line.p2.y) { std::swap(line.p1, line.p2); } for(PHISCOORDTYPE y0 = 0; y0 <= (line.p2.y-line.p1.y); ++y0) { DrawPoint({line.p1.x,y0+line.p1.y},color); } } else [[likely]]*/ { if( std::fabs(line.DeltaX()) >= std::fabs(line.DeltaY())) { if(line.p1.x > line.p2.x) { std::swap(line.p1, line.p2); } auto k = (line.p2.y-line.p1.y)/(line.p2.x-line.p1.x); //линия - слева направо for(PHISCOORDTYPE x0 = 0; x0 <= (line.p2.x-line.p1.x); ++x0) { auto y0 = x0 * k; DrawPoint({ x0+line.p1.x, y0+line.p1.y},color); } } else { if(line.p1.y > line.p2.y) { std::swap(line.p1, line.p2); } auto k = (line.p2.x-line.p1.x)/(line.p2.y-line.p1.y); //линия - сверху вниз for(PHISCOORDTYPE y0 = 0; y0 <= (line.p2.y-line.p1.y); ++y0) { auto x0 = y0 * k; DrawPoint({x0+line.p1.x , y0+line.p1.y},color); } } } } void DrawRect(s_rect rect, RGBTRIPLE color) { if( std::fabs(rect.Wid()) >= std::fabs(rect.Hig())) { if(rect.p1.x > rect.p2.x) { std::swap(rect.p1, rect.p2); } //рисуем вертикальные линии for(PHISCOORDTYPE x0 = 0; x0 <= (rect.p2.x-rect.p1.x); ++x0) { DrawLine({{x0+rect.p1.x,rect.p1.y},{x0+rect.p1.x,rect.p2.y}},color); } } else { if(rect.p1.y > rect.p2.y) { std::swap(rect.p1, rect.p2); } //рисуем горизонтальные линии for(PHISCOORDTYPE y0 = 0; y0 <= (rect.p2.y-rect.p1.y); ++y0) { DrawLine({{rect.p1.x,y0+rect.p1.y},{rect.p2.x,y0+rect.p1.y}},color); } } } void DrawEllipse(s_point center, COORDTYPE R , RGBTRIPLE color) { //center={30,10}; const auto R2= R*R; for(COORDTYPE x = 0; ; ++x) { COORDTYPE acc = 0.5f; auto y = std::sqrt(R2 - x*x); DrawPoint({ +x + center.x + acc, +y + center.y + acc},color); DrawPoint({ +y + center.x + acc, +x + center.y + acc},color); DrawPoint({ -x + center.x - acc, +y + center.y + acc},color); DrawPoint({ -y + center.x - acc, +x + center.y + acc},color); DrawPoint({ +x + center.x + acc, -y + center.y - acc},color); DrawPoint({ +y + center.x + acc, -x + center.y - acc},color); DrawPoint({ -x + center.x - acc, -y + center.y - acc},color); DrawPoint({ -y + center.x - acc, -x + center.y - acc},color); if(y < x)break; } } private: size_t map_xy_to_plain(size_t x, size_t y)const { return y*m_wid+x; } public: public: void SaveToFile(std::string file_name)const { std::ofstream file(file_name); BITMAPFILEHEADER FILE{}; FILE.bfType = 0x4d42; //'M','B' file.write((const char*) &FILE, sizeof FILE); BITMAPINFOHEADER INFO{}; file.write((const char*) &INFO, sizeof INFO); FILE.bfOffBits=file.tellp(); auto pix_line_no_padding = sizeof( decltype(m_pixels)::value_type ) * m_wid; constexpr size_t pad_step=4; //%4 pad //0 +0 //1 +3 //2 +2 //3 +1 auto pix_padding=0; if(pix_line_no_padding%pad_step)//pix_line_no_padding & 0b11 { pix_padding = pad_step - pix_line_no_padding%pad_step; } constexpr unsigned char zeros[pad_step]{}; //пикселы for(size_t y=m_hig; y-->0;) { const RGBTRIPLE* beg = m_pixels.data() + y*m_wid; const RGBTRIPLE* end = beg+m_wid; file.write((const char*) beg, pix_line_no_padding); //паддинг if(pix_padding) { file.write((const char*) &zeros[0], pix_padding); } } FILE.bfSize=file.tellp(); INFO.biSize = sizeof INFO; INFO.biWidth = {m_wid}; INFO.biHeight = {m_hig}; INFO.biPlanes = 1; INFO.biBitCount = {sizeof(decltype(m_pixels)::value_type) * CHAR_BIT}; //24; //INFO.biCompression == 0; file.seekp(0) ; file.write((const char*) &FILE, sizeof FILE); file.write((const char*) &INFO, sizeof INFO); } //тест точек static void test0(bool MakeFilesEmpty) { auto file_name = std::string{__func__}+".bmp"; if(MakeFilesEmpty) { std::ofstream{file_name}; return; } s_bmp bmp; bmp.SetSize(111,300); const auto center = bmp.Center(); const auto rect = bmp.Rect(); bmp.DrawPoint( {10,30}, {0,255,0} ); bmp.SaveToFile(file_name); } //тест линий static void test1(bool MakeFilesEmpty) { auto file_name = std::string{__func__}+".bmp"; if(MakeFilesEmpty) { std::ofstream{file_name}; return; } s_bmp bmp; bmp.SetSize(111,300); const auto center = bmp.Center(); const auto rect = bmp.Rect(); bmp.DrawLine( {{10,30},{10,30}}, {0,255,0} ); bmp.DrawLine( {{center.x,center.y-2000},{center.x,center.y+2000}} , {255,100,100} ); bmp.DrawLine( {{center.x-2000,center.y},{center.x+2000,center.y}} , {255,100,100} ); bmp.DrawLine( {center,{center.x+50,center.y-1000}} , {0,255,0} );//вправо вверх 60* bmp.DrawLine( {center,{center.x+500,center.y-500}} , {0,255,0} );//вправо вверх 45* bmp.DrawLine( {center,{center.x+500,center.y-200}} , {0,255,0} );//вправо вверх 30* bmp.DrawLine( {center,{center.x+50,center.y+1000}} , {0,255,0} );//вправо вниз 60* bmp.DrawLine( {center,{center.x+500,center.y+500}} , {0,255,0} );//вправо вниз 45* bmp.DrawLine( {center,{center.x+500,center.y+200}} , {0,255,0} );//вправо вниз 30* bmp.DrawLine( {center,{center.x-50,center.y-1000}} , {0,255,0} );//влево вверх 60* bmp.DrawLine( {center,{center.x-500,center.y-500}} , {0,255,0} );//влево вверх 45* bmp.DrawLine( {center,{center.x-500,center.y-200}} , {0,255,0} );//влево вверх 30* bmp.DrawLine( {center,{center.x-50,center.y+1000}} , {0,255,0} );//влево вниз 60* bmp.DrawLine( {center,{center.x-500,center.y+500}} , {0,255,0} );//влево вниз 45* bmp.DrawLine( {center,{center.x-500,center.y+200}} , {0,255,0} );//влево вниз 30* bmp.SaveToFile(file_name); } //тест прямоугольников static void test2(bool MakeFilesEmpty) { auto file_name = std::string{__func__}+".bmp"; if(MakeFilesEmpty) { std::ofstream{file_name}; return; } s_bmp bmp; bmp.SetSize(111,300); const auto center = bmp.Center(); const auto rect = bmp.Rect(); bmp.DrawRect( {{rect.p1.x-20,rect.p1.y-20},{rect.p2.x+20,rect.p2.y+20}} , {0,255,0} );//выход за все границы // bmp.DrawRect( {{rect.p1.x,rect.p1.y},{rect.p2.x,rect.p2.y}} , {0,255,0} );//по границе bmp.DrawRect( {{rect.p1.x+20,rect.p1.y+20},{rect.p2.x-20,rect.p2.y-20}} , {0,128,0} );//полностью внутри bmp.SaveToFile(file_name); } //тест окружностей static void test3(bool MakeFilesEmpty) { auto file_name = std::string{__func__}+".bmp"; if(MakeFilesEmpty) { std::ofstream{file_name}; return; } s_bmp bmp; bmp.SetSize(111,300); const auto center = bmp.Center(); const auto rect = bmp.Rect(); { s_point c{50,100}; bmp.DrawPoint( c , {255,255,255} ); for(int R=1; R<50; R+=3) { bmp.DrawEllipse( c, R , {0,255,0} ); } for(int R=2; R<50; R+=3) { bmp.DrawEllipse( c, R , {0,255,255} ); } } bmp.SaveToFile(file_name); } };

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue