LoginSignup
0
0

More than 5 years have passed since last update.

C++ Builder / TCanvas > 円をセクターに分割して、グラデーションを塗る実装

Last updated at Posted at 2017-03-28
動作環境
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();
}
//---------------------------------------------------------------------------

qiita.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0