Pendulum

From JSXGraph Wiki

Simple Pendulum with Damping

The JavaScript code

var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-9, 9, 9, -12], keepaspectratio: true, false: true, grid: true}),
    p1 = board.create('point', [0.0, 0.0], {visible:false, name: 'a', size: 3}),
    c1 = board.create('circle', [p1, [0,8]], {visible:false, name: 'circle', size: 3}),
    p2 = board.create('glider', [3,-4, c1], {visible: true, name: '', size: 3}),
    grr=board.create('functiongraph', [function(t){ return -10-2*Math.cos(t/2); },-10, 10],{strokeColor: "#cccccc"}),
    p3 = board.create('point', [
                function(){return 2*Math.atan2(p2.X(),-p2.Y())},
                function(){return -10-2*Math.cos(Math.atan2(p2.X(),-p2.Y()))}], 
                {visible: true, name:'', size: 3}),
    line = board.create('line', [p1, p2], {visible:true, straightFirst: false,straightLast: false}),
    isInDragMode = false;

var gg =  board.create('slider',[[-6,6],[-3,6],[1,9.8,10]]); board.create('text',[-8,6,'gravity']);
var cc =  board.create('slider',[[3,6],[6,6],[0.1,0.5,1]]); board.create('text',[1,6,'damping']);

function startAnimation(start_theta) {
 var c = cc.Value(), g = gg.Value(), l = 10;
    p2.moveAlong(function() {
        var f = function(t, x) {
                return [x[1], -c * x[1] - g / l * (Math.sin(x[0]))];
            },
            area = [0, 200],
            numberOfEvaluations = (area[1] - area[0]) * 100,
            data = JXG.Math.Numerics.rungeKutta('heun', [start_theta, 0], area, numberOfEvaluations, f),
            duration = 20 * 1e3;
   
        return function(t) {
            if (t >= duration)
                return NaN;
            angle2=-Math.PI/2+data[Math.floor(t / duration * numberOfEvaluations)][0];
            return [p1.X()+l*Math.cos(angle2),p1.Y()+l*Math.sin(angle2)];
        };
    }());
}

function hook() {
    if(!isInDragMode) {
        if(board.mode === board.BOARD_MODE_DRAG) {
            board.stopAllAnimation();
            isInDragMode = true;
        }
    }
    if(isInDragMode) {
        if(board.mode !== board.BOARD_MODE_DRAG) {
            isInDragMode = false;
            angle=Math.atan2(p2.Y()-p1.Y(),p2.X()-p1.X())+Math.PI*1/2;
            startAnimation(angle);
        }
    }
}

board.addHook(hook);
startAnimation(-1.2);