Kreiskoordinaten

Zera Kakkade

Grünschnabel
Hallo an alle :)

Ich habe wiedermal ein kleines Problem.

Ich Habe eine Form die 600x300 Pixel groß ist und auf dieser befinded sich ein Punkt mit ein von mir festgelegtem Startpunkt.
Sagen wir der Startpunkt ist bei 300x150.
Der Punkt soll sich nun immer in eine bestimmte Richtung bewegen.
Dazu habe ich ihm eine Winkel Variable gegeben.
90
0 + 180
270

Nun soll er sich um zwei Einheiten (Pixel) in eine bestimmte Richtun bewegen.
Dazu rechne ich den gewünschten Winkel aus.
Angenommen der Winkel ist 135Grad sollte sich der Punkt nun nach rechts oben Bewegen.

Mein Problem ist, das ich es nicht hinbekomme mit Hilfe der Aktuellen Koordinaten und den mir zur verfügung stehenden Winkel den Punkt in die gewünschte Richtung zu bewegen...
Zudem habe ich gelesen das c# mit radiant rechnet und ich der Meinung bin Degree zu benötigen.

Die neuen Koordinate wollte ich so ermitteln, was aber irgendwie gar nicht klappt.

float x = (float)Math.Sin(fAngle); <<< wobei das irgendwie kein sinn ergibt
float y = (float)Math.Sqrt(Math.Pow(2, 2) + Math.Pow(x, 2));

In xPos und yPos sind die derzeitigen Koordinaten des Punkt.

nun rechne ich nur noch
xPos += (Int32)x;
yPos += (Int32)y;


Ich hoffe Ihr könnt mir helfen.
So löse ich nicht nur mein Problem sondern erweitere mein Wissen mit euerer Hilfe direkt mir :)

Danke im vorraus

Mfg.: Zera
 
Du möchtest also den Endpunkt deines Bewegungsvektors berechnen. Nehmen wir erstmal an, der Startpunkt sei bei (0,0). Du hast den Vektor in Poarkoordinaten vorgegeben, nämlich mit der Länge r und dem Winkel w; r ist in deinem Fall 2. Die kartesischen Koordinaten des Endpunktes sind dann:

Code:
x = r * cos(w) 
y = r * sin(w)
Dies addierst du auf deine Startkoordinaten. Allerdings darfst du nur die x-Koordinate addieren, die y-Koordinate musst du subtrahieren, weil in der Mathematik die y-Achse nach oben zeigt, beim Bildschirmfenster aber nach unten.
Den Winkel hast du in Altgrad (degrees), du musst ihn also vorher in Bogenmaß (radiant) umrechnen. Hier sind die Formeln dafür.

Code:
360/deg = 2*PI/rad

daraus folgt:
rad = deg*(2*PI)/360 = deg*PI/180 
deg = rad*360/(2*PI) = rad*180/PI
Das ganze würde dann ungefähr so aussehen:

C#:
float w = (float)(fAngle*Math.PI/180.0);
float r = 2;

float x = (float)(r*Math.Cos(fAngle)); // NICHT Math.sin
float y = (float)(r*Math.Sin(fAngle));

xPos += (Int32)(x);
yPos -= (Int32)(y);

PS: Altgrad unterteilt den Vollwinkel in 360 Grad, Neugrad in 400 Gon.
 
Zuletzt bearbeitet von einem Moderator:
@Vereth
Hay danke dir für deine schnelle Antwort.

Es hat auch auf dem ersten blick gut geklappt... doch dreht der Punkt nach dem zweiten Klick durch.

Ich habe das ganze nun Grafisch verpackt und zeige es euch mal.
Programm: http://www.onlinefirmenbuch.de/Ship.exe

Ihr müsst oben auf das + Klicken um Schiffe zu erzeugen. und diese Könnt ihr dann einzeln durch selektieren in der Combobox anwählen.
Durch klicken auf ^ bewegen diese sich(oder sollten sich) dann in Blickrichtung.
Durch klicken im All, könnt ihr das Schiff Drehen.
Dies geht auch ohne das das Schiff forwarts fliegt, doch müsst ihr dann ganz oft klicken.
In dem ersten Label wird dir Differenz angezeigt, um die sich das Schiff noch drehen muss.
Im zweiten Label wird die x und y Koordinate angezeigt, die aus Vereth´s Gleichung erreichnet werden.

hier der Code der den Winkel bei einem Klick errechnet, das Schiff fliegen lässt und Zeichnet.

Der Start Angle ist 90...
Also im Konstruktor ist fAngle = 90;

