пользовательский вид - скругление углов прямоугольника, нарисованных линиями - PullRequest
0 голосов
/ 22 мая 2019

Я играю с пользовательскими видами и хочу построить прямоугольник со скругленными углами, используя методы path.lineTo() и path.arcTo().
Итак, прямоугольник, который я хочу получить:

enter image description here

Обычно я рисую это с помощью этого блока кода:

    RectF backReftf = new RectF();
    Path path = new Path();
    int width = getWidth();
    int height = getHeight();
    float curve = (float) (0.1 *  height);
    RectF backReftf = new RectF();
    backReftf.left = 0;
    backReftf.top = 0;
    backReftf.right = width;
    backReftf.bottom = height;
    path.addRoundRect(backReftf, curve, curve, Path.Direction.CW);
    canvas.drawPath(path, paint);

Но я хочу нарисовать это с path.lineTo() и path.arcTo().

Согласно Документам о arcTo():

Добавьте указанную дугу к контуру в качестве нового контура.Если начало пути отличается от текущей последней точки пути, то добавляется автоматическая функция lineTo () для соединения текущего контура с началом дуги.Однако, если путь пуст, то мы вызываем moveTo () с первой точкой дуги.

Так что теоретически моя дуга должна начинаться там, где заканчивается линия, поэтому, если я нарисовал линию (левая сторона прямоугольника):

    float curve = (float) (0.1 *  height);
    path.moveTo(0,0);
    path.lineTo(0, height - curve);

тогда моя дуга должна начинаться с этой точки (0, высота - кривая), но где мне передать эти аргументы, когда arcTo() имеет следующие параметры: arcTo (float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)?

Плюс как рассчитать в этом случае startAngle и sweepAngle?

Заранее спасибо!

1 Ответ

2 голосов
/ 22 мая 2019

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

arcTo angles

Например, при движении по часовой стрелке начальный угол расположен на 180 градусов от начала координат.А из startAngle, если вы развернитесь на 90 градусов по часовой стрелке, вы окажетесь в желаемой конечной позиции.

Обратите внимание, где на этом рисунке находятся origin, startAngle и sweepAngle.В kotlin это может выглядеть примерно так:

// Given some radius, viewWidth and viewHeight
override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        path.apply {
            moveTo(radius, 0F)
            lineTo(viewWidth - radius, 0F)
            arcTo(viewWidth - 2 * radius, 0F, viewWidth, 2 * radius, -90F, 90F, false)
            lineTo(viewWidth, radius)
            arcTo(viewWidth - 2 * radius, viewHeight - 2 * radius, viewWidth, viewHeight, 0F, 90F, false)
            lineTo(radius, viewHeight)
            arcTo(0F, viewHeight - 2 * radius, 2 * radius, viewHeight, 90F, 90F, false)
            lineTo(0F, radius)
            arcTo(0F, 0F, 2 * radius, 2 * radius, 180F, 90F, false)
        }

        canvas?.drawPath(path, linePaint)
    }

И результат будет примерно таким:

enter image description here

...