Tôi muốn đóng góp câu trả lời của mình trong C# dựa trên câu trả lời của Marcelo Cantos vì thuật toán hoạt động thực sự tốt. Tôi đã viết một chương trình để tính toán trọng tâm của chùm tia laser chiếu trên mảng CCD. Sau khi tìm thấy trọng tâm, đường góc hướng được vẽ và tôi cần đầu mũi tên chỉ hướng đó. Vì góc được tính toán, đầu mũi tên sẽ phải theo góc theo bất kỳ hướng nào.
Mã này mang đến cho bạn sự linh hoạt của việc thay đổi kích thước mũi tên đầu như thể hiện trong hình ảnh.
Trước tiên, bạn cần cấu trúc vectơ với tất cả các toán tử cần thiết quá tải.
private struct vec
{
public float x;
public float y;
public vec(float x, float y)
{
this.x = x;
this.y = y;
}
public static vec operator -(vec v1, vec v2)
{
return new vec(v1.x - v2.x, v1.y - v2.y);
}
public static vec operator +(vec v1, vec v2)
{
return new vec(v1.x + v2.x, v1.y + v2.y);
}
public static vec operator /(vec v1, float number)
{
return new vec(v1.x/number, v1.y/number);
}
public static vec operator *(vec v1, float number)
{
return new vec(v1.x * number, v1.y * number);
}
public static vec operator *(float number, vec v1)
{
return new vec(v1.x * number, v1.y * number);
}
public float length()
{
double distance;
distance = (this.x * this.x) + (this.y * this.y);
return (float)Math.Sqrt(distance);
}
}
Sau đó, bạn có thể sử dụng cùng mã do Marcelo Cantos đưa ra, nhưng tôi đã thực hiện độ dài và half_width của các biến đầu mũi tên để bạn có thể xác định khi gọi hàm.
private void arrowhead(float length, float half_width,
vec A, vec B, ref vec v1, ref vec v2)
{
float h = length * (float)Math.Sqrt(3);
float w = half_width;
vec U = (B - A)/(B - A).length();
vec V = new vec(-U.y, U.x);
v1 = B - h * U + w * V;
v2 = B - h * U - w * V;
}
Bây giờ bạn có thể gọi hàm như thế này:
vec leftArrowHead = new vec();
vec rightArrowHead = new vec();
arrowhead(20, 10, new vec(circle_center_x, circle_center_y),
new vec(x_centroid_pixel, y_centroid_pixel),
ref leftArrowHead, ref rightArrowHead);
Trong mã của tôi, trung tâm vòng tròn là vị trí vector đầu tiên (mũi tên mông), và centroid_pixel là vị trí vector thứ hai (mũi tên cái đầu).
Tôi vẽ đầu mũi tên bằng cách lưu các giá trị vectơ vào các điểm cho đồ họa.DrawPolygon() trong System.Drawings.Mã được hiển thị bên dưới:
Point[] ppts = new Point[3];
ppts[0] = new Point((int)leftArrowHead.x, (int)leftArrowHead.y);
ppts[1] = new Point(x_cm_pixel,y_cm_pixel);
ppts[2] = new Point((int)rightArrowHead.x, (int)rightArrowHead.y);
g2.DrawPolygon(p, ppts);
Để làm rõ - là kết thúc của dòng ở giữa điểm gốc của đầu mũi tên hay là đầu mũi tên của đầu mũi tên? – Chowlett
Đó là mũi tên của đầu mũi tên –