Baisc dynamic example
madil4 opened this issue · comments
The goal is to set up an architecture to handle dynamic simulation within Awatif. So, we will focus now on bar elements in 2D. In other iterations, we will expand to 3D bars and expose parameters for users to play with.
You can follow these guidelines if it makes sense to you but I would encourage you to improve it and make it better.
1- Setup the example: In /examples/basic-dynamic/main.ts
:
const nodes = [
[0, 0, 0],
[2, 0, 0],
[4, 0, 0],
];
const elements = [
[0, 1],
[1, 2],
];
const assignments = [
{
node: 0,
support: [true, true, true],
},
{
node: 1, // and 2 similarly
force: [0, 0, -20], // gravity force computed for masses of 2 and acceleration of 9.81
},
{
element: 0, // and 1 similarly
elasticity: 1,
},
];
const analysisResults = analyzeDynamically(nodes, elements, assignments, {
time: 5,
timeStep: 0.001,
});
app({ model: { nodes, elements, assignments, analysisResults } });
2- Write the dynamic algorithm: in /examples/basic-dynamic/analyzeDynamically.ts
export function analyzeDynamically(nodes, elements, assignments, config) {
// run the dynamic loop here
analysisResults = {
1: [ // here is the frame/step number
{
node: 0,
position: [0, 0, 0], // here is the new computed position
},
{
node: 2,
position: [0, 0, 0],
},
],
2: [
{
node: 0,
position: [0, 0, 0],
},
{
node: 2,
position: [0, 0, 0],
},
],
};
}
3- Add TimeLine component to App component: in /awatif-ui/src/App.ts
if (condition) TimeLine(modelState); // check if we have dynamic analysis results, if so, show the Timeline
4- Implement the Timeline component: in /awatif-ui/src/Timeline.ts
function TimeLine(modelState) {
const frame = van.State(0); // the frame in consideration
const isPlayed = false:
// render the slider with vanjs rendering system instead of pure html and append it to body
slider = input({ type: "range", min: "0", max: "100" });
// change the frame state according to slider.value
slider.oninput(() => {
frame.val = slider.value;
});
// change nodes positions according to frame state
van.derive(() => {
modelState.val.nodes = modelState.val.analysisResults[frame.val].position;
});
// animate slider value
setInterval(() => {
if (isPlayed) slider.val = frame.val + 1; // this assumes the steps from the analysis results are incremented by 1
}, 1000/30); // 30 fps, the animation is handled by the viewer, which is triggered when changing the position
}