Próbowałem z następującym kodem, ale ten kod nie działa zgodnie z oczekiwaniami. Właściwie wahałem się, czy poprosić o pomoc w sprawie tego prostego rozwiązania, ale straciłem dużo czasu, w końcu tu przyjechałem.

deltaX = bounds.right - bounds.left;
deltaY = bounds.bottom - bounds.top;

double distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
float arrowLength= (float) (distance / 3);
float lineAngle = (float) Math.atan2(deltaY, deltaX);
float angle = (float) Math.toRadians(20);
float sinValue = (float) Math.sin(lineAngle - angle);
point_x_1 = bounds.left - 20 * sinValue;
point_y_1 = (float) (bounds.bottom - 0.5 * arrowLength* Math.cos(lineAngle - angle));
angle = (float) Math.toRadians(60);
sinValue = (float) Math.sin(lineAngle + angle);
point_x_3 = bounds.left + 20 * sinValue;
point_y_3 = (float) (bounds.bottom + arrowLength* Math.cos(lineAngle + angle));

path.moveTo(bounds.right, bounds.top);
path.lineTo(bounds.left, bounds.bottom);
path.moveTo(point_x_1, point_y_1);
path.lineTo(bounds.left, bounds.bottom);
path.lineTo(point_x_3, point_y_3);

Uwaga: mam cztery kierunki, każdy będzie dostępny w różnych scenariuszach.

enum PathDirection {
    TopLeftToBottomRight,
    TopRightToBottomLeft,
    BottomLeftToTopRight,
    BottomRightToTopLeft
} 

Powyższy kod próbowałem dla TopRightToBottomLeft.

Przykładowe wyniki

Rys 1: Wartości RectF: [180.0,560.0] [820.0,740.0]

enter image description here

Rys. 2: Wartości RectF: [240.0,480.0] [640.0,980.0]

enter image description here

Aktualizuj

path.reset();
canvas.save();
canvas.translate(200, 200);
float direction = (float) Math.atan2(400 - 200, 400 - 200);
canvas.rotate(direction);
path.moveTo(0, 0);
float distance = (float) Math.sqrt(200 * 200 + 200 * 200);
path.lineTo(distance, 0);
float x1 = distance - (distance * 20 / 100);
float y1 = -(distance * 15 / 100);
path.moveTo(x1, y1);
path.lineTo(distance, 0);
x1 = distance - (distance * 20 / 100);
y1 = (distance * 15 / 100);
path.lineTo(x1, y1);
canvas.drawPath(path, mPaint);
canvas.restore();

Użyłem tego kodu, aby narysować linię od pozycji 200, 200 do 300, 300. Ale to narysuje linię od 0, 0 do distance.

Zrzut ekranu

enter image description here

1
Gunaseelan 13 marzec 2020, 16:11

2 odpowiedzi

Najlepsza odpowiedź

Z pomocą pskink doszedłem do rozwiązania, przykładowego kodu, które rysuje linię ze strzałką z 200, 200 do 400, 400

path.reset();
RectF rectF = new RectF(200, 200, 400, 400);
canvas.save();
canvas.translate(rectF.left, rectF.top);
float direction = (float) Math.atan2(rectF.bottom - rectF.top, rectF.right - rectF.left);
float degree = (float) Math.toDegrees(direction);
canvas.rotate(degree);
canvas.drawColor(Color.parseColor("#E3F2FD"));
path.moveTo(0, 0);
float x = rectF.right - rectF.left;
float y = rectF.bottom - rectF.top;
float distance = (float) Math.sqrt(x * x + y * y);
path.lineTo(distance, 0);
float x1 = distance - (distance * 20 / 100);
float y1 = -(distance * 15 / 100);
path.moveTo(x1, y1);
path.lineTo(distance, 0);
float x2 = distance - (distance * 20 / 100);
float y2 = (distance * 15 / 100);
path.lineTo(x2, y2);
canvas.drawPath(path, mPaint);
canvas.restore();

SC:

enter image description here

Uwaga Jeśli nie chcesz obracać płótna, możesz użyć Helder Sepulveda, działa również zgodnie z oczekiwaniami.

1
Gunaseelan 18 marzec 2020, 08:26

Zobacz poniższy kod javascript, który powinien ładnie przekładać się na Javę

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");

function drawLine(p1, p2, asize) {
  ctx.beginPath()
  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x, p2.y);
  
  if (asize > 0) {
    lineAngle = Math.atan2(p1.y - p2.y, p1.x - p2.x);
    delta = Math.PI/6  
    for (i=0; i<2; i++) {
      ctx.moveTo(p2.x, p2.y);
      x = p2.x + asize * Math.cos(lineAngle + delta)
      y = p2.y + asize * Math.sin(lineAngle + delta)
      ctx.lineTo(x, y);
      delta *= -1
    }
  }
  ctx.stroke();
}

drawLine({x:10, y:10}, {x:100, y:20}, 20)
drawLine({x:20, y:15}, {x:140, y:120}, 20)
drawLine({x:140, y:20}, {x:80, y:50} , 20)

drawLine({x:150, y:20}, {x:150, y:90}, 20)
drawLine({x:180, y:90}, {x:180, y:20}, 20)

drawLine({x:200, y:10}, {x:200, y:140}, 10)
drawLine({x:220, y:140}, {x:220, y:10}, 10)
<canvas id="canvas">

Jeśli go uruchomisz, powinieneś zobaczyć kilka próbek.
Rozbijmy to, że drawLine ma 3 parametry (p1, p2, asize) pierwsze dwa to punkt początkowy i końcowy linii, ostatni to rozmiar strzałki, aby dać końcowemu użytkownikowi pewną kontrolę nad tym, jak duże są te strzały na końcu.

Większość matematyki zawierałaś w swoim kodzie, ale była trochę pomieszana, obliczyłeś lineAngle, ale zgubiłem się w kolejności twoich operacji, więc lepiej zacznij od zera.

1
Helder Sepulveda 14 marzec 2020, 19:29