Laden...

Kugeln drehen sich im Kreis

Erstellt von Angel_de vor 17 Jahren Letzter Beitrag vor 17 Jahren 12.215 Views
A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren
Kugeln drehen sich im Kreis

Ich habe arge Probleme damit einen Algorithmus hinzubiegen, der folgendes bewerkstelligt
(in C# + D3D)

  • ich habe 3 Radien für 3 Kreise
  • auf diesen 3 Radien sollen sich, abhängig von einer Variablen, mehrere Kugeln befinden.
  • diese kugeln sollen sich dann wie ein Rad um den Nullpunkt drehen.

Folgende Konstruktion habe ich bisher getestet ... aber das passt nocht nicht ganz.
in den For-Schleifen werden ja auch immer die selben Koordinaten eingetragen. Somit zeichnet er dann z.B. 7mal den selben Punkt auf der selben Stelle ... komme aber trotzdem vom Denken her nicht weiter


geschw = (geschw + 0.03f) % 360; // Schrittgeschw.
        cosinus = Math.Cos(geschw);
        sinus = Math.Sin(geschw);

        float Schale1 = 0.7f;   //Radien der
        float Schale2 = 1.0f;   //Schalen zum 
        float Schale3 = 1.2f;   //Mittelpunkt

        Eleks[0].X = (float)cosinus * Schale1;
        Eleks[0].Y = (float)sinus * Schale1;
        Eleks[1].X = (float)Math.Cos(geschw + Math.PI);   //Pi = 180Grad
        Eleks[1].Y = (float)Math.Sin(geschw + Math.PI);   //also genau gegenüber

        Eleks[2].X = (float)cosinus * Schale2;
        Eleks[2].Y = (float)sinus * Schale2;
        for (i = 3; i < 10; i++)
        {
                Eleks[i].X = (float)Math.Cos(geschw + Math.PI / 3) * Schale2;
                Eleks[i].Y = (float)Math.Sin(geschw + Math.PI / 3) * Schale2;
        }

        Eleks[10].X = (float)cosinus * Schale3;
        Eleks[10].Y = (float)sinus * Schale3;
        for (i = 11; i < 14; i++)
        {
            Eleks[i].X = (float)Math.Cos(geschw + Math.PI / 4) * Schale3;
            Eleks[i].Y = (float)Math.Sin(geschw + Math.PI / 4) * Schale3;
        }


//Schale 1 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Blue;
        device.Material = mtrl;
        for (i = 0; i < 2; i++)
        {            
            mElektron = Matrix.Translation(new Vector3(Eleks[i].X, Eleks[i].Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);   //zeichnet Elektronen der 1. Schale
        } 

        //Schale 2 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Yellow;
        device.Material = mtrl;
        for (i = 2; i < 10; i++)
        {
            mElektron = Matrix.Translation(new Vector3(Eleks[i].X, Eleks[i].Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);   //zeichnet Elektronen der 2. Schale
        }

Hat jmd. eine Idee ?

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Angel_de,

kannst bitte noch beschreiben, wo du genau hängst? Was geht, was geht nicht? Was ist dein gedankliches Problem?

herbivore

F
529 Beiträge seit 2003
vor 17 Jahren

Ich glaube ich kennen den Fehler:
x = cos(w + fi) * r
y = sin(w + fi) *r

Soweit ich das sehen kann, ist bei deiner Formel hier alles im Sinus erstens konstant (und zweitens nicht einheitenfrei). Daher bekommst du immer den selben Punkt. Wenn du die Winkelgeschwinigkeit einheitenfrei machst(also mit t multiplizierst) sollte es gehen. Du musst halt bei den Schleifendurchläufen die verstrichene Zeit messen.

Edit:
Übrigens würde ich nicht mit der Kanone auf die Spatzen schießen und die Kreisbahn mit
r² = x ² + y² beschreiben.

Besuchen sie das VisualC++ - Forum

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

mit der aktuellen Version passiert folgendes :

ich habe 3 Bahnen

Gedacht ist es so : 2 Elektronen (blau) auf der inneren Bahn, 8 ( gelb) auf der mittleren und 4 (türkis) auf der äußeren.

Momentan macht er aber :
1 innere blau
2 gelbe + 1 blaue in der mitte
2 türkise außen

drehen tun die sich auch ... aber es sind halt zu wenige


protected static void OnTimer(Object myObject, EventArgs myEventArgs)
    {
        if (device == null) return;
        device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1f, 0);   //Altes Image verwerfen - Color.Black als Hintergrund
               
        geschw = (geschw + 0.03f) % 360; // Schrittgeschw.
        cosinus = Math.Cos(geschw);
        sinus = Math.Sin(geschw);

        float Schale1 = 0.7f;   //Radien der
        float Schale2 = 1.0f;   //Schalen zum 
        float Schale3 = 1.2f;   //Mittelpunkt

        Eleks[0].X = (float)cosinus * Schale1;
        Eleks[0].Y = (float)sinus * Schale1;
        Eleks[1].X = (float)Math.Cos(geschw + Math.PI);   //Pi = 180Grad
        Eleks[1].Y = (float)Math.Sin(geschw + Math.PI);   //also genau gegenüber

        Eleks[2].X = (float)cosinus * Schale2;
        Eleks[2].Y = (float)sinus * Schale2;
        for (i = 3; i < 10; i++)
        {
                Eleks[i].X = (float)Math.Cos(geschw + Math.PI / 3) * Schale2;
                Eleks[i].Y = (float)Math.Sin(geschw + Math.PI / 3) * Schale2;
        }

        Eleks[10].X = (float)cosinus * Schale3;
        Eleks[10].Y = (float)sinus * Schale3;
        for (i = 11; i < 14; i++)
        {
            Eleks[i].X = (float)Math.Cos(geschw + Math.PI / 4) * Schale3;
            Eleks[i].Y = (float)Math.Sin(geschw + Math.PI / 4) * Schale3;
        }

        device.BeginScene();
        //device.Transform.World = Matrix.Translation(0f,0f,0f);
        //Nullpunkt.DrawSubset(0);
        //Atomkern - Proton
        mtrl.Diffuse = mtrl.Ambient = Color.Red;
        device.Material = mtrl;
        for (i=0; i<Protonen; i++)
        { device.Transform.World = Matrix.Translation(Kerne[i]); Kern.DrawSubset(0); }  //zeichnet Proton

        //Atomkern - Neutron
        mtrl.Diffuse = mtrl.Ambient = Color.Gray;
        device.Material = mtrl;
        for (i = Protonen; i < (Neutronen+Protonen); i++)
        { device.Transform.World = Matrix.Translation(Kerne[i]); Kern.DrawSubset(0); }  //zeichnet Neutron

        //Schale 1 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Blue;
        device.Material = mtrl;
        for (i = 0; i < 2; i++)
        {            
            mElektron = Matrix.Translation(new Vector3(Eleks[i].X, Eleks[i].Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);   //zeichnet Elektronen der 1. Schale
        } 

        //Schale 2 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Yellow;
        device.Material = mtrl;
        for (i = 2; i < 10; i++)
        {
            mElektron = Matrix.Translation(new Vector3(Eleks[i].X, Eleks[i].Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);   //zeichnet Elektronen der 2. Schale
        }

        //Schale 3 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Cyan;
        device.Material = mtrl;
        for (i = 10; i < 14; i++)
        {
            mElektron = Matrix.Translation(new Vector3(Eleks[i].X, Eleks[i].Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);   //zeichnet Elektronen der 3. Schale
        }

        device.EndScene();  //Zeichnen beenden
        device.Present(); //Leinwand/Canvas anzeigen
    }
}

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Angel_de,

hm, das ganze Programm wird sicher deutlich übersichtlicher, wenn du die Berechnungen mit Polarkoordinaten machst und diese erst fürs Zeichnen in rechtwinklige Koordinaten umrechnest. Wenn du dann noch eine eigene Klasse PolarKoordinate verwendest, in der der ganze Sinus-Krams gekapselt ist, sollte anschließend auch keine Fehler mehr drin oder diese zumindest leicht zu finden sein.

herbivore

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

hab schon immer so meine Probleme mit der Mathematik gehabt.

hab mir eben mal http://de.wikipedia.org/wiki/Polarkoordinaten durchgelesen.

versuche da mal durchzusteigen und das auszulagern ... bin für jede weitere Hilfe dankbar ...

bin zu allem überfluß jetzt noch krank geworden und die Sache muss bald fertig werden 😦 ich hasse Zeitdruck

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Angel_de,

Polarkoordinaten bestimmen einen Punkt einfach durch einen Winkel und die Entfernung vom Ursprung. Da dein Radius für jede Kugel ja konstant bleibt, kannst du die Kugen durch reines Erhöhen des Winkels bewegen. Also super simpel.

Zum Zeichnen, musst dazu nur in der Klasse Polarkoordinate die Umrechnung in rechtwinklige Koordinaten implementieren (ein Zweizeiler, soweit ich das überblicke), d.h. im ganzen restlichen Programm kommst du ohne Sin/Cos aus.

herbivore

564 Beiträge seit 2006
vor 17 Jahren

hi angel-de!

das ist die Umrechnung von Polarkoordinaten zu kartesischen Koordinaten:

x = R * cos(phi)
y = R * sin(phi)

R ... Radius
phi ... Winkel

😉

der Marcel

:] 😄Der größte Fehler eines modernen Computers sitzt meist davor 😁 :]

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

@ Marcel .. so viel hab ich dann auch verstanden 🙂 Trotzdem danke.

Also von der extra Klasse hab ich jetzt erstmal abstand genommen. Fühl mich da grad zu blöd für.

Hab jetzt nochmal versucht das von vorne zu schreiben ... jetzt ist natürlich die Bewegung erstmal hinüber ... aber selbst die starren Kugeln sind nicht gleich verteilt ... wo ist mein Denkfehler ?


winkel = 360 / EleksSchale2;
        for (i = 1; i <= EleksSchale2; i++)
        {
            winkel += winkel;
            X = Schale2 * (float)(Math.Cos(winkel));
            Y = Schale2 * (float)(Math.Sin(winkel));
            mElektron = Matrix.Translation(new Vector3(X, Y, 0f));
            device.Transform.World = mElektron; Elektron.DrawSubset(0);
        }

In EleksSchale2 steht 8 (8 Elektronen auf der zweiten Schale.

Er zeichnet zwar 8 Kugeln, aber alles andere als gleichverteilt. Die Gleichverteilung müßte eigentlich doch durch das kontinuierliche weitergehen des winkels in gleichen schritten zustandekommen, oder ?

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Angel_de,

durch winkel += winkel steigt der Winkel auch nicht gleichmäßig, sondern verdoppelt sich immer. Vielleicht meinst bestimmt sowas wie aktWinkel += winkel;

herbivore

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

das ändert leider nicht viel 😦 hab hier mal nen screenshot gemacht :


//Schale 2 - Elektronen
        mtrl.Diffuse = mtrl.Ambient = Color.Yellow;
        device.Material = mtrl;
        try
        {
            winkel = 360 / EleksSchale2;
            for (i = 1; i <= EleksSchale2; i++)
            {
                aktwinkel += winkel;
                X = Schale2 * (float)(Math.Cos(aktwinkel));
                Y = Schale2 * (float)(Math.Sin(aktwinkel));
                mElektron = Matrix.Translation(new Vector3(X, Y, 0f));
                device.Transform.World = mElektron; Elektron.DrawSubset(0);
            }
        }
        catch (DivideByZeroException) { }

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

Ihr wisst auch nicht weiter, oder? Ich versteh's einfach nicht, warum die Verteilung der Punkt so ist, wie sie gerade ist.

Die Drehung des ganzen hab ich jetzt auch wieder drin.


X = Schale1 * (float)(Math.Cos(schritt + aktwinkel));
Y = Schale1 * (float)(Math.Sin(schritt + aktwinkel));

Aber die Verteilung ist noch nicht 100%ig 😦

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Angel_de,

bei Math.Sin & Co musst du den Winkel im Bogenmaß und nicht in Grad angeben.

herbivore

A
Angel_de Themenstarter:in
17 Beiträge seit 2006
vor 17 Jahren

herbivore ... du bist ab jetzt mein persönlicher Held und ich werde meinen Erstgeborenen nach dir benennen !!

Jetzt ist alles schön ... herrlich ... zurücklehn&genieß