Mit Pfeil und Kreis...
-
Hallo,
gegeben habe ich zwei Punkte A und B. Zwischen den zwei Punkten will ich nun einen Pfeil zeichnen. Nur ich komme mit der Mathematik dahinter nicht ganz klar oO
Die Pfeilspitze soll bei A sein und eine variable Dicke und Länge haben.
Ich dachte, ich nehme mir zur Hilfe einen Kreis. Der Kreis hat den Radius von der Länge der Pfeilspitze. Dann brauch ich ja "nur" noch die Sehne zeichnen.Aber um überhaupt mit dem Kreis arbeiten zu können brauche ich ja einen Winkel. Den Winkel wollte ich bekommen, indem ich den Kreis nach den gegebenen Punkten zeichne. Also Kreismitte ist A und der Punkt auf dem Rand ist B.
Einen Punkt auf dem Kreis berechnet man ja so:
Px = Mx + r * cos( Winkel )
Py = My + r * sin( Winkel )Das hab ich dann nach dem Winkel umgestellt:
Winkel = ( Px - Mx ) / rAber wenn ich das mit A( 50, 50 ) und B( 200, 100 ) berechne, kommt ein Winkel von -0,949... raus.
Wie komm ich an den Winkel? Hab ich falsch umgestellt oder nehme ich die falsche Formel?Bzw. gibt es bessere Wege, einen Pfeil von A nach B zu zeichnen?
MfG. Ich
-
ChristophLu schrieb:
Das hab ich dann nach dem Winkel umgestellt:
cos(Winkel) = ( Px - Mx ) / rWinkel = arccos(( Px - Mx ) / r).
ChristophLu schrieb:
Bzw. gibt es bessere Wege, einen Pfeil von A nach B zu zeichnen?
-
Hallo,
ich hab das jetzt auf anderen Wegen hinbekommen, habe aber ein Problem.
Hier mal eine Grafik dazu:
http://home.arcor.de/minicrispie/dreieck.pngIch hab jeden Punkt, jede Länge und jeden Winkel. Das einzige, was fehlt, ist G.
Wie komme ich an die x- und y-Koordinaten von G?
Mir will da keine Lösung einfallen oOMfG. Ich
-
ChristophLu schrieb:
Wie komme ich an die x- und y-Koordinaten von G?
Durch Vektorrechnung (Großbuchstaben sollen im Folgenden Vektoren bezeichnen):
G = D + ((C-D) * Drehmatrix(-Winkel zwischen GDC))* y/x
-
Hallo,
ich hab das jetzt doch mit den Kreisen gemacht, und habe da schonwieder nen Problem. In meinem Programm zeichne ich den Pfeil in jedem Winkel:
#include <cmath> //[...] double winkel = 0.0; Punkt Start; Punkt Ende( 200, 200 ); double radius = 50.0; while( !key[KEY_ESC] ) { Start.x = Ende.x + radius * cos( winkel / DEGtoRAD ); Start.y = Ende.y + radius * sin( winkel / DEGtoRAD ); zeichnePfeil( puffer, Start, Ende, 0, false ); //Parameter: Bitmap, A, B, Farbe, Gefüllter Pfeil? textprintf_ex( puffer, font, 3, 3, 0, -1, "Winkel: %f", winkel ); winkel += 1.0; if( winkel > 360.0 ) { winkel = 0.0; } }
Um die Pfeilspitze zeichnen zu können, brauche ich wieder den Winkel. Den muss ich nun aus den übergebenen Punkten A und B wieder herauslesen. in zeichnePfeil() mache ich das so:
#define DEGtoRAD ( 180 / M_PI ) double winkel_pfeil = acos( ( B.x - A.x ) / pfeillaenge ) * DEGtoRAD;
Der ausgelesene Winkel stimmt nie mit dem gesetzten überein. Zudem wird der Pfeil falsch gezeichnet. Aber ich finde den Fehler nicht.
Hier sind mal ein paar Screenshots von ein paar Positionen:
http://home.arcor.de/minicrispie/pfeil/1.png
http://home.arcor.de/minicrispie/pfeil/2.png
http://home.arcor.de/minicrispie/pfeil/3.png
http://home.arcor.de/minicrispie/pfeil/4.pngDie Pfeilspitze liegt bei Punkt A. Demnach ist der Kreis-Mittelpunkt bei B. Die rote Linie wird von A nach B gezeichnet.
Falls das bei der Lösung hilft, hier ist die gesamte Pfeil-Mal-Funktion:
const double pfeil_winkel = 25.0; const double pfeil_laenge = 10.0; int zeichnePfeil( BITMAP *buffer, Punkt A, Punkt B, int color, bool fill ) { if( buffer == NULL ) { return -1; } /* Bei Punkt A ist die Pfeilspitze Bei Punkt B ist das Ende des Pfeils. */ //Die Pfeillänge berechnen double pfeillaenge = satzDesPythagoras( ( A.x - B.x ), ( A.y - B.y ) ); //Die Winkel berechnen #define DEGtoRAD ( 180 / M_PI ) double winkel_pfeil = acos( ( B.x - A.x ) / pfeillaenge ) * DEGtoRAD; double winkel_spitze_oben = winkel_pfeil + pfeil_winkel; double winkel_spitze_unten = winkel_pfeil - pfeil_winkel; int zeile = 20; #define ZEILE ( zeile += 10 ) textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "Pfeillänge: %f", pfeillaenge ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "winkel_pfeil: %f", winkel_pfeil ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "winkel_spitze_oben: %f", winkel_spitze_oben ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "winkel_spitze_unten: %f", winkel_spitze_unten ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "A.x: %f", A.x ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "B.x: %f", B.x ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "A.y: %f", A.y ); textprintf_ex( buffer, font, 50, ZEILE, 0, -1, "B.y: %f", B.y ); //Die Positionen der Pfeilenden berechnen Punkt p_spitze_oben; Punkt p_spitze_unten; Punkt p_linie_start; p_spitze_oben.x = A.x + pfeil_laenge * cos( winkel_spitze_oben / DEGtoRAD ); p_spitze_oben.y = A.y + pfeil_laenge * sin( winkel_spitze_oben / DEGtoRAD ); p_spitze_unten.x = A.x + pfeil_laenge * cos( winkel_spitze_unten / DEGtoRAD ); p_spitze_unten.y = A.y + pfeil_laenge * sin( winkel_spitze_unten / DEGtoRAD ); p_linie_start.x = A.x + pfeil_laenge * cos( winkel_pfeil / DEGtoRAD ); p_linie_start.y = A.y + pfeil_laenge * sin( winkel_pfeil / DEGtoRAD ); //Den Pfeil zeichnen line( buffer, B.x, B.y, p_linie_start.x, p_linie_start.y, color ); line( buffer, A.x, A.y, p_spitze_unten.x, p_spitze_unten.y, color ); line( buffer, A.x, A.y, p_spitze_oben.x, p_spitze_oben.y, color ); line( buffer, p_spitze_unten.x, p_spitze_unten.y, p_spitze_oben.x, p_spitze_oben.y, color ); line( buffer, A.x, A.y, B.x, B.y, makecol( 255, 0, 0 ) ); //Soll der Pfeil gefüllt werden? if( fill ) { //Ein Punkt in der Pfeilspitze bestimmen Punkt fuell_punkt; fuell_punkt.x = A.x + ( pfeil_laenge / 2.0 ) * cos( winkel_pfeil / DEGtoRAD ); fuell_punkt.y = A.y + ( pfeil_laenge / 2.0 ) * sin( winkel_pfeil / DEGtoRAD ); //Den Pfeil füllen floodfill( buffer, fuell_punkt.x, fuell_punkt.y, color ); } return 0; }
Ich hoffe, ihr findet den Fehler, ich bin mit meinem Latain am Ende. Und meine Mathe-Begabung hält sich auch in Grenzen
Danke schon mal
MfG. Ich
-
So ... habs geschafft. Ich hatte erstens falsch gedacht und zweitens falsch berechnet oO.
Problem behoben.
-
Falls du es nicht kennst: Schlag mal nach, was atan2 ist.