Laden...

Punkt umkreisen (Winkel berechnung)

Erstellt von Crone vor 11 Jahren Letzter Beitrag vor 11 Jahren 5.165 Views
Thema geschlossen
C
Crone Themenstarter:in
168 Beiträge seit 2010
vor 11 Jahren
Punkt umkreisen (Winkel berechnung)

Hallo zusammen,

ich sitze nun schon seit Tagen ein einem kleinen Mathematischen Problem und weiß nun leider auch nicht mehr weiter.

Ich würde gerne ein Punkt (X,Y) umkreisen mit einem zweiten Punkt(X2,Y2) mit einer Distanz von 60. Dazu hab ich mir folgenden Code zusammen gebastellt der auch ohne Probleme funktioniert ...

        Point p, p2, p3;
        float Distanz, Winkel, Geschwindigkeit;
        bool changed = false;
        private void Form1_Load(object sender, EventArgs e)
        {
            Geschwindigkeit = 0.1f;
            Distanz = 60f;
            Winkel = 0f;

            p = new Point(180, 120);
            p2 = new Point(240, 120);
            p3 = new Point(110, 120);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            move();
        }

        private void move()
        {
            int PosX, PosY;
            if (((p3.X - p2.X) * -1) < 11 || changed)
            {
                changed = true;
                PosX = CalcX(Convert.ToInt32(p3.X), Winkel, Distanz);
                PosY = CalcY(Convert.ToInt32(p3.Y), Winkel, Distanz);
            }
            else
            {

                PosX = CalcX(Convert.ToInt32(p.X), Winkel, Distanz);
                PosY = CalcY(Convert.ToInt32(p.Y), Winkel, Distanz);
            }
            Winkel += Geschwindigkeit;

            p2 = new Point(PosX, PosY);
            Update();
        }

        private void Update()
        {
            panel1.Location = p2;
        }

        private int CalcX(int midPoint, float newAngle, float distance)
        {
            return Convert.ToInt32(midPoint + Math.Cos(newAngle) * distance);
        }

        private int CalcY(int midPoint, float newAngle, float distance)
        {
            return Convert.ToInt32(midPoint + Math.Sin(newAngle) * distance);
        }

Dazu hab ich aber erstmal eine frage nach meinem Mathematischen verständnis müsste der Winkel nach einer vollen Umrundung bei 360 Grad bzw. 3.60 liegen jedoch liegt der Winkel bei 6.30... Warum? Entweder ich hab in der Schule geschlafen oder ich weiß auch nicht 😃

Naja jedenfalls kommen wir zu meinen eigentlichen Problem ich hab nämlich einen Dritten Punkt hinzugefügt.

Punkt 3 Steht auch still genau so wie Punkt 1 nun soll der sich bewegende Punkt (Punkt 2) sobald dieser zu nah an Punkt3 ist diesen umkreisen, jedoch brauche ich dafür den Winkel von Punkt2 zu Punkt3 um von dort aus weiter zu Rotieren würde ich den Winkel von Punkt2 zu Punkt1 nehmen würde dieser beim nächsten Update an einer ganz anderen Position auftauchen.

Hört sich alles kompliziert an daher hier ein Screenshot

Siehe Bild im Anhang

Naja jedenfalls kam mir dann folgende Idee wenn ich den Winkel durch 2 Teile müsste dies bedeuten das der Punkt an den Koordinaten bleibt und nicht sein Position total Planlos verändert nur leider falsch gedacht ... zweiter gedanke na dann einfach -(6,3/2) (eigentlich (3,60/2)) aber auch hier landet Punkt2 wo ganz anderes. Ich muss also den Winkel neu berechnen... nur wie? Ich habs schon auf zig wegen versuch ich hab mir gedacht das ich einfach ein Dreieck bilden müsste um den Winkel zu ermitteln aber das scheint auch nicht ganz zu stimmen 😃

im zweiten Beitrag gibt es noch ein Bild dazu

aber am besten sieht man es wenn man es als Programm ausführt. Dazu müsste man zu den code oben nur noch eine Form erstellen und dort ein Panel und Button hinzufügen.

Edit: Das ist nur ein Beispiel man könnte den Winkel einfach auf 0 Setzen in diesm Beispiel fall, aber im meinem fall kann der Wechsel zu Punkt3 an jeder Beliebigen Position passieren, zudem Rotiert Punkt2 vorher mehrmals um Punkt1

Ich hoffe ich habe mein Problem verständlich ausgedrückt und danke schon mal an alle die sich daran probieren werden mein Problem zu lösen 😃

Mit freundlichen Grüßen
Marcel

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

C
Crone Themenstarter:in
168 Beiträge seit 2010
vor 11 Jahren

Zweites Bild:

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

