C++ Builder/TCanvas > 원을 섹터로 분할하고 그라데이션을 그리는 구현

운영 환경
C++ Builder XE4
  • 원 그리기
  • 20 개의 sectors로 분할
  • RGB 값의 B를 변경하면서 sector를 바른다

  • Unit1.cpp
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::drawRadialLine(double angle_deg)
    {
        TRect R = Image1->ClientRect;
    
        double radius = (R.right - R.left) / 2;
        int center_x = (R.left + R.right) / 2;
        int center_y = (R.top + R.bottom) / 2;
    
        Image1->Canvas->MoveTo(center_x, center_y);
    
        int to_x = radius * Cos(angle_deg * M_PI / 180.0);
        int to_y = radius * Sin(angle_deg * M_PI / 180.0);
        to_x += center_x;
        to_y += center_y;
        Image1->Canvas->LineTo(to_x, to_y);
    }
    
    void __fastcall TForm1::fillSector(double angle_deg, double width_deg)
    {
        TRect R = Image1->ClientRect;
        double radius = (R.right - R.left) / 2;
    
        radius = 0.7 * radius; // to get inside the sector (0.7: arbitrary)
        double wrk_ang = angle_deg + width_deg / 2.0; // to get inside the sector
    
        int center_x = (R.left + R.right) / 2;
        int center_y = (R.top + R.bottom) / 2;
    
        int pt_x = radius * Cos(wrk_ang * M_PI / 180.0);
        int pt_y = radius * Sin(wrk_ang * M_PI / 180.0);
        pt_x += center_x;
        pt_y += center_y;
    
        Image1->Canvas->Brush->Color = RGB(0, 0, 255 * angle_deg / 360.0);
        Image1->Canvas->FloodFill(pt_x, pt_y, clBlack, fsBorder);
    
        // String msg = IntToStr(pt_x) + L"-" + IntToStr(pt_y) + L": " + FloatToStr(angle_deg);
        // OutputDebugString(msg.c_str());
    }
    
    void __fastcall TForm1::drawOnImage(void)
    {
        // 1. draw circle
        TRect R = Image1->ClientRect;
        //                      X1,     Y1     X2       Y2
        Image1->Canvas->Ellipse(R.left, R.top, R.right, R.bottom);
    
        // 2. draw line in radial direction
        static const int kNumAngles = 20;
    
        for(int idx=0; idx < kNumAngles; idx++) {
            double ang_deg = (360.0 / (double)kNumAngles) * idx;
            drawRadialLine(ang_deg);
        }
    
        // 3.. fill the sectors
        for(int idx=0; idx < kNumAngles; idx++) {
            double ang_deg = (360.0 / (double)kNumAngles) * idx;
            fillSector(ang_deg, /* width_deg=*/(360.0 / kNumAngles));
        }
    }
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        drawOnImage();
    }
    //---------------------------------------------------------------------------
    

    좋은 웹페이지 즐겨찾기