• 0
Dimoniks

Как вывести (отрисовать) текст по произвольной дуге

Вопрос

Доброго времени суток. 

Скажите пожалуйста, как в FM вывести текст по дуге с произвольным радиусом?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

8 ответов на этот вопрос

  • 0

TextToPath

 

Похоже ошибочка...

В одной книжке прочитал, что этот метод "выводит текст по траектории Path", но судя по описанию на офф сайте - это не так.

 

Значит придется руками делать...

Изменено пользователем FIL

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

TextToPath

 

Похоже ошибочка...

В одной книжке прочитал, что этот метод "выводит текст по траектории Path", но судя по описанию на офф сайте - это не так.

 

Значит придется руками делать...

Да... видимо так... Нет пути с меньшим сопротивлением...(((

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

для произвольной кривой - крайне сложная задача

вычислить точку на контуре для позиции каждой буквы - уже непросто
потом взятием производной по точке контура определить наклон в этой точке

определиться с понятием "внутрь/наружу" контура

 

а вот для дуги с заданными параметрами как раз в принципе несложно получается

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

для произвольной кривой - крайне сложная задача

вычислить точку на контуре для позиции каждой буквы - уже непросто

потом взятием производной по точке контура определить наклон в этой точке

определиться с понятием "внутрь/наружу" контура

 

а вот для дуги с заданными параметрами как раз в принципе несложно получается

А меня дуга и интересует... :) Если вам не сложно, можете примерчик кинуть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

насчет примера - нет времени полностью разобраться, но я бы пошел по такому пути:

 

1. сделать TextToPath для первой буквы. получим объект TPathData

2. рассчитать матрицу преобразования - поворот на угол alfa и перемещение из центра дуги на точку начала дуги.

Alfa - угол между вертикалью и прямой [центр дуги -- первая точка дуги]

применить матрицу - TPathData.ApplyMatrix

3. вычислить отступ между буквами и отступить на это расстояние по дуге.

4. берем вторую букву и делаем то же самое

 

после получения всех объектов TPathData, отрисовываем их

 

P.S. если что, формула окружности X^2+Y^2 = 0 ))

Изменено пользователем krapotkin

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

насчет примера - нет времени полностью разобраться, но я бы пошел по такому пути:

 

1. сделать TextToPath для первой буквы. получим объект TPathData

2. рассчитать матрицу преобразования - поворот на угол alfa и перемещение из центра дуги на точку начала дуги.

Alfa - угол между вертикалью и прямой [центр дуги -- первая точка дуги]

применить матрицу - TPathData.ApplyMatrix

3. вычислить отступ между буквами и отступить на это расстояние по дуге.

4. берем вторую букву и делаем то же самое

 

после получения всех объектов TPathData, отрисовываем их

 

P.S. если что, формула окружности X^2+Y^2 = 0 

 

насчет примера - нет времени полностью разобраться, но я бы пошел по такому пути:

 

1. сделать TextToPath для первой буквы. получим объект TPathData

2. рассчитать матрицу преобразования - поворот на угол alfa и перемещение из центра дуги на точку начала дуги.

Alfa - угол между вертикалью и прямой [центр дуги -- первая точка дуги]

применить матрицу - TPathData.ApplyMatrix

3. вычислить отступ между буквами и отступить на это расстояние по дуге.

4. берем вторую букву и делаем то же самое

 

после получения всех объектов TPathData, отрисовываем их

 

P.S. если что, формула окружности X^2+Y^2 = 0 ))

Спасибо за алгоритм, ну а уравнение я знаю... )))

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Набросал пример отрисовки текста по дуге:





procedure TForm1.FormPaint(Sender: TObject; Canvas: TCanvas;
  const ARect: TRectF);
const
  S: String = 'Пример отрисовки текста по заданной траектории (дуга)';
var
  i: Integer;
  A, Ao, R, TextLen: Single;
  Rect: TRectF;
  M1, M2: TMatrix; // uses System.Math.Vectors

begin
//  if Canvas.BeginScene then
  begin
    Randomize;
    R  := 400;
    Ao := DegToRad(150); // uses System.Math
    A  := (Pi - Ao) / 2;

    Canvas.Font.Size := 32;
    Canvas.Stroke.Kind := TBrushKind.Solid;
    Canvas.StrokeThickness := 3;
    Canvas.Fill.Color := TAlphaColors.Palegreen xor $80000000;
    Canvas.FillEllipse(TRectF.Create(0, 0, 2 * R, 2 * R), 1);

    TextLen := Canvas.TextWidth(S);

    if TextLen > R * Ao  then
      Caption := 'АХТУНГ!'; // длина текста больше выделенной под него дуги (будет наложение букв)

    for i := 1 to S.Length do
    begin
      Rect.Left   := 0;
      Rect.Top    := R;
      Rect.Width  := Canvas.TextWidth(S[i]);
      Rect.Height := Canvas.TextHeight(S[i]);

      A := A + Ao / (S.Length - 1);

      M1 := TMatrix.CreateTranslation(- Rect.CenterPoint.X, - Rect.CenterPoint.Y) *
            TMatrix.CreateRotation(A - A - Pi / 2) *
            TMatrix.CreateTranslation(Rect.CenterPoint.X, Rect.CenterPoint.Y);

      M2 := TMatrix.CreateTranslation(-R, -R) *
            TMatrix.CreateRotation(A) *
            TMatrix.CreateTranslation(R, R);

      Canvas.SetMatrix(M1 * M2);

      Canvas.Fill.Color := TAlphaColor(Random(MaxInt) or $FF000000);
      Canvas.FillText(Rect, S[i], False, 1, [{TFillTextFlag.RightToLeft}], TTextAlign.Leading, TTextAlign.Center);
    end;

//    Canvas.EndScene;
  end;
end;

post-1506-0-54940200-1440177693_thumb.jp

Изменено пользователем FIL
rareMax, i.r.khayrullin и Вячеслав понравилось это

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Гость
Эта тема закрыта для публикации сообщений.

  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу