diff --git a/experiment/newton/.gitignore b/experiment/newton/.gitignore
index ba31bf0a27bc5a896a8bd1351e44ba31e8b69ac7..6ff2e4cd4de8ffb1d3a6427db87b796f71b0aa43 100644
--- a/experiment/newton/.gitignore
+++ b/experiment/newton/.gitignore
@@ -1,2 +1,3 @@
 *.o
-newton
\ No newline at end of file
+newton
+pendulum
\ No newline at end of file
diff --git a/experiment/newton/Makefile b/experiment/newton/Makefile
index adec1dbfd2678a7fce0a8715aee9aab3d2503979..ca339506d540b1b9296677fdcc3e5b93b5e29af3 100644
--- a/experiment/newton/Makefile
+++ b/experiment/newton/Makefile
@@ -5,10 +5,13 @@ CFLAGS=-Wall -Wextra -std=gnu11 -O3
 LIBS=-lSDL2 -lm
  
 
-all: newton
+all: newton pendulum
 
 newton: newton.o gfx.o
 	$(C_GCC) $(CFLAGS) $^ -o $@ $(LIBS)
 
+pendulum: pendulum.o gfx.o
+	$(C_GCC) $(CFLAGS) $^ -o $@ $(LIBS)
+
 clean:
-	rm -f *.o gfx_example newton
+	rm -f *.o gfx_example newton pendulum
diff --git a/experiment/newton/pendulum.c b/experiment/newton/pendulum.c
new file mode 100644
index 0000000000000000000000000000000000000000..066f4b21ca0905ece935c628a2b847f86db1bc5c
--- /dev/null
+++ b/experiment/newton/pendulum.c
@@ -0,0 +1,191 @@
+#include "gfx.h"
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define GRAV 9.8
+
+typedef struct _point
+{
+  double x, y;
+} point;
+
+point point_new(double x, double y)
+{
+  point p = {x, y};
+  return p;
+}
+
+point point_from_polar(double r, double theta)
+{
+  return point_new(r * cos(theta), r * sin(theta));
+}
+
+point point_add(point lhs, point rhs)
+{
+  point res = {lhs.x + rhs.x, lhs.y + rhs.y};
+  return res;
+}
+
+point point_sub(point lhs, point rhs)
+{
+  point res = {lhs.x - rhs.x, lhs.y - rhs.y};
+  return res;
+}
+
+point point_mul(double lhs, point rhs)
+{
+  point res = {lhs * rhs.x, lhs * rhs.y};
+  return res;
+}
+
+double point_norm_sqr(point lhs)
+{
+  return lhs.x * lhs.x + lhs.y * lhs.y;
+}
+
+double point_norm(point lhs)
+{
+  return sqrt(point_norm_sqr(lhs));
+}
+
+point compute_deriv(double dt, point p, point p_1)
+{
+  return point_mul(1.0 / dt, point_sub(p, p_1));
+}
+
+point compute_force(point pos, double g, double mass)
+{
+  double angle = atan2(pos.y, pos.x);
+  double amplitude = g * mass;
+  point grav = point_new(0.0, -amplitude);
+  point string = point_from_polar(amplitude, angle);
+  return point_add(grav, string);
+}
+
+static void render_point(struct gfx_context_t *context, int x, int y, uint32_t color)
+{
+  for (int i = -2; i <= 2; ++i)
+  {
+    for (int j = -2; j <= 2; ++j)
+    {
+      gfx_putpixel(context, x + i, y + j, color);
+    }
+  }
+}
+
+/// @param context graphical context to use.
+static void render(struct gfx_context_t *context, point pos, double length)
+{
+  gfx_clear(context, COLOR_BLACK);
+  int cx = context->width / 2;
+  int cy = context->height / 2;
+  render_point(context, cx, cy, COLOR_RED);
+  int x = cx + pos.x / length * context->width / 2;
+  int y = cy + pos.y / length * context->height / 2;
+  render_point(context, x, y, COLOR_WHITE);
+
+  gfx_present(context);
+}
+
+point verlet(point p, point p_1, point a, double dt)
+{
+  return point_add(point_sub(point_mul(2.0, p), p_1), point_mul(dt * dt, a));
+}
+
+int main(int argc, char **argv)
+{
+  double mass = 0.0;
+  double length = 0.0;
+  bool debug = false;
+  if (argc == 3)
+  {
+    mass = atof(argv[1]);
+    length = atof(argv[2]);
+  }
+  else if (argc == 4)
+  {
+    mass = atof(argv[1]);
+    length = atof(argv[2]);
+    debug = (0 == strcmp("-d", argv[2]));
+  }
+  else
+  {
+    printf("Error: missing mass or length parameters.\n\
+                Normal use is: ./newton <mass> <length> -d\n\
+                where -d is for debug mode and is optional.\n\
+                The units are in IS.\n\
+                Example: ./newton 1.0 1.0\n");
+    return EXIT_FAILURE;
+  }
+  int width = 1000, height = 1000;
+  struct gfx_context_t *ctxt = gfx_create("The Pendulum", width, height);
+  if (!ctxt)
+  {
+    fprintf(stderr, "Graphics initialization failed!\n");
+    return EXIT_FAILURE;
+  }
+
+  double angle = (double)rand() / (double)RAND_MAX * 2.0 * M_PI;
+  point p = point_from_polar(length, angle);
+  point p_1 = p; // TODO: change that....
+  point p_2 = p; // TODO: change that....
+  double dt = 0.01;
+
+  struct timespec time = {0, dt * 1.0e9};
+
+  int num = 1000;
+  if (debug)
+  {
+    printf("time position velocity acceleration\n");
+  }
+  else
+  {
+    printf("time position\n");
+  }
+
+  gfx_clear(ctxt, COLOR_BLACK);
+
+  point avg_acc = point_new(0.0, 0.0);
+  for (int i = 0; i < num; ++i)
+  {
+    point vel = compute_deriv(dt, p, p_1);
+    point vel_1 = compute_deriv(dt, p_1, p_2);
+    point acc = compute_deriv(dt, vel, vel_1);
+    if (i > 0)
+    {
+      if (debug)
+      {
+        printf("t = %f, pos = (%f, %f), vel = (%f, %f), acc = (%f, %f)\n",
+               i * dt, p.x, p.y, vel.x, vel.y, acc.x, acc.y);
+      }
+      else
+      {
+        printf("%f, %f, %f\n", i * dt, p.x, p.y);
+      }
+      avg_acc = point_add(avg_acc, acc);
+    }
+    render(ctxt, p, length);
+    nanosleep(&time, NULL);
+    point p_tmp = p;
+    point new_acc = point_mul(1.0 / mass, compute_force(p, GRAV, mass));
+    p = verlet(p, p_1, new_acc, dt); // add some noise of the order of
+    p_2 = p_1;
+    p_1 = p_tmp;
+  }
+  if (debug)
+  {
+    point a = point_mul(1.0 / (num - 1), avg_acc);
+    printf("Simulation ended: avg acceleration = (%f, %f)\n", a.x, a.y);
+  }
+
+  while (gfx_keypressed() != SDLK_ESCAPE)
+  {
+  }
+
+  gfx_destroy(ctxt);
+
+  return EXIT_SUCCESS;
+}
\ No newline at end of file