Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 19.10.2013, 17:50
woojin woojin вне форума
Прохожий
 
Регистрация: 09.08.2008
Сообщения: 3
Репутация: 10
Вопрос как нарисовать стрелку в конце дуги?

всем здравствуйте!

возникла у меня такая проблема:
есть дуга (может быть повёрнут относительно своего цента как угодно),
требуется нарисовать в конце дуги стрелку (наконечник, указатель), так чтобы стороны стрелки на касались дуги

1 изображение - как не надо
2 изображение - как надо

и по этому поводу вопрос, как правильно рассчитать такого рода художеста
для простоты пусть дуга будет горизонтальной, высота 100, ширина 200
Изображения
Тип файла: jpg Без имени-4.jpg (10.1 Кбайт, 20 просмотров)
Тип файла: jpg Без имени-5.jpg (9.9 Кбайт, 18 просмотров)
Ответить с цитированием
  #2  
Старый 19.10.2013, 19:28
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Школьный курс геометрии. Все ж просто, просто радиус уменьшить надо, и нарисовать из точки, где стрелка должна быть.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
  #3  
Старый 19.10.2013, 19:40
woojin woojin вне форума
Прохожий
 
Регистрация: 09.08.2008
Сообщения: 3
Репутация: 10
Печаль

если подумать то у эллипса радиус то разный!!!
какой из них использовать
и вообще как это программно применить?

P.S. извините за тупость, но сообразить не получается
Ответить с цитированием
  #4  
Старый 21.10.2013, 01:00
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Поиграйтесь с этим, правда стрелка прямая, рисуется в паинтбоксе, но зато под любым углом (за концы её можно крутить мышкой)
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
woojin (31.10.2013)
  #5  
Старый 21.10.2013, 13:04
Аватар для Pilot_Red
Pilot_Red Pilot_Red вне форума
Продвинутый
 
Регистрация: 01.11.2006
Адрес: Карелия
Сообщения: 702
Версия Delphi: D7
Репутация: 11581
По умолчанию

получаешь угол, и поворачиваешь свою стрелку на этот угол, соответственно перенеся ее координаты в конец дуги(или ее начала)
Ответить с цитированием
Этот пользователь сказал Спасибо Pilot_Red за это полезное сообщение:
woojin (31.10.2013)
  #6  
Старый 31.10.2013, 23:03
woojin woojin вне форума
Прохожий
 
Регистрация: 09.08.2008
Сообщения: 3
Репутация: 10
Хорошо

подсказали на другом форуме и вот что получилось:

Код:
var
  bm: TBitmap;

procedure TForm1.FormCreate(Sender: TObject);
begin
   bm := TBitmap.Create;
   bm.Width := PaintBox1.Width;
   bm.Height := PaintBox1.height;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Count: integer;

begin
    Count: = 50; //количество точек
    bm.Canvas.FillRect(Bounds(0, 0, PaintBox1.Width, PaintBox1.Height));
    DrawBezier(bm.Canvas, Count, PenW, Color)
    PaintBox1.Canvas.Draw(0, 0, bm);
end;

procedure DrawEdje(P1, P2: TPoint; Arrow: boolean; Canvas: TCanvas; Color: TColor);
var
  Angle: real;
  p3, p4: TPoint;
  size, angle_shift: Integer;

begin
   size := 20;
   angle_shift := 160; // на сколько острой стрелка
   Canvas.Color := Color;
  if Arrow = true then
     begin
        Angle := 180 * ArcTan2(P2.y - P1.y, P2.x - P1.x) / pi;
        p3 := Point(P2.x + Round(size * cos(pi * (Angle + angle_shift) / 180)), P2.y + Round(size * sin(pi * (Angle + angle_shift) / 180)));
        p4 := Point(P2.x + Round(size * cos(pi * (Angle - angle_shift) / 180)), P2.y + Round(size * sin(pi * (Angle - angle_shift) / 180)));
        Canvas.MoveTo(p2.X,p2.Y);
        Canvas.LineTo(p3.X,p3.y);
        Canvas.MoveTo(p2.X,p2.Y);
        Canvas.LineTo(p4.X,p4.y);

        Canvas.MoveTo(p1.X,p1.Y);
        Canvas.LineTo(p3.X,p3.y);
        Canvas.MoveTo(p1.X,p1.Y);
        Canvas.LineTo(p4.X,p4.y);
  end;
end;

function GetBinomialCoefficient(m, i: Integer): single;
  function Factorial(x: Integer): double;
  var
    i: Integer;
  begin
     result := 1;
     for i := 2 to x do
       result := result * i;
  end;

begin
   result := Factorial(m) / (Factorial(i) * Factorial(m - i));
end;

procedure DrawBezier(Canvas: TCanvas; Count: Integer; PenW: Integer = 2; Color: TColor = clRed);
type
  TPointFArray = array [word] of TPoint;
  PPointFArray = ^TPointFArray;

var
  p: PPointFArray;
  Step, qx, qy, t, q: single;
  i, j, n: Integer;
  BezierPoints: array of TPoint;
  PointShift: single;
  C: array of single;

begin
   n := 3;
   SetLength(BezierPoints, n);
   SetLength(C, n);

//координаты трапеции для полуэллипса
   PointShift := Canvas.Width / 3;
   BezierPoints[0] := TPoint.Create(Canvas.Width, Canvas.Height);
   BezierPoints[1] := TPoint.Create(Canvas.Width - PointShift, 0);
   BezierPoints[2] := TPoint.Create(Canvas.Width - PointShift * 2, 0);
   BezierPoints[3] := TPoint.Create(0, Canvas.Height);

   for i := 0 to n do
     C[i] := GetBinomialCoefficient(n, i);

   GetMem(p, sizeof(TPoint) * (Count + 1));
   Step := 1.0 / Count;
   for i := 0 to Count do
     begin
        t := i * Step;
        qx := 0;
        qy := 0;
        for j := 0 to n do
          begin
             q := C[j] * IntPower(1 - t, j) * IntPower(t, n - j);
             qx := qx + q * BezierPoints[j].x;
             qy := qy + q * BezierPoints[j].y;
          end;
        p[i] := PointF(qx, qy);
     end;

   Canvas.Pen.Color := Color;
   Canvas.pen.Width := PenW;
   i := 0;
   while (i <= Count - 1) do
      begin
         Canvas.MoveTo(p[i], p[i + 1], 100);
         Canvas.LineTo(p[i+1].x, p[i+1].y);
         inc(i, 2);
      end;

   DrawEdje(p[Count - 1], p[Count], true, Canvas, Color);

   FreeMem(p);
end;
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 18:48.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter