How to code a swinging movement

Started by
6 comments, last by MattProductions 11 years, 11 months ago
Hi guys!


I have to built a small prototype of a concept my team came up with.
I'm having some issues on letting to spider swing it's web.

So how can I code a swinging movement of a spider with a web attached to a fixed point?
It has to swing a few times, before losing it's velocity and then hanging still.

This may sound a bit confusing, but this "drawing" should make it clear.
2qx0oli.jpg

Many thanks in advance!


(This would have been better in the Math & Physics forum...)
Advertisement
This is basically a pendulum:

If you look at:

http://en.wikipedia.org/wiki/Pendulum_%28mathematics%29

you'll see that the angle(in radians) between the spider and the anchor point at a given time is:

angle = initialAngle * cos(sqrt(gravity/length)*time)

That formula is reasonably accurate as long as the initial angle is below 1 radian. (around 57 degrees)

the position of the spider is then x=cos(angle), y=sin(angle) and you can simply reduce the initial angle in that calculation to reduce the amplitude of the swing. (Not physically accurate but it should work well enough for your situation).

another option is to use a proper physics model but it is quite a bit more complicated.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
[font=arial,helvetica,sans-serif]If you want to slowly reduce the peak height, you could always do something like intialAngle *= friction, to decrease the max height geometrically.[/font]
what
An even better solution would be to use a 2d physics engine. Then, you would just attach an object (the spider) to a constraint, which would be attached to the static object as the fixed point. Give the spider some values (mass, friction, and starting location), apply gravity, and watch the engine do all the work for you.

I personally use chipmunk-physics, but box2d is a popular one as well (google them).

Here's a video of the chipmunk-physics engine at work, You'd be using the most basic one, the pin joint (used 1st):

#!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

You can write a simple verlet integrator, which will allow you to do many more fun things easily (this is the home-made version of using a 2D Physics engine).

#include <iostream>
#include <cmath>

float const degrees = std::atan(1.0f)/45.0f;

struct Vector2D {
float x, y;
Vector2D(float x, float y) : x(x), y(y) {
}
};

std::ostream &operator<<(std::ostream &os, Vector2D v) {
return os << '(' << v.x << ',' << v.y << ')';
}

Vector2D operator+(Vector2D v, Vector2D w) {
return Vector2D(v.x+w.x, v.y+w.y);
}

Vector2D operator-(Vector2D v, Vector2D w) {
return Vector2D(v.x-w.x, v.y-w.y);
}

Vector2D operator*(Vector2D v, float s) {
return Vector2D(v.x*s, v.y*s);
}

float length(Vector2D v) {
return std::sqrt(v.x*v.x+v.y*v.y);
}

int main() {
float const dt = 0.01f; // (s) (100 Hz simulation)
float const dt_squared = dt*dt;
float length_of_string = 0.1f; // (m)
float gravity = 9.81f; // (m/s^2)
float friction = 1.5f; // (s^-1), I believe, but you better ask a Physicist if you care ;)
float friction_coef = std::exp(-friction*dt);
float alpha = 15.0f*degrees;
Vector2D position(length_of_string*std::sin(alpha), -length_of_string*std::cos(alpha));
Vector2D previous_position = position;
Vector2D acceleration(0.0f, -gravity);

// For 10 seconds
for (float t = 0; t < 10.0; t += dt) {
// Verlet integration
Vector2D next_position = position + (position - previous_position) * friction_coef + acceleration * dt_squared;

// Constrain the point to be at the desired length from the origin
next_position = next_position * (length_of_string / length(next_position));

// Update
previous_position = position;
position = next_position;

// Output
std::cout << t << ' ' << position << '\n';
}
}

Hurray!

Thanks to you guys, it works now!
So... What solution did you go with?
I used SimonForsman's solution.
It was the easiest one the implement (just for a prototype).

Thanks!

This topic is closed to new replies.

Advertisement