Uhr pendel

wanja26

Mitglied
Hi, ich bin gerad dabei eine 2D grafische Pendel Uhr zu erstellen. Funktioniert auch soweit bei einer Periode von 1000 Millisekunden, nun möchte ich aber eine langsamere Periode haben, dass funktioniert leider nicht so wie es sein sollte. Hab zwar auch schon ne lösung dafür gefunden.

Wollte hier mal nachfragen wie ich das einfacher machen kann einfach nur die Geschwindigkeit der Pendel einstellen. Im Anhang mein Code.

Periode 1000:
Java:
public void DrawPendulum(Graphics g, double milisecond){
	   Graphics2D g2d = (Graphics2D) g;
	   
	   int pend_x = center_x;	//start of pendulum
	   int pend_y = center_y * 2; //end of pendulum
	   int pend_size = r_outer / 3; // pendulum size
	   
	   //max pendulum angle when 1 sec rad = 0.5 -->30° (Amplitude) 
	   
	   double max_angle= (Math.PI *30 / 180);/*
	   double angle = (milisecond - 500)*max_angle/500;
	   if(0 == second % 2)
		   angle = angle*-1;*/
	   
	   double angle =  max_angle * Math.sin((2 * Math.PI * (milisecond)/ 1000));
	   
	   // coordinates from pendulum circle for time t
	   pend_x +=  (int) (center_y * Math.sin(angle));
	   pend_y +=  (int) (center_y * Math.cos(angle));
	   
	 //Draw circle
	   Ellipse2D.Double pendulumCircle = new Ellipse2D.Double(pend_x - (pend_size / 2), pend_y - (pend_size / 2), pend_size, pend_size);

	   g2d.setColor(Color.gray);
	   g2d.fill(pendulumCircle);
	   g2d.draw(pendulumCircle);
	   
	   //Draw Line
	   Line2D.Double pendulum = new Line2D.Double();
	   pendulum.x1 = center_x;
	   pendulum.y1 = r_outer + center_y;
	   pendulum.x2 = pend_x;
	   pendulum.y2 = pend_y;
	   
	   System.out.println(milisecond);
	   //System.out.println(angle);
	   //System.out.println(pend_x + ", " + pend_y);
	   
	   g2d.draw(pendulum);   
   }

und Periode 2000:
Java:
public void DrawPendulum(Graphics g, double milisecond,double second){
	   Graphics2D g2d = (Graphics2D) g;
	   
	   int pend_x = center_x;	//start of pendulum
	   int pend_y = center_y * 2; //end of pendulum
	   int pend_size = r_outer / 3; // pendulum size
	   
	   //max pendulum angle when 1 sec rad = 0.5 -->30° (Amplitude) 
	   
	   double max_angle= (Math.PI *30 / 180);/*
	   double angle = (milisecond - 500)*max_angle/500;
	   if(0 == second % 2)
		   angle = angle*-1;*/
	   
	   double angle =  max_angle * Math.sin((2 * Math.PI * (milisecond)/ 2000));
	   if (0 == second % 2)
		   angle = angle * -1;
	   // coordinates from pendulum circle for time t
	   pend_x +=  (int) (center_y * Math.sin(angle));
	   pend_y +=  (int) (center_y * Math.cos(angle));
	   
	 //Draw circle
	   Ellipse2D.Double pendulumCircle = new Ellipse2D.Double(pend_x - (pend_size / 2), pend_y - (pend_size / 2), pend_size, pend_size);

	   g2d.setColor(Color.gray);
	   g2d.fill(pendulumCircle);
	   g2d.draw(pendulumCircle);
	   
	   //Draw Line
	   Line2D.Double pendulum = new Line2D.Double();
	   pendulum.x1 = center_x;
	   pendulum.y1 = r_outer + center_y;
	   pendulum.x2 = pend_x;
	   pendulum.y2 = pend_y;
	   
	   System.out.println(milisecond);
	   //System.out.println(angle);
	   //System.out.println(pend_x + ", " + pend_y);
	   
	   g2d.draw(pendulum);   
   }
 
S

SlaterB

Gast
die Berechnung ist doch quasi nur eine Zeile, Zeile 15, was soll denn da noch besser werden?
dass du für 2000 statt 1000 nicht die ganze Methode kopieren musst (übrigens klein schreiben!) sondern nur eine Variable verwenden solltest, versteht sich von selbst?

