БлогNot. С++/CLI: рисуем сердечко на PictureBox

С++/CLI: рисуем сердечко на PictureBox

По этой ссылке уже есть подобное в Mathcad, но оно с параметрическим определением функции.

Рисунок с сердечком на белом фоне создаёт класс Heart, конструктор которого имеет аргументы fromx, fromy - левая верхняя точка в пикселях, w, h - ширина и высота в пикселях, col, lw - цвет и толщина линии, а единственный метод Draw возвращает ссылку на Bitmap с полученным рисунком.

Ниже приводится полный код класса Heart (файл Heart.h):

#pragma once
public ref class Heart {
public:
 Heart (int fromx, int fromy, int w, int h, System::Drawing::Color col, int lw) {
  //(fromx, fromy) - левая верхняя точка 
  //(w, h) - ширина и высота
  //col, lw - цвет и толщина линии
  x = fromx;
  y = fromy;
  width = fromx + w - 1;
  height = fromy + h - 1;
  color = col;
  linewidth = lw;
 }
public:
 System::Drawing::Bitmap^ Draw() {
  System::Drawing::Bitmap^ Img = gcnew System::Drawing::Bitmap(width, height);
  System::Drawing::Graphics^ g = System::Drawing::Graphics::FromImage(Img);
  g->Clear(System::Drawing::Color::White);
  System::Drawing::Drawing2D::GraphicsPath^ path;
  path = gcnew System::Drawing::Drawing2D::GraphicsPath();
  path->StartFigure();
  double topCurveHeight = height * 0.25; //выпуклость, или впуклость, в долях высоты рисунка
  x += width / 2; //начинаем с серединки
  path->AddBezier(x, y + topCurveHeight, x, y, 
   x - width / 2, y, x - width / 2, y + topCurveHeight); //левая верхняя
  path->AddBezier(x - width / 2, y + topCurveHeight, x - width / 2, y + (height + topCurveHeight) / 2,
   x, y + (height + topCurveHeight) / 2, x, y + height); //левая нижняя
  path->AddBezier(x, y + height, x, y + (height + topCurveHeight) / 2,
   x + width / 2, y + (height + topCurveHeight) / 2, x + width / 2, y + topCurveHeight); //правая нижняя
  path->AddBezier(x + width / 2, y + topCurveHeight, x + width / 2, y,
   x, y, x, y + topCurveHeight); //правая верхняя
  path->CloseFigure();
  g->DrawPath(gcnew System::Drawing::Pen(color, linewidth), path);
  return Img;
 }
private:
 int x, y, width, height, linewidth;
 System::Drawing::Color color;
};

Для создания контура используются кривые Безье. Отрисовать на PictureBox можно, например, таким кодом:

private: System::Void pictureBox1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
 Heart ^myHeart = gcnew Heart(0,0, pictureBox1->Width, pictureBox1->Height,Color::Red, 10);
 //во весь pictureBox1, красным, толщиной 10 пикселей
 pictureBox1->Image = myHeart->Draw();
}
скриншот приложения
скриншот приложения

Тем, чтобы линия толще одного пикселя частично не "наезжала" на края формы, не озадачивался, этим можно управлять через аргументы конструктора. Размеры окна можно менять, каждый раз сердечко перерисуется.

 Проект на C++/CLI с проектом из этой статьи в архиве .zip, папка уже создана внутри архива (7 Кб)

Как правильно настроить PictureBox в форме, чтобы рисовать на нём - есть вот здесь или в коде приложенного примера.

20.12.2020, 14:11 [414 просмотров]


теги: графика программирование c++/cli