Quiero contribuir con mi respuesta en C# según la respuesta de Marcelo Cantos, ya que el algoritmo funciona muy bien. Escribí un programa para calcular el centroide de un rayo láser proyectado en la matriz CCD. Después de encontrar el centroide, se dibuja la línea del ángulo de dirección y necesito la punta de la flecha apuntando en esa dirección. Como se calcula el ángulo, la punta de la flecha debería seguir el ángulo en cualquiera de las direcciones.
Este código le da la flexibilidad de cambiar el tamaño de la punta de la flecha, como se muestra en las fotos.
Primero necesita la estructura vectorial con todas las sobrecargas de operadores necesarias.
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);
}
}
A continuación, puede utilizar el mismo código dado por Marcelo Cantos, pero hice lo largo y half_width de las variables punta de flecha de manera que se puede definir que cuando se llama a la función.
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;
}
Ahora se puede llamar a la función como esta:
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);
En mi código, el centro del círculo es la primera ubicación de vectores (flecha a tope), y la centroid_pixel es la segunda ubicación del vector (flecha cabeza).
Dibujo la punta de flecha almacenando los valores vectoriales en los puntos para la función graphics.DrawPolygon() en System.Drawings.El código se muestra a continuación:
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);
Para aclarar: ¿está el final de la línea en el punto medio de la base de la punta de la flecha, o está en la punta de la punta de la flecha? – Chowlett
Es la punta de la punta de flecha –