Как нарисовать дугу между двумя точками на холсте?

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

Этот код canvas.drawLine(p1.x, p1.y, p2.x, p2.y, paint); Введите описание изображения здесь

Я хочу нарисовать дугу между двумя точками, как показано ниже.

Введите описание изображения здесь

Как я могу рисовать так.

Solutions Collecting From Web of "Как нарисовать дугу между двумя точками на холсте?"

Наконец, я получил решение из этого кода:

 float radius = 20; final RectF oval = new RectF(); oval.set(point1.x - radius, point1.y - radius, point1.x + radius, point1.y+ radius); Path myPath = new Path(); myPath.arcTo(oval, startAngle, -(float) sweepAngle, true); 

Чтобы вычислить startAngle , используйте этот код:

 int startAngle = (int) (180 / Math.PI * Math.atan2(point.y - point1.y, point.x - point1.x)); 

Здесь point1 означает, что вы хотите начать рисовать Arc. sweepAngle означает угол между двумя линиями. Мы должны вычислить это, используя две точки, такие как синие точки в моем изображении вопроса.

Сделайте что-то вроде этого:

 @Override protected void onDraw(Canvas canvas) { Paint p = new Paint(); RectF rectF = new RectF(50, 20, 100, 80); p.setColor(Color.BLACK); canvas.drawArc (rectF, 90, 45, true, p); } 

Я пытался сделать что-то совсем другое, и все дело в том, чтобы вычислить развертку и начать ракурсы.

Я хотел показать дугу, которая представляет прогресс по кругу, который идет сверху вниз.

Таким образом, у меня было значение прогресса от 0 … 100, и я хочу показать дугу, начинающуюся сверху вниз, чтобы заполнить круг, когда прогресс составляет 100.

Чтобы вычислить sweepAngle, я использую:

  int sweepAngle = (int) (360 * (getProgress() / 100.f)); 

Далее следует вычислить startAngle

  int startAngle = 270 - sweepAngle / 2; 

Начальный угол рассчитывается таким образом, потому что:

  1. Он всегда будет начинаться с левой стороны, начиная сверху донизу. Таким образом, начальный угол вверх равен 270 (обратите внимание, что он идет по часовой стрелке и 0 = 3 часа, поэтому 12 часов равно 270 градусам)
  2. Затем я хочу рассчитать, как далеко я уйду от своей начальной точки (270), и для этого я рассчитываю только половину угла развертки, потому что только половина дуги будет с левой стороны, а другая половина – правая сторона.

Поэтому, учитывая, что у меня есть прогресс в 25%

 sweepAngle = 90 degrees (90 degrees is quarter of a circle) start angle = 225 (45 degrees away from 270) 

Если вы хотите, чтобы прогресс проходил с других сторон (слева направо, справа налево и т. Д.), Вам нужно будет только заменить 270 начальным углом.

Образец для рисования дуги.

 public static Bitmap clipRoundedCorner(Bitmap bitmap, float r, boolean tr, boolean tl, boolean bl, boolean br) { int W = bitmap.getWidth(); int H = bitmap.getHeight(); if (r < 0) r = 0; int smallLeg = W; if(H < W ) smallLeg = H; if (r > smallLeg) r = smallLeg / 2; float lineStop = r/2; Path path = new Path(); path.moveTo(0,0); if(tr) { path.moveTo(0, lineStop); path.arcTo(new RectF(0,0, r,r), 180, 90, false); } path.lineTo(W-lineStop, 0); if(tl) path.arcTo(new RectF(Wr,0, W,r), 270, 90, false); else path.lineTo(W, 0); path.lineTo(W, H-lineStop); if(bl) path.arcTo(new RectF(Wr,Hr, W,H), 0, 90, false); else path.lineTo(W, H); path.lineTo(lineStop, H); if(br) path.arcTo(new RectF(0,Hr, r,H), 90, 90, false); else path.lineTo(0,H); if(tr) path.lineTo(0,lineStop); else path.lineTo(0,0); Bitmap output = Bitmap.createBitmap(W, H, Config.ARGB_8888); Canvas canvas = new Canvas(output); final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.BLACK); canvas.drawPath(path, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); canvas.drawBitmap(bitmap, 0, 0, paint); return output; }