Skip to content
Snippets Groups Projects
Select Git revision
  • aeadb66c6d0dad0f3bff78acbb0c79ea05d061d4
  • master default protected
  • 2018ws
  • 2017ws
  • 2016ws
5 results

pendulum-3.c

Blame
  • Forked from Peter Gerwinski / hp
    281 commits behind the upstream repository.
    pendulum-3.c 2.29 KiB
    #include <gtk/gtk.h>
    #include <math.h>
    
    #define WIDTH 320
    #define HEIGHT 240
    #define GAP (HEIGHT / 20)
    #define r GAP
    #define visual_length (HEIGHT - 2 * GAP - r)
    
    #define phi0 (-0.5)
    #define omega0 0.0
    #define t0 0.0
    #define g 9.81
    #define l 1.0
    #define dt 0.02
    
    double t = t0;
    double phi_with_sin = phi0;
    double omega_with_sin= omega0;
    double phi_without_sin = phi0;
    double omega_without_sin= omega0;
    
    void draw_pendulum (cairo_t *c, double phi, GdkRGBA *colour)
    {
      int x = WIDTH / 2 + visual_length * sin (phi);
      int y = GAP + visual_length * cos (phi);
    
      gdk_cairo_set_source_rgba (c, colour);
      cairo_move_to (c, WIDTH / 2, 10);
      cairo_line_to (c, x, y);
      cairo_stroke (c);
      cairo_arc (c, x, y, r, 0, 2 * G_PI);
      cairo_fill (c);
    }
    
    gboolean draw (GtkWidget *widget, cairo_t *c, gpointer data)
    {
      GdkRGBA blue   = { 0.0, 0.5, 1.0, 1.0 };
      GdkRGBA orange = { 1.0, 0.5, 0.0, 1.0 };
      GdkRGBA green  = { 0.0, 0.5, 0.0, 1.0 };
    
      double A = phi0;
      double B = 0.5 * M_PI;  /* 90° */
      double phi_analytic = A * sin (sqrt (g / l) * t + B);
    
      draw_pendulum (c, phi_with_sin, &blue);
      draw_pendulum (c, phi_without_sin, &orange);
      draw_pendulum (c, phi_analytic, &green);
    
      return FALSE;  /* TRUE to stop other handlers from being invoked for the event.
                        FALSE to propagate the event further. */
    }
    
    gboolean timer (GtkWidget *widget)
    {
      t += dt;
      phi_with_sin += omega_with_sin * dt;
      omega_with_sin += - dt * g / l * sin (phi_with_sin);
      phi_without_sin += omega_without_sin * dt;
      omega_without_sin += - dt * g / l * phi_without_sin;
    
      gtk_widget_queue_draw_area (widget, 0, 0, WIDTH, HEIGHT);
      g_timeout_add (50, (GSourceFunc) timer, widget);
      return FALSE;
    }
    
    int main (int argc, char **argv)
    {
      gtk_init (&argc, &argv);
    
      GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
      gtk_widget_show (window);
      gtk_window_set_title (GTK_WINDOW (window), "Hello");
      g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    
      GtkWidget *drawing_area = gtk_drawing_area_new ();
      gtk_widget_show (drawing_area);
      gtk_container_add (GTK_CONTAINER (window), drawing_area);
      gtk_widget_set_size_request (drawing_area, WIDTH, HEIGHT);
      g_signal_connect (drawing_area, "draw", G_CALLBACK (draw), NULL);
    
      g_timeout_add (50, (GSourceFunc) timer, drawing_area);
    
      gtk_main ();
      return 0;
    }