Reputation: 727
I'm going to draw lines using canvas. I want to draw a dashed line like the image below.
I succeeded in drawing a dashed line with two points with the same Y-axis with the following code.
void _drawDashedLine(
Canvas canvas,
Paint paint,
Size size,
Offset p1,
Offset p2,
) {
// dashed width and distance
const int dashWidth = 5;
const int dashSpace = 5;
double startX = p1.dx;
double startY = p1.dy;
while (startX < p2.dx) {
canvas.drawLine(
Offset(startX, startY), Offset(startX + dashWidth, startY), paint);
startX += dashWidth + dashSpace;
}
}
However, I'm failed to draw a diagonal line like the image below (the blue dot in the image is p1, p2).
This is the code I tried.
void _drawDashedLine(
Canvas canvas,
Paint paint,
Size size,
Offset p1,
Offset p2,
) {
const int dashWidth = 5;
const int dashSpace = 5;
double startX = p1.dx;
double startY = p1.dy;
while (startX < p2.dx) {
canvas.drawLine(Offset(startX, startY),
Offset(startX + dashWidth, startY + dashWidth), paint);
startX += dashWidth + dashSpace;
startY += dashWidth + dashSpace;
}
}
This always changes the value of the Y-axis to be constant, so that it is drawn at a completely different angle.
I think I should calculate the Y-axis by the angle of the two points p1, p2, so can I know how to do this?
Upvotes: 0
Views: 1170
Reputation: 12891
As you already guessed, we need to determine the angle formed by the two points p1
and p2
first. The dart's math library is our little helper here. Let's say we have the points
final p1 = Offset(50, 50);
final p2 = Offset(250, 150);
and feed the difference between the two points horizontal and vertical position to the math.atan2()
method, we get the angle in radians
final dX = p2.dx - p1.dx;
final dY = p2.dy - p1.dy;
final angle = math.atan2(dY, dX);
The second step is calculating the actual width of the line. If it's a simple horizontal or vertical line things are quite simple, if it's at an angle which is not a multiple of 90° things are - a bit - more complicated. If we add two 'virtual' lines to our line to form a right-triangle, we can use the Pythagorean theorem to calculate the length of the line .
final totalLength = math.sqrt(math.pow(dX, 2) + math.pow(dY, 2));
With this two steps we're ready to go. Starting from p1
we move into the direction of p2
, sum up the segments we already draw and if it exceeds totalLength
our line is complete.
void _drawDashedLine(
Canvas canvas,
Paint paint,
Offset p1,
Offset p2,
) {
const int dashWidth = 5;
const int dashSpace = 5;
final dX = p2.dx - p1.dx;
final dY = p2.dy - p1.dy;
final angle = math.atan2(dY, dX);
final totalLength = math.sqrt(math.pow(dX, 2) + math.pow(dY, 2));
double drawnLength = 0.0;
final cos = math.cos(angle);
final sin = math.sin(angle);
while (drawnLength < totalLength) {
canvas.drawLine(
Offset(p1.dx + cos * drawnLength, p1.dy + sin * drawnLength),
Offset(p1.dx + cos * (drawnLength + dashWidth),
p1.dy + sin * (drawnLength + dashWidth)),
paint);
drawnLength += dashWidth + dashSpace;
}
}
Upvotes: 2