Code:
public void FlyForward()
            {
            double w = fAngle * Math.PI / 180;
            double x = 2 * Math.Cos(w);
            double y = 2 * Math.Sin(w);
            
            xPos += (Int32)x;
            yPos -= (Int32)y;
        }

        public void NewKoord(Int32 x, Int32 y)
        {
            double newWinkel = Math.Atan2((yPos - y), (xPos - x));
            DWinkel = newWinkel * (180.0 / Math.PI);
            if (DWinkel < 0)
                DWinkel = 180 + (DWinkel + 180);
            DiffWinkel = (Int32)DWinkel - fAngle;

            if (DiffWinkel < -180)
            {
                DiffWinkel += 360;
            }
            else if (DiffWinkel > 180)
            {
                DiffWinkel -= 360;
            }
        }

        public void DrawShipGraphic(PaintEventArgs e)
        {
            if (DiffWinkel != 0)
                if (DiffWinkel < 0)
                {
                    fAngle--;
                    if (fAngle < 0)
                        fAngle = 359;

                    //Angle--;
                    DiffWinkel++;
                    m.RotateAt(-1, new Point((Int32)xPos, (Int32)yPos));
                }
                else if (DiffWinkel > 0)
                {
                    fAngle++;
                    if (fAngle > 359)
                        fAngle = 0;
                    //Angle++;
                    DiffWinkel--;
                    m.RotateAt(1, new Point((Int32)xPos, (Int32)yPos));
                }

            panel1.Text = "DiffW: " + DiffWinkel.ToString();
            panel2.Text = "x,y  : " + xPos.ToString()+"|"+yPos.ToString();
                   


            Graphics g = e.Graphics;
            //g.RotateTransform(Angle);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.Transform = m;
            //g.DrawImage(test,100,100,60,60);

            e.Graphics.DrawImage(ShipG, xPos - sWidth/2, yPos - sHeight/2, sWidth, sHeight);

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        }


Ich danke euch allen!
ich probier dann auch mal weiter
 
Das FlyForward() ist korrekt. Ist ja auch von mir. :)
In NewKoord() berechnest du newWinkel falsch. Denke immer daran, dass Winkel im Gegenuhrzeigersinn hochgezählt werden und die Orientierung der Y-Achse in der Mathematik nach oben zeigt, bei einem Bildschirmfenster aber nach unten. Deswegen musst du schreiben
C:
double newWinkel = Math.Atan2((yPos - y), (x - xPos));
So wie du es geschrieben hast, bringt es die Variable fAngle durcheinander.
DrawShipGraphic() scheint ok zu sein, allerdings ist das erste if-Statement überflüssig.

Die Zuordnung der Steuerelemente zu den Schiffen scheint bei dir für Konfusion zu sorgen. Wenn ein neues Schiff erzeugt wird, wird es angezeigt, aber nicht ausgewählt, jedoch seine Werte in die Anzeige geschrieben. Und wenn die Maus in einem Steuerelement (Button oder Combobox) bewegt wird, wird der DiffW-Wert in Richtung 0 runter- bzw. raufgezählt; wahrscheinlich wird irgendein Event falsch gehandelt.

Aber deine Grafik ist schön geworden. Hast du die Schiffe selber gemalt?
 
Wenn ich
Code:
double newWinkel = Math.Atan2((yPos - y), (x - xPos));
mache, dann dreht der in die falsche richtung auf der x-achse. das kann ich kompensieren in dem ich die Winkel anderes abziehe in der Zeichenfunktion,
jedoch funktioniert dann immer noch nix... mir ist aufgefallen das die Schiffgrafik meist nie an der eigentlichen x und y position sind.
Laut Code
Code:
e.Graphics.DrawImage(ShipG, xPos - sWidth / 2, yPos - sHeight / 2, sWidth, sHeight);
wird die grafik zwar an die neu errechneten Koordinaten plaziert.. aber laut Bildschirm stimmen diese nicht.
Irgendwann verschwindet das Schiff meist nach oben, obwohl der y wert noch bei 200 ist.

Ich bin am verzweifeln... <.<
 
Das kmmt alles daher, dass du mit deiner Transformationsmatrix nicht einfach nur das Bild drehst, sondern das ganze Koordinatensystem um den angegebenen Punkt drehst. Dadurch verändert sich auch die Position der Punkte an den anderen Koordinaten. Du darfst eine Transformation nicht auf das Graphics-Objekt anwenden, sondern musst deine Bitmap einem GUI-Element zuweisen, das du anzeigst. Auf dieses kannst du dann eine Dreh-Transformation anwenden, ohne die Koordinaten der Punkte deiner gesamten Zeichenfläche zu verändern. Du kannst zum Beispiel schauen, ob du eine geeignete UIElement-Klasse findest.
Außerdem solltes du zur Erhöhung der Rechengenauigkeit in der FlyForward-Methode den cast von (Int32) auf (float) ändern.

PS: Deine Mail habe ich erhalten. Der Anhang ist auch korrekt rübergekommen.
 
Ich habe noch nie mit UIElementen gearbeitet bzw was davon gehört...
Wie binde ich die denn ein?
Überall steht das die in System.Windows sind. Aber ich kann keine erstellen.

Wenn ich das über die Graphics mache. Malt der doch jedes mal alles neu...
Dennoch rotiert der ja das Ganze Bild... kann ich dem nicht sagen, das er nur ein Bitmap laden soll dieses Rotieren soll und es dann dem Haupt Graphic hinzufügt?
Ich kann aber irgendwie nur ein graphic aus dem Hauptbild erstellen.
 
Zurück