Geschwindigkeit eines sich bewegenden Kreises

erazor2106

Bekanntes Mitglied
Hallo,

kurz zur Problembeschreibung. Ich habe einen einfach großen Kreis gezeichnet welcher die Erde darstellen soll. Ich möchte nun in meinem Programm erreichen dass sich ein kleiner Kreis scheinbar um diese Erde dreht, wie z.b. ein Satellit.

Dies habe ich bereits erreicht indem ich den Kreis zeichne und dann mit einer Verzögerung den gleichen Kreis nur ein paar Pixel weiter rechts bzw. links. Dies habe ich übrigens mit Thread.sleep umgesetzt.

Mein Problem ist nun dass das ganze nicht nach einer Umkreisung aussieht weil ich es bisher nur so gemacht habe dass der Punkt wenn er auf seiner geradlinigen Bahn rechts den Rand berührt, er sich nun nach links an den linken Rand bewegen soll. Das klappt auch wunderbar, nur sieht das eher wie Ping Pong aus. Um einen 3D-Effekt zu erhalten müsste der Kreis ganz in der Nähe des Randes des großen Kreises langsamer werden, damit man das Gefühl hat er bewegt sich gerade über den nicht sichtbaren Teil der Erde. Befindet sich der Kreis nun scheinbar hinter der Erde soll seine Geschwindigkeit wieder so sein als würde er sich vor der Erde bewegen, da diese hier "durchsichtig" ist.

Habt ihr da vllt. eine Idee wie man so eine geschwindigkeitssteuerung in abhängigkeit der kreisbreite erstellen kann?

VIelen Dank schonmal
 
ein Kreis ist gar kein Kreis wenn man nicht auch sofort an Sinus/ Kosinus denkt, davon noch nie gehört?
damit geht so vieles, hier hilft es auch genau weiter

schau dir eine Sinus-Schwingung an:
Sinus und Kosinus ? Wikipedia

im Bereich von 0, PI usw. ist die Bewegung hoch, die Steigung gleichmäßig, das ist die Bewegung 'nicht am Rand' sondern in der Mitte,
bei pi/2 ist die Bewegung fast 0 bzw. dreht sich in Gegenrichtung, das entspricht genau der benötigten Verlangsamung und der Umkehr,
es ist eben exakt die richtige Originalbewegung,

wie du das ganze in dein Programm bekommst ist noch eine Menge Arbeit,
Bogenmaß/ Gradmaß bedenken, deine Zeit- und Raumkoordinanten passend umrechnen
aber letztlich ist entscheidend: Math.sin() und/oder Math.cos() müssen in deine Berechnungen rein

edit:
komisch dass sich dazu nicht sofort eine Seite mit direkter Beschreibung finden läßt, am ehesten auf die Schnelle:
Galileo Design :: Einstieg in ActionScript – 11.2 Bögen und Trigonometrie
 