oder funktioniert genau dieser Austausch nicht?
was meinst du mit 'Hab zwar auch schon ne lösung dafür gefunden.'?
 

wanja26

Mitglied
Danke für die schnelle Antwort.

Die Methode kopiere ich natürlich nicht. Mit gelöst meinte ich für eine Periode von 2000, wenn ich jetzt aber eine Periode von 3000 haben möchte oder höher funktioniert es nicht mehr richt. Ja der Austausch funktioniert nicht richt. Am einfachsten wäre halt die eingabe über eine Geschwindigkeit.
 
S

SlaterB

Gast
also bei mir funktioniert jede Periode, wobei 3000 dann langsamer als 2000 ist,
hier ein lustiges Testprogramm das automatisch immer schneller wird

ich musste durchaus noch eine Menge ändern, vielleicht hilft dir das gerade bei deinen Überlegungen,

beim Wechsel der Geschwindigkeit springt das Pendel auf eine andere Position,
das ist korrekt, um das abzufangen müßte man den Übergang aufwendiger berechnen

bei sehr hohen Geschwindigkeiten ist die Anzeige nicht mehr allzu pendelig, aber auch kein Wunder wenn nur alle 30ms (bei mir) gezeichnet wird und in ähnlich kurzer Zeit ein ganzer Schwung durchläuft

Java:
public class TestGUI
    extends JFrame
{

    public TestGUI()
    {
        add(new P());
        setSize(350, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        for (int i = 1; i < 1000; i++)
        {
            if (i % 100 == 0)
            {
                speed /= 2;
            }
            try
            {
                Thread.sleep(30);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            repaint();
        }
    }

    long speed = 5000;
    long start = System.currentTimeMillis();

    class P
        extends JPanel
    {
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D)g;

            int center_x = 150;
            int center_y = 20;
            int r_outer = 100;

            int pend_x = center_x; // start of pendulum
            int pend_y = center_y + r_outer; // end of pendulum
            int pend_size = r_outer / 3; // pendulum size

            double max_angle = (Math.PI * 30 / 180);
            long milisecond = System.currentTimeMillis() - start;
            double angle = max_angle * Math.sin((2 * Math.PI * (milisecond) / speed));

            pend_x += (int)(r_outer * Math.sin(angle));
            pend_y += (int)(r_outer * Math.cos(angle));

            // Draw circle
            Ellipse2D.Double pendulumCircle = new Ellipse2D.Double(pend_x - (pend_size / 2), pend_y - (pend_size / 2), pend_size,
                                                                   pend_size);

            g2d.setColor(Color.gray);
            g2d.fill(pendulumCircle);
            g2d.draw(pendulumCircle);

            // Draw Line
            Line2D.Double pendulum = new Line2D.Double();
            pendulum.x1 = center_x;
            pendulum.y1 = r_outer + center_y;
            pendulum.x2 = pend_x;
            pendulum.y2 = pend_y;

            g2d.draw(pendulum);
            g2d.drawString("" + speed, 50, 50);
        }
    }

    public static void main(String[] args)   {
        new TestGUI();
    }
}

also viele x/y-Berechnungen sind geändert, angle = -angle sollte nicht nötig sein,

besonders komisch ist bei dir
> pend_x += (int) (center_y * Math.sin(angle));
> pend_y += (int) (center_y * Math.cos(angle));
kein center_x?

edit:
sehe gerade
> pendulum.y1 = r_outer + center_y;
in meinem Code, das passt mit dem Rest vielleicht nicht so zusammen,
wo das Center und wo das Pendel ist, ist vielleicht nicht ganz originalgetreu dargestellt
 
Zuletzt bearbeitet von einem Moderator:

wanja26

Mitglied
Gut versuchs mal, die center_y variable gibt die Länge des Pendels an. ist aber weiter oben im Code definiert, dieser ist hier nicht abgebildet. danke! Wenn noch was ist melde ich mich.
 

wanja26

Mitglied
Habe den Fehler gefunden, ich verwende für die variable millisecond um diese zu erhalten die calendar.get( Calendar.MILLISECOND ), hab diese jetzt geändert und holle mir die Werte über System.currentTimeMillis(). Dann funktioniert es. Auch ohne die if Anweisung
 

Neue Themen


Oben