D
96 Beiträge seit 2012
vor 11 Jahren
  1. Die trigonometrischen Funktionen im .NET-Framework rechnen mit dem Bogenmaß. Eine Umdrehung (360°) entspricht im Bogenmaß 2*PI, was etwa 6,28 und somit ca. 6,3 ist.

  2. Der Ansatz mit dem Dreieck sollte doch funktionieren. Der Winkel zwischen zwei Punkten ist (mithilfe eines Dreiecks leicht zu erkennen):

alpha = atan(dy/dx)

atan ist die Arcustangens-Funktion und dy bzw. dx ist die Differenz der y- bzw. x-Koordinaten deiner Punkte.

C
Crone Themenstarter:in
168 Beiträge seit 2010
vor 11 Jahren

zu Nummer 1. Wer soll den da drauf kommen 😃 Naja du anscheinend jetzt weiß ich zu mindestens auch bescheit... und ich dachte schon das ich irgendwas falsch gemacht habe und das mein Punkt nur durch zufall um den anderen Rotiert 😄

zu Nummer 2. werde ich gleich mal testen ... ich habs natürlich nit Sin und Cos probiert aber nicht mit Tan. Ich bin schon langsam etwas eingerostet in sachen Winkel berechnung 😃

Viel Dank.

Gruß Marcel

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

5.658 Beiträge seit 2006
vor 11 Jahren

zu Nummer 1. Wer soll den da drauf kommen 😃

Da kommt jeder drauf, der mal in die Doku geschaut hat. Die Beschreibung des Parameters, den die Math.Sin-Methode erwartet, lautet:

An angle, measured in radians.

Deine Erklärung, wie du die Position des dritten Punktes berechnen willst, hab ich leider nicht verstanden. Aber letztendlich ist es egal, um welchen Punkt sich ein anderer Punkt dreht. Die Berechnung anhand des Winkels und des Abstandes ist genau die gleiche wie beim ersten Punkt. Am Ende mußt du dann nur noch die Position von P2 zur errechneten Position von P3 addieren.

Für komplexerer Transformationen (wenn sich z.B. noch ein weiterer Punkt um P3 drehen soll o.ä.) kann man die einzelnen Schritte auch zu Transformations-Matrizen zusammen fassen. Dann kann man beliebige Rotationen, Skalierungen und Translationen anwenden, indem man die Matrizen miteinander kombiniert. Hier gibt es ein kurzes Beispiel ganz unten: Matrix-Klasse.

Christian

Weeks of programming can save you hours of planning

C
Crone Themenstarter:in
168 Beiträge seit 2010
vor 11 Jahren

Irgend was stimmt noch immer nicht mit der Berechnung der neuen Position wenn der zu umkreisende Punkte gewechselt wird.

Hier meine Berechnung des Winkels zum neuen Punkt.

               
                float ay = p2.Location.Y - p3.Location.Y                
                float bx = p2.Location.X - p3.Location.X
                
                if (bx < 0f)
                    bx *= -1;

                if (ay < 0f)
                    ay *= -1;

                float hypothenuse = (float)Math.Sqrt((ay * ay) + (bx * bx));

                float alpha = (float)Math.Tan(ay / bx);

                angle = (alpha * ((float)(Math.PI)) / 180f);
                float distance = hypothenuse;
                bool changed = true;

Mit dem neuen Winkel bzw. Bogenmaß berechne ich dann wie zuvor die Position.


        if(changed)
        {
            PosX = CalcX(Convert.ToInt32(p3.X), angle, distance);
            PosY = CalcY(Convert.ToInt32(p3.Y), angle, distance);
        }
        else
        {    
            PosX = CalcX(Convert.ToInt32(p2.X), angle, distance);
            PosY = CalcY(Convert.ToInt32(p2.Y), angle, distance);
        }
        private int CalcX(int midPoint, float newAngle, float distance)
        {
            return Convert.ToInt32(midPoint + Math.Cos(newAngle) * distance);
        }

        private int CalcY(int midPoint, float newAngle, float distance)
        {
            return Convert.ToInt32(midPoint + Math.Sin(newAngle) * distance);
        }

Das sollte eingentlich zurfolge habe das die Position genau die gleich ist wie zuvor nur das, dass Bogenmaß durch das Bogenmaßes des neuen Punktes ersetzt wurde und das die Distanz zum neuen Punkt brechnet wurde.

Leider bleibt wie erhofft die Position nicht gleich und landet wieder wo ganz anders.

ich hoffe ihr könnt mein Fehler finden 😃

Gruß Marcel

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

4.938 Beiträge seit 2008
vor 11 Jahren

Hallo Crone,

die zwei Zeilen


float alpha = (float)Math.Tan(ay / bx);

angle = (alpha * ((float)(Math.PI)) / 180f);

sind falsch (und ergeben keinen Sinn). DerKleineTomy hatte dir doch schon geschrieben, daß du den Arkustangens benutzen sollst (und nicht den Tangens).
Die zugehörige Methode dazu lautet Math.Atan(a) bzw. gerade für den Fall, daß bei a = (y/x) x auch 0 sein kann (und dann der Parameter ungültig wäre), gibt es die Methode Math.Atan2(y, x).