Zuletzt bearbeitet von einem Moderator:
Hier mal das aktuelle Programm. Und bevor wieder jede Menge Kritik kommt, ich weiß dass da einiges nicht so toll ist. Es ist ja auch noch in der Entwicklung 😀

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

 public class Kugel extends Frame implements Runnable
 {
   private Thread th;
   public int actx1;
   public int actx2;
   public int actx3;
   public int actx4;
   public int actx5;
   public int actx6;
   public int actx7;
   public int actx8;
   public int actx9;
   public int actx10;
   public int actx11;
   public int actx12;
   public int actx13;
   public int actx14;
   public int actx15;
   public int actx16;
   public int actx17;
   public int actx18;
   public int actx19;
   public int actx20;
   public int actx21;
   public int actx22;
   public int actx23;
   public int actx24;
   public int actx25;
   public int actx26;
   public int actx27;
   public int actx28;
   public int actx29;
   public int actx30;
   public int actx31;
   public int actx32;
   public int actx33;
   public int actx34;
   public int actx35;
   public int actx36;
   public int actx37;
   public int actx38;
   public int actx39;
   public int actx40;

   public int dx1;
   public int dx2;
   public int dx3;
   public int dx4;
   public int dx5;
   public int dx6;
   public int dx7;
   public int dx8;
   public int dx9;
   public int dx10;
   public int dx11;
   public int dx12;
   public int dx13;
   public int dx14;
   public int dx15;
   public int dx16;
   public int dx17;
   public int dx18;
   public int dx19;
   public int dx20;
   public int dx21;
   public int dx22;
   public int dx23;
   public int dx24;
   public int dx25;
   public int dx26;
   public int dx27;
   public int dx28;
   public int dx29;
   public int dx30;
   public int dx31;
   public int dx32;
   public int dx33;
   public int dx34;
   public int dx35;
   public int dx36;
   public int dx37;
   public int dx38;
   public int dx39;
   public int dx40;
   
   public int xoffs = 60;
   public int yoffs = 60;
   public int breiteOst = 100;
   public int KreisBreite = 20;

   private Image dbImage;
   private Graphics dbGraphics;

   public JPanel panelOst;
   public JPanel panelWest;
   public JPanel panelZentrum;

//---------------------------------
   public Kugel()
   {
      super("Kugel");
      
        this.setBounds(0, 0, 850, 850);
        this.setLocationRelativeTo(null);

     // --- NORDEN ---
        JPanel panel = new JPanel();
        panel.setBackground(Color.red);
        this.add(panel, BorderLayout.NORTH);

    // --- SÜDEN ---
        panel = new JPanel();
        panel.setBackground(Color.BLUE);
        this.add(panel, BorderLayout.SOUTH);

    // --- OSTEN ---
        panelOst = new JPanel();
        panelOst.setLayout(null);
        panelOst.setBackground(Color.GREEN);
        panelOst.setPreferredSize(new Dimension(breiteOst, 900));
        panelOst.setVisible(true);
        this.add(panelOst, BorderLayout.EAST);

    // --- WESTEN ---
        panelWest = new JPanel();
        panelWest.setLayout(null);
        panelWest.setBackground(Color.YELLOW);
        panelWest.setPreferredSize(new Dimension(327, 1100));
        this.add(panelWest, BorderLayout.WEST);

      addWindowListener(
         new WindowAdapter() {
            public void windowClosing(WindowEvent event)
            {
               if (th != null) {
                  th.stop();
                  th = null;
               }
               setVisible(false);
               dispose();
               System.exit(0);
            }
         }
      );
      
        setResizable(true);
        setVisible(true);
   }

// -----------------------------------------------------------------------------------

   public void startAnimation()
   {
      Thread th = new Thread(this);
      th.start();
   }

// -----------------------------------------------------------------------------------

   public void run()
   {
      actx1 = 0;
      actx2 = 0;
      actx3 = 0;
      actx4 = 0;
      actx5 = 0;
      actx6 = 0;
      actx7 = 0;
      actx8 = 0;
      actx9 = 0;
      actx10 = 0;
      actx11 = 0;
      actx12 = 0;
      actx13 = 0;
      actx14 = 0;
      actx15 = 0;
      actx16 = 0;
      actx17 = 0;
      actx18 = 0;
      actx19 = 0;
      actx20 = 0;
      actx21 = 0;
      actx22 = 0;
      actx23 = 0;
      actx24 = 0;
      actx25 = 0;
      actx26 = 0;
      actx27 = 0;
      actx28 = 0;
      actx29 = 0;
      actx30 = 0;
      actx31 = 0;
      actx32 = 0;
      actx33 = 0;
      actx34 = 0;
      actx35 = 0;
      actx36 = 0;
      actx37 = 0;
      actx38 = 0;
      actx39 = 0;
      actx40 = 0;
      
      dx1 = 1;
      dx2 = 1;
      dx3 = 1;
      dx4 = 1;
      dx5 = 1;
      dx6 = 1;
      dx7 = 1;
      dx8 = 1;
      dx9 = 1;
      dx10 = 1;
      dx11 = 1;
      dx12 = 1;
      dx13 = 1;
      dx14 = 1;
      dx15 = 1;
      dx16 = 1;
      dx17 = 1;
      dx18 = 1;
      dx19 = 1;
      dx20 = 1;
      dx21 = 1;
      dx22 = 1;
      dx23 = 1;
      dx24 = 1;
      dx25 = 1;
      dx26 = 1;
      dx27 = 1;
      dx28 = 1;
      dx29 = 1;
      dx30 = 1;
      dx31 = 1;
      dx32 = 1;
      dx33 = 1;
      dx34 = 1;
      dx35 = 1;
      dx36 = 1;
      dx37 = 1;
      dx38 = 1;
      dx39 = 1;
      dx40 = 1;
      

      while (true)
       {
        repaint();
         
         actx1 = actx1 + dx1;
         actx2 = actx2 + 2*dx2;
         actx3 = actx3 + 3*dx3;
         actx4 = actx4 + 4*dx4;
         
         actx5 = actx5 + dx5;
         actx6 = actx6 + 2*dx6;
         actx7 = actx7 + 3*dx7;
         actx8 = actx8 + 4*dx8;
         
         actx9  = actx9  + dx9;
         actx10 = actx10 + 2*dx10;
         actx11 = actx11 + 3*dx11;
         actx12 = actx12 + 4*dx12;
         
         actx13 = actx13 + dx13;
         actx14 = actx14 + 2*dx14;
         actx15 = actx15 + 2*dx15;
         actx16 = actx16 + 2*dx16;
         
         actx17 = actx17 + 2*dx17;
         actx18 = actx18 + 2*dx18;
         actx19 = actx19 + 2*dx19;
         

       //--------- Versuch die Geschwindikeit der untersten (20-ten) Kugel zu regulieren----------------
         int zahl = 50;
         int laenge20 = 617;
           
         if ( (actx20 > -2 && actx20 < (laenge20 - Math.round(laenge20*15/15)))  || (actx20 > 521 && actx20 < 623) )
          {
             actx20 = actx20 + dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*15/15))-1 && actx20 < (laenge20 - Math.round(laenge20*14/15) - 20) )
          {
             actx20 = actx20 + 2*dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*14/15))-21 && actx20 < (laenge20 - Math.round(laenge20*13/15)) )
          {
             actx20 = actx20 + 3*dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*13/15))-1 && actx20 < (laenge20 - Math.round(laenge20*12/15)))
          {
             actx20 = actx20 + 4*dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*12/15))-1 && actx20 < (laenge20 - Math.round(laenge20*11/15)) )
          {
             actx20 = actx20 + 5*dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*11/15))-1 && actx20 < (laenge20 - Math.round(laenge20*10/15)) )
          {
             actx20 = actx20 + 6*dx20;
          }
         else if (actx20 > (laenge20 - Math.round(laenge20*10/15))-1 && actx20 < (laenge20 - Math.round(laenge20*9/15)) )
          {
             actx20 = actx20 + 7*dx20;
          }
         else if ( actx20 > (laenge20 - Math.round(laenge20*9/15))-1  && actx20 < 618)//(laenge20 - Math.round(laenge20*6/15)) )
          {
             actx20 = actx20 + 8*dx20;
          }


