ELASTIC STRING(S)

—————

My intended goal this week was to create a dynamic elastic; I wanted to make a band that could be stretched… and after being released… would dance a bit before eventually returning to its original form.

I approached the idea by first stripping the concept down to its most basic form… and then slowly adding new dynamics with each iteration.

—————

STEP 1 (BEZIER CURVE FOLLOWS DRAGGED MOUSE AND RETURNS TO ORIGINAL FORM UPON RELEASE)

In this sketch a vertical line appears upon loading. When you click inside the sketch the bezier (bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2)) will slowly stretch itself in the direction of the mouse coordinates. This stretching is accomplished through the custom function called linePull(). To accomplish the gradual stretching I first locked the 2 anchor points of the bezier to x1 =  width/2, y1 = height-(height*8.5/10) and x2 = width/2, y2 = height-(height*1.5/10). Next I set the 2 control points to follow mouseX and mouseY. But the trick to getting the bezier to gradually follow the mouse was to assign the mouseX and mouseY data first into a constrained variable (mX, mY) and then creating if conditionals that gradually adjusted the xPoint and yPoint variables.  These xPoint and yPoint variables were actually the drawn data points fed into the bezier function. By checking for the difference between the current mouse coordinates and the value of the control point coordinates, then dividing that difference by a factor (a variable I called cushion) and either adding or subtracting that factored difference to the control points, I was able to have the line gradually stretch in to place. To get a better grasp of the mechanics of bezier curves, I created small ellipses that represent the value of the control points (red is cx1,cy1 and green is cx2,cy2).

Now I had to create a boolean to control pull and release states. If the pull boolean was true, the line stretching would be animated. I tried putting the pull boolean inside a mouseDragged function, but for some reason it didn’t work as I expected. I switched it to a mousePressed function and it worked just fine. While the mouse was pressed the boolean would be true. If the mouse was released the boolean would be false. While false, the control points would gradually return to their original values (cx1 = width/2, cy1 = 0, cx2 = width/2, cy2 = height) using the same cushioned formula for stretching through the custom lineRelease() function.

—————

STEP 2 (BEZIER CURVE SWINGS FROM LEFT TO RIGHT UPON RELEASE WHILE GRADUALLY RETURNING TO ITS ORIGINAL FORM)

In order to get the bezier to swing from left to right I had to use the constrained mouseX coordinate to define a symmetrical point opposite its current location. The key however was to ensure that this point was not perfectly symmetrical otherwise it would never return to its original form; the symmetrical point had to be just slightly closer to center than mouseX. To do so I created a variable called swingSpeed. This variable multiplies the current mouseX by a percentage represented as a float (either 0.X to decrease its value or 1.X to increase it) and then assigns the product to either xSwingL (x point on the left side of center) or xSwingR (x point on the right side of center). Within the linePull() function I built a conditional checker to determine which side of center the bezier’s xPoint was on so that the direction boolean could be set accordingly for the eventual release of the mouse. For example, if the xPoint is on the right side of the screen, the boolean is set to false.

Once released, the program goes to a function I created called directionSwitch() that follows the bezier’s xPoint relative to its symmetrical swing point. Again using the xPoint set to the right of center as an example, the directionSwitch() function checks for the value of the xPoint relative to the point it is approaching (xSwingL). The motion between these points is produced inside the lineRelease() function using pretty much the exact same formula as that which gradually pulls the line to the mouse location. The only difference is that while xPoint is approaching xSwingL it is simultaneously and constantly setting the next symmetry point (xSwingR). When the conditional inside directionSwitch() is met (when xPoint is more or less equal to xSwingL) the boolean is flipped and xPoint approaches xSwingR while again setting xSwingL. This is repeated until the x control points settle along the center line (width/2).

—————

STEP 3 (ADD Y CONTROL POINTS THAT SWING UP AND DOWN)

Though I had great trouble creating the Y-axis physics I had hoped to achieve (I’m still working on it!) I did manage to get some motion in my Y values. It follows the same mechanics as the swinging X values only there are 2 Y control points (yPoint and yPoint0); one point should pull the line up towards the top anchor point while the other should be pull it down towards to the bottom one (hence the ySwingB and ySwingT variables). Right now the Y swing values mirror each other when they should be independent. I’ll figure it out eventually…

—————

STEP 4 (RECORD MOUSE X AND Y COORDINATES INTO AN ARRAY WHILE MOUSE IS PRESSED THEN USE THE VALUES TO DRAW MANY ELASTICS ONCE RELEASED)

I used the snake array from Learning Processing as a template. To make the arrays work I had to consolidate all of my custom functions into 2 functions (the now familiar linePull() and lineRelease()). There has to be a way to do this without sacrificing my functions but I couldn’t get there. All the mouse X and mouse Y points are assigned to 2 arrays (aX and aY) while mousePressed is active. It also records all the other important swing and direction variables into their own arrays (12 arrays in all). Then once the mouse is released these variables are fed in to the lineRelease() function which now has local variables for the first time.

—————

STEP 5 (CLEAN IT UP AND MAKE IT LOOK FANCY)

Though I am by no means done with this sketch (I still want to clean it up using object classes… fix the elastic physics while making them more dramatic… use the push/pop matrix functions to add a rotational translate to the whole elastic… and finally maybe add some sound… maybe?) I cleaned STEP 4 up in a couple of ways. First I changed the xPoint and yPoint variables in the linePull() function to GxPoint and GyPoint (G is short for Global) so that I could pass the last xPoint and yPoint from the lineRelease() function back to linePull() making the stretching animation transition smoother between release and pull. The second thing I did was to simply create some RGB variables that react to arrays aX and aY colouring the lines in a more dynamic way.

4 comments to ELASTIC STRING(S)