Прозрачная толстая линия с контуром

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Прозрачная толстая линия с контуром

Сообщение DropSoft » 25.04.2018 11:27:39

Нужно нарисовать отрезки заданной толщины со скругленными концами.
С помощью LINE получается как на рисунке слева.
Код: Выделить всё
  with Image1.Canvas do
  begin
    Pen.Width := 30;
    Pen.Color := clGreen;
    Line(X1, Y1, X2, Y2);
  end;

А надо сделать, как на рисунке справа, чтобы были только окружности в крайних точках отрезка и верхняя/нижняя границы отрезка, а середина прозрачная, чтобы было видно нарисованное ранее. Есть ли простой способ так сделать, поменяв какие-нибудь свойства?

1.png
1.png (5.15 КБ) Просмотров: 9326
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Прозрачная толстая линия с контуром

Сообщение zub » 25.04.2018 14:11:56

Никак. Сам считаешь координаты линий и окружностей, рисуешь их
zub
долгожитель
 
Сообщения: 2886
Зарегистрирован: 14.11.2005 23:51:26

Re: Прозрачная толстая линия с контуром

Сообщение runewalsh » 25.04.2018 15:08:25

Перпендикуляры к v = (X, Y) — v1 = (-Y, X) и v2 = -v1 = (Y, -X).
Код: Выделить всё
procedure Capsule(c: TCanvas; x1, y1, x2, y2, r: integer);
var
   k: single;
   ndx, ndy: integer;
begin
   c.Ellipse(x1-r, y1-r, x1+r+1, y1+r+1);
   c.Ellipse(x2-r, y2-r, x2+r+1, y2+r+1);

   k := sqrt(sqr(x2 - x1) + sqr(y2 - y1));
   if k > 0 then k := r/k;
   ndx := round(k * (y2 - y1));
   ndy := round(k * -(x2 - x1));
   c.Line(x1 + ndx, y1 + ndy, x2 + ndx, y2 + ndy);
   c.Line(x1 - ndx, y1 - ndy, x2 - ndx, y2 - ndy);
end;

Модификацией с Arc убираются внутренние части окружностей (хотя вряд ли тебе это нужно хд):
Код: Выделить всё
uses Math;

procedure Capsule(c: TCanvas; x1, y1, x2, y2, r: integer);
var
   k: single;
   ndx, ndy, fixx, fixy: integer;
begin
   k := sqrt(sqr(x2 - x1) + sqr(y2 - y1));
   if k > 0 then k := r/k;
   ndx := round(k * (y2 - y1));
   ndy := round(k * -(x2 - x1));
   fixx := sign(x2 - x1);
   fixy := sign(y2 - y1);
   c.Arc(x1-r, y1-r, x1+r+1, y1+r+1, x1 + ndx + fixx, y1 + ndy + fixy, x1 - ndx + fixx, y1 - ndy + fixy);
   c.Arc(x2-r, y2-r, x2+r+1, y2+r+1, x2 - ndx - fixx, y2 - ndy - fixy, x2 + ndx - fixx, y2 + ndy - fixy);
   c.Line(x1 + ndx, y1 + ndy, x2 + ndx, y2 + ndy);
   c.Line(x1 - ndx, y1 - ndy, x2 - ndx, y2 - ndy);
end;

capsule.png
capsule.png (5.68 КБ) Просмотров: 9285

А вот убрать вообще все внутренности будет сложнее...
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Прозрачная толстая линия с контуром

Сообщение DropSoft » 25.04.2018 17:20:38

runewalsh, спасибо! Все работает. Полудуги не нужны. Я пробовал извращаться через arctan, sin, cos. Но так эффективнее.
Еще добавил до и после окружностей
Код: Выделить всё
  c.Brush.Style := bsClear;
  c.Ellipse(x1-r, y1-r, x1+r+1, y1+r+1);
  c.Ellipse(x2-r, y2-r, x2+r+1, y2+r+1);
  c.Brush.Style := bsSolid;

чтобы внутри окружности не затиралось.

Добавлено спустя 17 минут 17 секунд:
А еще вопрос, перед
Код: Выделить всё
c.Brush.Style := bsClear;
хочу запомнить текущее состояние c.Brush.Style
У него тип TFPBrushStyle. Но задать переменной этот тип - выдает ошибку, что тип неизвестен.
Как правильно сохранить, а потом восстановить текущий c.Brush.Style?
DropSoft
новенький
 
Сообщения: 31
Зарегистрирован: 31.03.2013 13:47:40

Re: Прозрачная толстая линия с контуром

Сообщение runewalsh » 25.04.2018 17:53:14

Подключи модуль, в котором определён этот тип (FPCanvas).
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 579
Зарегистрирован: 27.04.2010 00:15:25

Re: Прозрачная толстая линия с контуром

Сообщение xterro » 27.04.2018 11:11:58

Наверно правильнее рисовать линию как полигон, т.е это полигон в форме линии, после, его триангулировать и закрашивать. Как-только сделать полигон в форме линии(вытянутого прямоугольника), я пока не придумал ))
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

Рейтинг@Mail.ru