//--------------- rot ---------
         if (actx1 < 0 || actx1 > 460)
          {
            dx1 = -dx1;
          }

         if (actx2 < 0 || actx2 > 555)
          {
            dx2 = -dx2;
          }
          
         if (actx3 < 0 || actx3 > 610)
          {
            dx3 = -dx3;
          }

         if (actx4 < 0 || actx4 > 630)
          {
            dx4 = -dx4;
          }

//--------------- blau ---------
         if (actx5 < 0 || actx5 > 213)
          {
            dx5 = -dx5;
          }
          
         if (actx6 < 0 || actx6 > 272)
          {
            dx6 = -dx6;
          }
          
         if (actx7 < 0 || actx7 > 386)
          {
            dx7 = -dx7;
          }
          
         if (actx8 < 0 || actx8 > 454)
          {
            dx8 = -dx8;
          }

//--------------- gelb ---------
         if (actx9 < 0 || actx9 > 498)
          {
            dx9 = -dx9;
          }
          
         if (actx10 < 0 || actx10 > 518)
          {
            dx10 = -dx10;
          }

         if (actx11 < 0 || actx11 > 573)
          {
            dx11 = -dx11;
          }

         if (actx12 < 0 || actx12 > 593)
          {
            dx12 = -dx12;
          }

         if (actx13 < 0 || actx13 > 619)
          {
            dx13 = -dx13;
          }

         if (actx14 < 0 || actx14 > 628)
          {
            dx14 = -dx14;
          }