5.658 Beiträge seit 2006
vor 11 Jahren

Hi Marcel,

ich hoffe ihr könnt mein Fehler finden 😃

Dafür ist das Forum aber nicht gedacht, siehe [Hinweis] Wie poste ich richtig? Punkt 4a und 4c.

Du hast einen Debugger zur Verfügung, mit dem du dir die berechneten Werte anschauen kannst. Dann siehst du selbst, welche Berechnungen falsche Ergebnisse haben. Wenn du dann dazu eine konkrete Frage hast, kannst du die hier stellen. Aber einfach irgendwelchen Code posten mit der Bemerkung "Sucht mal schnell meinen Fehler" ist wirklich sehr unhöflich.

Christian

Weeks of programming can save you hours of planning

C
Crone Themenstarter:in
168 Beiträge seit 2010
vor 11 Jahren

Hallo Th69,

erstmal danke das du mich auf den Fehler aufmerksam gemacht hast, hab das mit Arcustangens, und hab garnicht gewusst das es diesen überhaupt gibt 😄. Ich hab auch gleich mal wie du Vorgeschlagen hast Atan2 genutzt:

alpha = (float)Math.Atan2(Convert.ToDouble(ay), Convert.ToDouble(bx));

Die Zeile hab ich entfernt

angle = (alpha * ((float)(Math.PI)) / 180f); 

wenn ich nun alpha = angle; nutze müsste es funktionieren tut es aber leider nicht selbe resultat wie vorher 😃.

Die Punkt ändern wieder die Position hab es auch natürlich mit Math.Atan(ay / bx); hat aber auch nichts gebracht.

Ich bekommen werte zwischen 0.0X - ca. 0.1X was ja schon nicht richtig sein kann, da der wert eigentlich immer so zwischen 0.0 - 6.3 liegen sollte, jetzt kam mir aber folgende Idee wenn ich 6,3 / 4 rechne hab ich 1.575 könnte es also sein das ich berechnen muss in welchen Quadranten sich der Punkt befindet eine andere erklärung hätte ich sonst nicht warum das nicht passt.

edit: Idee getestet und auch Fehlgeschlagen 😦

edit2: Okay hab das problem gefunden folgenden Zeilen müssen entfernt werden sonst landet man immer nur im Positiven bereich also unten recht von einem Kreis 😃

                if (bx < 0f)
                     bx *= -1;
 
                if (ay < 0f)
                     ay *= -1;

@MrSparkle so war das auch nicht gemeint und ich hab mich zuvor natürlich mit den Code beschäftigt und hab auch den Debugger benutzt. + ein Taschenrechner und Dreiecks-Calculatoren, jedoch hab ich Arcustangens im Posting zuvor überlesen, da ich dies nicht mal kannte hab ich gedacht damit wäre der normal Tangens gemeint.

Jedenfalls Danke für euere hilfe endlich kann es weiter gehen 😃

Real programmers don't comment their code - it was hard to write, it should be hard to understand.

D
96 Beiträge seit 2012
vor 11 Jahren

Nur als Ergänzung:
Mit Sinus, Kosinus und Tangens erhält man zu einem Winkel ein passendes Seitenverhältnis

sin(alpha)=Gegenkathete/Hypothenuse
cos(alpha)=Ankathete/Hypothenuse
tan(alpha)=Gegenkathete/Ankathete

Allerdings hast du ja gerade mit dy/dx das Seitenverhältnis, aber nicht den Winkel, den du suchst. Der Arkussinus/-kosinus/-tangens ist die Umkehrfunktion des Sinus/Kosinus/Tangens und berechnet somit zu einem Seitenverhältnis den passenden Winkel.

asin(Gegenkathete/Hypothenuse)=alpha
acos(Ankathete/Hypothenuse)=alpha
atan(Gegenkathete/Ankathete)=alpha
Hinweis von herbivore vor 11 Jahren

Sicher muss man nicht alles wissen. Und es schändet auch keinen, wenn er etwas bestimmtes nicht weiß. Doch dass du dich mit so einer Aufgabe beschäftigst und das Bogenmaß nicht kanntest, hatte mich schon stutzig gemacht. Doch wenn du die Arcus-(also Umkehr)Funktionen nicht kennst, dann fehlen definitiv die Grundlagen des Themengebiets (hier: Dreicks- bzw. Winkelbrechungen), die man für die Lösung der Aufgabe braucht. Und wir setzen nicht nur die allgemeinen Grundlagen voraus, sondern auch die die jeweiligen Themengebiets, siehe [Hinweis] Wie poste ich richtig? Punkt 1.1.1. Ohne diese Grundlagen wird es sicher schwer, Probleme auf dem Gebiet zu lösen. Es wäre sicher auch in deinem Interesse dir das in einem Mathebuch nochmal anzuschauen.

Thema geschlossen