Skip to content

Commit 353fc21

Browse files
authored
Merge pull request #295 from joaomenkdev-cloud/feat/double-pendulum
2 parents cefb60b + c368d33 commit 353fc21

4 files changed

Lines changed: 524 additions & 0 deletions

File tree

app/(core)/data/chapters.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ const chapters = [
9797
tags: [TAGS.MEDIUM, TAGS.DYNAMICS, TAGS.SPRINGS, TAGS.OSCILLATIONS],
9898
icon: "/icons/spring.png",
9999
},
100+
{
101+
id: 12,
102+
name: "Double Pendulum",
103+
desc: "Simulate a double pendulum and explore chaotic motion. Watch how small changes in initial conditions lead to completely different trajectories — a classic example of chaos theory.",
104+
link: "/simulations/DoublePendulum",
105+
tags: [TAGS.ADVANCED, TAGS.DYNAMICS, TAGS.OSCILLATIONS, TAGS.ENERGY],
106+
icon: "/icons/pendulam.png",
107+
},
100108
{
101109
id: 0,
102110
name: "Browser Performance & Stress Test",
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// app/(core)/data/configs/DoublePendulum.js
2+
3+
export const INITIAL_INPUTS = {
4+
length1: 2,
5+
length2: 2,
6+
mass1: 1,
7+
mass2: 1,
8+
gravity: 9.81,
9+
damping: 0,
10+
initialAngle1: 90,
11+
initialAngle2: 90,
12+
trailEnabled: true,
13+
bob1Color: "#3b82f6",
14+
bob2Color: "#ef4444",
15+
ropeColor: "#9ca3af",
16+
};
17+
18+
export const INPUT_FIELDS = [
19+
{
20+
name: "length1",
21+
label: "Length 1 (m)",
22+
type: "number",
23+
min: 0.5,
24+
max: 4,
25+
step: 0.1,
26+
},
27+
{
28+
name: "length2",
29+
label: "Length 2 (m)",
30+
type: "number",
31+
min: 0.5,
32+
max: 4,
33+
step: 0.1,
34+
},
35+
{
36+
name: "mass1",
37+
label: "Mass 1 (kg)",
38+
type: "number",
39+
min: 0.1,
40+
max: 5,
41+
step: 0.1,
42+
},
43+
{
44+
name: "mass2",
45+
label: "Mass 2 (kg)",
46+
type: "number",
47+
min: 0.1,
48+
max: 5,
49+
step: 0.1,
50+
},
51+
{
52+
name: "gravity",
53+
label: "Gravity (m/s²)",
54+
type: "number",
55+
min: 1,
56+
max: 20,
57+
step: 0.1,
58+
},
59+
{
60+
name: "damping",
61+
label: "Damping",
62+
type: "number",
63+
min: 0,
64+
max: 1,
65+
step: 0.01,
66+
},
67+
{
68+
name: "initialAngle1",
69+
label: "Initial Angle 1 (°)",
70+
type: "number",
71+
min: -180,
72+
max: 180,
73+
step: 1,
74+
},
75+
{
76+
name: "initialAngle2",
77+
label: "Initial Angle 2 (°)",
78+
type: "number",
79+
min: -180,
80+
max: 180,
81+
step: 1,
82+
},
83+
{
84+
name: "trailEnabled",
85+
label: "Show Trail",
86+
type: "checkbox",
87+
},
88+
{
89+
name: "bob1Color",
90+
label: "Bob 1 Color",
91+
type: "color",
92+
},
93+
{
94+
name: "bob2Color",
95+
label: "Bob 2 Color",
96+
type: "color",
97+
},
98+
{
99+
name: "ropeColor",
100+
label: "Rope Color",
101+
type: "color",
102+
},
103+
];
104+
105+
export const SimInfoMapper = (bodyState) => {
106+
const angle1 = (bodyState.angle1 * 180) / Math.PI;
107+
const angle2 = (bodyState.angle2 * 180) / Math.PI;
108+
109+
return {
110+
"Angle 1": `${angle1.toFixed(1)}°`,
111+
"Angle 2": `${angle2.toFixed(1)}°`,
112+
"Angular Vel 1": `${bodyState.angularVel1.toFixed(2)} rad/s`,
113+
"Angular Vel 2": `${bodyState.angularVel2.toFixed(2)} rad/s`,
114+
KE: `${bodyState.kineticEnergy.toFixed(2)} J`,
115+
PE: `${bodyState.potentialEnergy.toFixed(2)} J`,
116+
"Total E": `${(bodyState.kineticEnergy + bodyState.potentialEnergy).toFixed(2)} J`,
117+
};
118+
};

routes.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,10 @@ export const routes = [
6363
changefreq: "weekly",
6464
priority: 0.7,
6565
},
66+
{
67+
path: "/simulations/DoublePendulum",
68+
component: "DoublePendulum",
69+
changefreq: "weekly",
70+
priority: 0.7,
71+
},
6672
];

0 commit comments

Comments
 (0)