Страница 1 из 1
Прозрачная толстая линия с контуром
Добавлено: 25.04.2018 10:27:39
DropSoft
Нужно нарисовать отрезки заданной толщины со скругленными концами.
С помощью LINE получается как на рисунке слева.
Код: Выделить всё
with Image1.Canvas do
begin
Pen.Width := 30;
Pen.Color := clGreen;
Line(X1, Y1, X2, Y2);
end;
А надо сделать, как на рисунке справа, чтобы были только окружности в крайних точках отрезка и верхняя/нижняя границы отрезка, а середина прозрачная, чтобы было видно нарисованное ранее. Есть ли простой способ так сделать, поменяв какие-нибудь свойства?

- 1.png (5.15 КБ) 13097 просмотров
Re: Прозрачная толстая линия с контуром
Добавлено: 25.04.2018 13:11:56
zub
Никак. Сам считаешь координаты линий и окружностей, рисуешь их
Re: Прозрачная толстая линия с контуром
Добавлено: 25.04.2018 14:08:25
runewalsh
Перпендикуляры к 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 (5.68 КБ) 13056 просмотров
А вот убрать вообще все внутренности будет сложнее...
Re: Прозрачная толстая линия с контуром
Добавлено: 25.04.2018 16:37:55
DropSoft
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
У него тип TFPBrushStyle. Но задать переменной этот тип - выдает ошибку, что тип неизвестен.
Как правильно сохранить, а потом восстановить текущий c.Brush.Style?
Re: Прозрачная толстая линия с контуром
Добавлено: 25.04.2018 16:53:14
runewalsh
Подключи модуль, в котором определён этот тип (FPCanvas).
Re: Прозрачная толстая линия с контуром
Добавлено: 27.04.2018 10:11:58
xterro
Наверно правильнее рисовать линию как полигон, т.е это полигон в форме линии, после, его триангулировать и закрашивать. Как-только сделать полигон в форме линии(вытянутого прямоугольника), я пока не придумал ))