Blame c/gtk3/gravity-control/gravitycontrol.c

757b35
#include <math.h></math.h>
757b35
#include <stdlib.h></stdlib.h>
757b35
#include <time.h></time.h>
757b35
#include <gtk gtk.h=""></gtk>
757b35
757b35
757b35
const double pi = 3.141592653589793;
757b35
757b35
const guint interval_ms = 5;
757b35
const guint interval2_ms = 50;
757b35
const double G = 1000000;
757b35
const double radius = 30;
757b35
757b35
int width = 700;
757b35
int height = 500;
757b35
757b35
double mx = 0;
757b35
double my = 0;
757b35
double x = 200;
757b35
double y = 200;
757b35
double vx = 0;
757b35
double vy = 0;
757b35
757b35
GtkWidget *window;
757b35
757b35
757b35
gboolean motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
757b35
  mx = event->x;
757b35
  my = event->y;
757b35
  return TRUE;
757b35
}
757b35
757b35
gboolean timeout(gpointer data) {
757b35
  double t = interval_ms/1000.0;
757b35
757b35
  double dx = mx - x;
757b35
  double dy = my - y;
757b35
  double d = sqrt(dx*dx + dy*dy);
757b35
757b35
  double ax = G*dx/(d*d*d);
757b35
  double ay = G*dy/(d*d*d);
757b35
  if (d < 10.0) ax = ay = 0.0;
757b35
757b35
  vx += ax*t;
757b35
  vy += ay*t;
757b35
757b35
  x += vx*t;
757b35
  y += vy*t;
757b35
  
757b35
  if (x < radius)
757b35
    { x = radius; vx = fabs(vx); }
757b35
  if (x > width - radius)
757b35
    { x = width - radius; vx = -fabs(vx); }
757b35
  if (y < radius)
757b35
    { y = radius; vy = fabs(vy); }
757b35
  if (y > height - radius)
757b35
    { y = height - radius; vy = -fabs(vy); }
757b35
  
757b35
  return TRUE;
757b35
}
757b35
757b35
gboolean timeout2(gpointer data) {
757b35
  gtk_widget_queue_draw(window);
757b35
  return TRUE;
757b35
}
757b35
757b35
gboolean draw(GtkWidget *widget, cairo_t *cr, gpointer data) {
757b35
  cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1);
757b35
  cairo_paint(cr);
757b35
757b35
  cairo_set_source_rgba(cr, 0, 0, 0, 1);
757b35
  cairo_set_line_width(cr, 1.0);
757b35
  cairo_arc(cr, x, y, radius, 0, 2*pi);
757b35
  cairo_stroke(cr);
757b35
757b35
  return TRUE;
757b35
}
757b35
757b35
void activate(GtkApplication* app, gpointer data) {
757b35
  window = gtk_application_window_new (app);
757b35
  g_signal_connect(window, "draw", G_CALLBACK(draw), NULL);
757b35
  g_signal_connect(window, "motion-notify-event", G_CALLBACK(motion), NULL);
757b35
  gtk_widget_add_events(window, GDK_POINTER_MOTION_MASK);
757b35
  gtk_window_set_default_size(GTK_WINDOW(window), width, height);
757b35
  gtk_widget_show_all(window);
757b35
757b35
  g_timeout_add(interval_ms, timeout, NULL);
757b35
  g_timeout_add(interval2_ms, timeout2, NULL);
757b35
}
757b35
757b35
int main(int argc, char **argv) {
757b35
  GtkApplication *application = gtk_application_new(NULL, 0);
757b35
  g_signal_connect(application, "activate", G_CALLBACK(activate), NULL);
757b35
  int status = g_application_run(G_APPLICATION(application), argc, argv);
757b35
  g_object_unref(application);
757b35
  return status;
757b35
}
757b35
757b35