Pendulum: Difference between revisions
From JSXGraph Wiki
A WASSERMANN (talk | contribs) No edit summary |
A WASSERMANN (talk | contribs) No edit summary |
||
(5 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== | ==Simple Pendulum with Damping== | ||
<jsxgraph width="800" height="600"> | <jsxgraph width="800" height="600"> | ||
var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-9, 9, 9, -12], keepaspectratio: true, false: true, grid: true}), | 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}), | 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}), | 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}), | 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"}), | 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}), | p3 = board.create('point', [ | ||
line = board.create('line', [p1, p2], {visible:true, straightFirst: false,straightLast: false}),isInDragMode = false; | 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. | 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. | var cc = board.create('slider',[[3,6],[6,6],[0.1,0.5,1]]); board.create('text',[1,6,'damping']); | ||
function startAnimation(start_theta) { | function startAnimation(start_theta) { | ||
Line 53: | Line 57: | ||
</jsxgraph> | </jsxgraph> | ||
===The JavaScript code=== | |||
<source lang="javascript"> | |||
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); | |||
</source> | |||
[[Category:Examples]] | [[Category:Examples]] | ||
[[Category:Calculus]] | [[Category:Calculus]] |
Latest revision as of 13:21, 3 March 2021
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);