# C# XNA Elasticity Behavior

What is elasticity? How do I implement such a thing?

• Are you talking physics? – The Communist Duck Oct 20 '10 at 18:08
• Why would you want to implement it if you don't know what it is? – Ipsquiggle Oct 20 '10 at 19:28
• @Jim, if you're going to post a huge bounty on an extremely vague and aimless question that's already been answered in the only way it can (vaguely), you might want to say why those answers aren't satisfying enough for you. – doppelgreener May 10 '12 at 11:10
• Actually based on how hugely vague this question is I'm voting to close it. "How do I implement such a thing?" cannot be reasonably answered because we don't even know in what way the asker wants to implement it - and the asker wouldn't be able to tell us since they don't know what it is! The asker does, however, presumably have some effect they want to achieve - and they should instead be asking us about that. – doppelgreener May 10 '12 at 11:12
• Additionally, since this question is the top Google result for XNA elasticity (#3 for C# elasticity), anyone looking to learn about elasticity in XNA/C# is likely to end up at this page, regardless of their prior knowledge. It would be best if they could get a meaningful answer – yoozer8 May 10 '12 at 13:36

Elasticity can be defined in two ways; either to do with physics or to do with how you move from one value to another (tweening).

# Tweening

This is used in games to move between two values - for example you might have a set of points that the game camera needs to move between over time. The simplest tween is a lerp (also known as a linear tween):

Lerp(float initial, float target, float amount) =>
initial + (amount * (target - initial))

Linear(float initial, float change, float amount) =>
initial + (amount * change)


In order to use this function you must provide it with an initial value (for example, the camera starting position), the change required to get it to the target (where you want it to move to) and how far along that line you want it to be (a value between 0 and 1 - e.g. 0.5 would be half way to the target). The result of a lerp looks like this:

An elastic tween makes the value 'bounce' at the start, the end or both (ease in, ease out and ease in out respectively).

Ease in elastic:

Ease out elastic:

Ease in out elastic:

The MCTween animation types page will let you see these as animated graphs/values.

XNATweener has an elastic tween implementation.

# Springs

An elastic band in physics is usually represented by a long chain of very short interconnected springs, that are connected using a revolute joint (you may limit the angle) and that have a very high dampening factor. This means that each spring:

• Isn't likely to bounce back and forth
• Can revolve around the connection to the next spring

The whole system behaves as follows:

• It can be used like a rope - e.g. it is flexible (due to the revolute joints)
• It will snap back to its original length if stretched

Farseer has springs.

# Elastic and Inelastic Collisions

An elastic collision is when the kinetic (movement or momentum) energy of colliding bodies remains the same after a collision (it can still be distributed differently between the bodies). This means that no energy is lost to other forms of energy (for example, sound, heat and light). Elastic collisions (or "super-elastic", where the energy is greater) only happen at the molecular level - however elastic collisions can be passable in games.

An inelastic collision is when a portion of the kinetic energy is converted to other forms of energy. For example, when two billiard balls collide you hear a sound (although this does have a negligible impact on the total momentum). If a car collides with another one a lot of energy is lost to deformation and heat. At the macro-scale these types of collisions are more accurate; and will generally improve the stability of your physics simulation (they reduce the chance of a rounding error or such from introducing more energy).

Wikipedia has very good articles on both elastic and inelastic collisions, Physics for Game Programmers has a free excerpt on both.

• +1 Best answer so far as it adresses both parts of the question. – ClassicThunder May 10 '12 at 17:53
• In addition to this great answer, elasticity could also refer to elastic or inelastic collisions. – Cypher Jun 22 '12 at 3:10
• @Cypher thanks a ton! I will update the answer ASAP. – Jonathan Dickinson Jun 22 '12 at 7:23

Checkout Robbert Penner's easing classes and examples. They are very easy to convert to C#.

I don't know what you mean exactly by "elasticity". If you mean rope simulation or grid/cloth simulation, here is how to proceed :

A rope/string is simply a list of points connected together with springs :

Force applied on a point depends of forces received from the two neighbours springs :

Force applied by a spring on a point is calculated like this :

F = springvector / length * (length - normal_length) * k


where :

springvector = (position of neighbour point) - (position of point)

length = actual length of spring

normal_length = default length of spring when no force is applied on it (constant)

k = spring stiffness (constant)

Now, some code :

//init points (only once)
for(int i = 0 ; i < 10 ; i++)
{
points[i].x = 0
points[i].y = i; //vertical rope
}

//each frame
for(int i = 0 ; i < 10 ; i++)
{
vec2 forcePrev = points[i - 1] - points[i];
float lengthPrev = length(forcePrev);

vec2 forceNext = points[i + 1] - points[i];
float lengthNext = length(forceNext);

vec2 totalforce = forcePrev / lengthPrev * (lengthPrev - normal_length)
+ forceNext / lengthNext * (lengthNext - normal_length);

velocity[i] = velocity[i] * 0.98 + totalforce * 0.001;
velocity[i].y += gravity;

tmp_points[i] = points[i] + velocity[i];
}
copy all points from tmp_points to points


You can also skip simulation of some points and explicity set their position if you want them to be fixed (usually first point of rope is like this).

If you want to do grid/cloth simulation, this is exactly the same thing, but instead points are arranged as a grid, and forces are received from more neighbour springs :

Here is some pseudo-code :

foreach(point in grid1)
{
vec2 totalforce = new vec2(0, 0);
foreach(neighbourpoint in point.neighbours)
{
compute force from neighbourpoint to point