//--------------- Grau ---------

         if (actx15 < 0 || actx15 > 635)
          {
            dx15 = -dx15;
          }

         if (actx16 < 0 || actx16 > 628)
          {
            dx16 = -dx16;
          }

         if (actx17 < 0 || actx17 > 600)
          {
            dx17 = -dx17;
          }

         if (actx18 < 0 || actx18 > 613)
          {
            dx18 = -dx18;
          }

         if (actx19 < 0 || actx19 > 619)
          {
            dx19 = -dx19;
          }

         if (actx20 < 0 || actx20 > 615)
          {
            dx20 = -dx20;
          }



         try
          {
             Thread.sleep(40);            // bestimmt die Geschwindigkeit der Kugel
          }
         catch (InterruptedException e)
          {
          }

      }
   }

// -----------------------------------------------------------------------------------

   public void update(Graphics g)
   {
      //Double-Buffer initialisieren
      if (dbImage == null)
       {
          // dbImage = createImage( this.getSize().width,  this.getSize().height );
          dbImage = createImage( 700, 700 );   // bestimmt die Größe der rechteckigen Zeichenfläche auf der sich die Kugel bewegt

          dbGraphics = dbImage.getGraphics();
      }
      //Hintergrund löschen
            // dbGraphics.setColor(getBackground());
      dbGraphics.setColor(Color.GREEN);        // bestimmt die Hintergrundfarbe der zu zeichnenden Fläche

           // dbGraphics.fillRect( 0, 0, this.getSize().width, this.getSize().height );
      dbGraphics.fillRect( 0, 0, this.getSize().width, this.getSize().height );    // Größe des Rechteckts das die gemalte Kugel übermalt

      // Vordergrund zeichnen
            // dbGraphics.setColor(getForeground());
            // dbGraphics.setColor(Color.YELLOW);
      
      paint(dbGraphics);
      
      //Offscreen anzeigen
      g.drawImage(dbImage,100,100,this);    // dies legt den Platz und .... fest wo sich die Fläche im Frame befindet auf der sich die Kugel bewegt

      g.dispose();
   }


// -----------------------------------------------------------------------------------

   public void paint(Graphics g)
   {

      Graphics2D g2 = (Graphics2D) g;                  // wandeln eindimensionales Objekt in ein 2dimensionales um damit die Strichdicke geändert werden kann
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);        // dadurch werden die Kanten sauber gezeichnet ob Treppen-effekt

      g.setColor(Color.BLUE);
      g.drawOval(35,35,650,650);


      g.setColor(Color.RED);
      
      g.fillOval(xoffs+actx1+54,yoffs+70 , KreisBreite, KreisBreite);
      
      g.fillOval(xoffs+actx2+10,yoffs+140 , KreisBreite, KreisBreite);
      
      g.fillOval(xoffs+actx3-16,yoffs+210 , KreisBreite, KreisBreite);
      
      g.fillOval(xoffs+actx4-28,yoffs+280 , KreisBreite, KreisBreite);


      g.setColor(Color.BLUE);

      g.fillOval(xoffs+actx5+186,yoffs-20 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx6+153,yoffs+5 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx7+98,yoffs+30 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx8+63,yoffs+55 , KreisBreite, KreisBreite);



      g.setColor(Color.YELLOW);

      g.fillOval(xoffs+actx9+39,yoffs+90 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx10+30,yoffs+110 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx11+2,yoffs+160 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx12-10,yoffs+180 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx13-19,yoffs+230 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx14-22,yoffs+250 , KreisBreite, KreisBreite);
      
      
      
      g.setColor(Color.DARK_GRAY);

      g.fillOval(xoffs+actx15-26,yoffs+300 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx16-23,yoffs+320 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx17-2,yoffs+340 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx18-13,yoffs+360 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx19-19,yoffs+380 , KreisBreite, KreisBreite);

      g.fillOval(xoffs+actx20-22,yoffs+400 , KreisBreite, KreisBreite);
   }
   

   public static void main(String[] args)
   {
      Kugel frame = new Kugel();

      frame.startAnimation();
   }
}

