Ich möchte meine Antwort in C# auf der Grundlage der Antwort von Marcelo Cantos beitragen, da der Algorithmus wirklich gut funktioniert. Ich habe ein Programm geschrieben, um den Schwerpunkt eines Laserstrahls zu berechnen, der auf ein CCD-Array projiziert wird. Nachdem der Schwerpunkt gefunden wurde, wird die Richtungs-Winkel-Linie gezeichnet und ich brauche die Pfeilspitze, die in diese Richtung zeigt. Da der Winkel berechnet wird, müsste die Pfeilspitze dem Winkel in jeder beliebigen Richtung folgen.
Mit diesem Code können Sie die Größe der Pfeilspitze flexibel ändern, wie in den Abbildungen gezeigt.
Zunächst benötigen Sie die Vektorstruktur mit allen erforderlichen Überladungen der Operatoren.
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);
}
}
Dann kannst du den gleichen Code wie Marcelo Cantos verwenden, aber ich habe die Länge und die halbe Breite der Pfeilspitze zu Variablen gemacht, damit du sie beim Aufruf der Funktion definieren kannst.
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;
}
Jetzt können Sie die Funktion wie folgt aufrufen:
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);
In meinem Code ist der Kreismittelpunkt die erste Vektorposition (Pfeilspitze), und der centroid_pixel ist die zweite Vektorposition (Pfeilspitze).
Ich zeichne die Pfeilspitze, indem ich die Vektorwerte in den Punkten für die Funktion graphics.DrawPolygon() in der Datei System.Drawings. Der Code wird unten gezeigt:
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);