Нарисуйте текст на сегменте линии в C#

В этом примере показано, как вы можете нарисовать текст в сегменте линии. Ключ - это метод DrawTextOnSegment, показанный в следующем коде. Этот метод может нарисовать текст на сегменте линии или ниже сегмента линии.

// Нарисуем текст вдоль сегмента линии.
// Оставьте char_num, указывая на следующий символ, который нужно нарисовать.
// Оставьте start_point, удерживая последнюю используемую точку.
private void DrawTextOnSegment(Graphics gr, Brush brush,
    Font font, string txt, ref int first_ch,
    ref PointF start_point, PointF end_point,
    bool text_above_segment)
{
    float dx = end_point.X - start_point.X;
    float dy = end_point.Y - start_point.Y;
    float dist = (float)Math.Sqrt(dx * dx + dy * dy);
    dx /= dist;
    dy /= dist;

    // Посмотрите, сколько символов будет соответствовать.
    int last_ch = first_ch;
    while (last_ch < txt.Length)
    {
        string test_string =
            txt.Substring(first_ch, last_ch - first_ch + 1);
        if (gr.MeasureString(test_string, font).Width > dist)
        {
            // Это слишком много символов.
            last_ch--;
            break;
        }
        last_ch++;
    }
    if (last_ch < first_ch) return;
    if (last_ch >= txt.Length) last_ch = txt.Length - 1;
    string chars_that_fit =
        txt.Substring(first_ch, last_ch - first_ch + 1);

    // Поворачиваем и переводим, чтобы расположить символы.
    GraphicsState state = gr.Save();
    if (text_above_segment)
    {
        gr.TranslateTransform(0,
            -gr.MeasureString(chars_that_fit, font).Height,
            MatrixOrder.Append);
    }
    float angle = (float)(180 * Math.Atan2(dy, dx) / Math.PI);
    gr.RotateTransform(angle, MatrixOrder.Append);
    gr.TranslateTransform(start_point.X, start_point.Y,
        MatrixOrder.Append);

    // Рисуем подходящие символы.
    gr.DrawString(chars_that_fit, font, brush, 0, 0);

    // Восстановить сохраненное состояние.
    gr.Restore(state);

    // Обновление first_ch и start_point.
    first_ch = last_ch + 1;
    float text_width =
        gr.MeasureString(chars_that_fit, font).Width;
    start_point = new PointF(
        start_point.X + dx * text_width,
        start_point.Y + dy * text_width);
}

Код начинается с получения вектора длины единицы & lt; dx, dy & gt;, указывающего в направлении отрезка линии. Затем он вводит цикл, делающий дольше и длиннее строки, пока не найдет тот, который не будет помещаться в сегмент линии. Затем он удаляет последний добавленный символ, чтобы получить самую длинную подстроку, которая будет соответствовать.

Если самая длинная подстрока пуста, метод возвращается без рисования. Если каждый символ подходит, код устанавливает последний символ последним в строке.

Далее код сохраняет состояние объекта Graphics, чтобы код мог отменить последующие преобразования.

Если метод должен нарисовать текст над сегментом линии, код добавляет перевод в объект Graphics, чтобы переместить текст вверх по высоте текста.

Затем код вычисляет угол сегмента линии и добавляет поворотное преобразование для поворота текста, лежащего вдоль сегмента. Затем он добавляет окончательный перевод, чтобы переместить текст в исходную позицию сегмента.

Наконец, код рисует текст в начале. Преобразования вращаются и позиционируют текст соответствующим образом.

Источник: http://csharphelper.com/blog/2016/01/draw-text-on-a-line-segment-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (1 оценок, среднее: 5,00 из 5)
Adblock
detector