Ich habe mir jetzt mal einfach die unterste Kugel genommen um an einer Geschwindigkeitssteuerung zu arbeiten. Und ja ich weiß, die dx und die actx hätte ich auch in einem Array verwenden können. ich bitte einfach mal über solche Sachen hinwegzusehen
 
:autsch: Bevor du ans weitermachen denkst: das hier lesen.
(Wobei ich nichtmal sicher bin, ob das in diesem Fall angebracht ist).

Die Bewegung so erscheinen zu lassen, wie auf einer Kreisbahn, ist eigentlich ganz einfach: Man muss sich das Objekt auf einer Kreisbahn bewegen lassen. Und bei dir würde man dann noch eine Koordinate auf einen konstanten Wert setzen.

Aber räum' erstmal auf. Das ist ja kein KSKB sondern bestenfalls ein GSKB 😉
 
Hallo Marco,

danke für den Hinweis mit den Arrays ;-)
Die vielen Variablen hatte ich aus bestimmten Gründen nicht in ein Array gepackt, deswegen hatte ich darum gebeten mal darüber hinwegzu sehen.

Dein Vorschlag mit der Kreisbahn hört sich interessant an. Könntest du mir da mal ein Beispiel für geben? Das dürfte sich nicht viel Quelltext in Anspruch nehmen.

Und sorry nochmal für das große KSKB
 
Dein Vorschlag mit der Kreisbahn hört sich interessant an. Könntest du mir da mal ein Beispiel für geben? Das dürfte sich nicht viel Quelltext in Anspruch nehmen.

Die Koordinaten eines Objektes, das sich auf einem Kreis mit Radius r um den Ursprung bewegt, sind für einen Winkel a:
x = r*cos(a)
y = r*sin(a);
Wenn y bei dir konstant ist, kommt da genau das raus, was SlaterB schon gesagt hat 😉

Java:
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;



class CircleAnim
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final AnimPanel animPanel = new AnimPanel();
                Thread t = new Thread(new Runnable()
                {
                    public void run()
                    {
                        while (true)
                        {
                            animPanel.addAlpha(0.15f);
                            try
                            {
                                Thread.sleep(30);
                            }
                            catch (InterruptedException e)
                            {
                                Thread.currentThread().interrupt();
                                return;
                            }
                        }
                    }
                });
                t.start();
                f.getContentPane().add(animPanel);
                f.setSize(200,200);
                f.setVisible(true);
            }
        });
    }
    
    private static class AnimPanel extends JPanel
    {
        private float alpha = 0;
        private int radius = 50;
        
        public void addAlpha(float da)
        {
            alpha += da;
            repaint();
        }
        
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            
            int x = (int)(Math.cos(alpha)*radius);
            int y = (int)(Math.sin(alpha)*radius);
            
            g.fillOval(radius+10+x-4, radius+10+y-4, 8, 8);
            g.fillOval(radius+10+x-4, radius+radius+10-4, 8, 8);
        }
        
    }
}
 

Zurück
Oben