How to use ofPath for folding animation

Hello!

I want to learn how to animate the folding of paper.
To start small, I have a right triangle with ofDrawTriangle(100, 100, 180, 100, 180, 160). To move it to the right, I’ve used the below code:

void ofApp::setup(){
ofBackground(255);
ofSetFrameRate(60);

int moveX = 100;
int moveY = 100;

}
void ofApp::update(){
if (moveX <= 180) {
moveX = moveX + 1;
moveY = moveY + 1;
}
if (moveX >= 180 && moveX <= 260){
moveX = moveX + 1;
moveY = moveY - 1;
}
}

void ofApp::draw(){

ofSetColor(0);
ofNoFill();
ofDrawTriangle(moveX, moveY, 180, 100, 180, 160);

}

I’ve been wondering how to use ofPolylines or ofPath instead to set a path for my vector points. The documentation is difficult for me to interpret at my stage of learning. I aim to use shading/gradient to make it look more realistic as it moves across. I would appreciate any help with this. Thank you.

A screenshot of several triangles - a non-animated version:

Hey @M_S,

For starter I’m not sure I have understand your question so I might miss the point. Are you looking for a general 3D solution on a high resolution shape or a simple 2D effect ? let’s suppose the later.

Take two pieces of papers cut identically in a non symmetrical way (to spot corners differences) and try to create the illusion that oneis the folding part of the other. You will see a few transformations occurring :

  1. The corner you want to fold will follow your handle, a mouse’s pointer let’s say (it’s a translation).
  2. The shape will flip on one axis like a mirror (it’s a scaling).
  3. The shape will rotate depending on the vector between your folding corner and your handle (it’s a rotation).
  4. Finally the shape will recenter on the original shape corner (it’s a translation).

If you combine this 4 transformations it will give you the final homegeneous matrice to apply on the copy of your shape (you can also apply each of this step individually). You will then have two 2D shapes on a 2D plane, and with some cheap tricks (for example using masking shapes the same color of your background, or with a stencil buffer) you can hide the parts of each other that are supposedly folded.

Hope that answer your question, cheers.

Edit : here some pictures for clarification, the later one show the “tricks” and important points.




1 Like

Hey @DarkSalmon,

Thank you, so kind of you to reply, with some really helpful definitions and visualisation. I apologise I’m new to forums (and openFrameworks and coding!) so I haven’t been very clear with my query.

I wouldn’t know how to implement your solution in code. My original question was to ask how I might use ofPath to define the path my folding vertex would travel as it went across the paper to meet the opposite corner.

The way I am thinking about my problem is:
-set up variables
-define the path of my fold
-move along this path 1-10% each frame

I don’t understand the documentation well, so I hoped that somebody might show me an example of how to use ofPath. I hope that’s clearer. Thank you!

Hey @M_S , just a couple of quick comments. ofBook has a chapter on ofPolyline and ofPath if you haven’t seen it yet. You can find it here: ofBook - Advanced graphics. Then also you could actually render the paper as a 3d object, maybe using an ofPlanePrimitive or an of3dPrimitive. If you use 3d rendering, you could rely more on oF for shading/gradient effects (using ofLight and ofMaterial). And you’d have a 3d model of the process that could be viewed from different angles with an ofEasyCam or similar.

Edit: Also ofPath and ofPolyline can have 3d vertices. And an ofPath can be tessellated to an ofMesh if that’s helpful in working with it.

In computer graphics a path often refers to a closed 2d shape consisting of different
contour (polyline in the case of openframework) before being sent to a tessellator, a process
that will convert this contours to a triangle mesh.

It is often used to represent the glyph of a font. You can see example of how to use that in the examples/graphics/fontShapesExample folder of your OpenFramework directory.

That being said in your case you might not be interested by ofPath directly, but more simply by ofPolyline.

Internally an ofPolyline use plain vertices but you can also construct them using vector logic (like bezier curve). Once you have construct your polyline, you can sample points on it using getPointAtPercent for example, to move along it every 1-10% like your comment suggest.

(+1 to @TimChi comment too !)

Thanks for this @TimChi. I had read it, somehow reading it again last night it was making more sense, so there’s been progress whilst searching for this know how. Alas my assignment for school must be 2D but great to know about ofLight and ofMaterial for another time. I’ve done some ofMesh tutorials in the last few days so I’ll try to think about how I can apply it. Thank you!

Thanks again for your explanation and suggestions also, I was getting more knowledge from looking into them. I think ofPolyline is what I should use. I just am stuck on how to animate, because, can you have vertices in a variable?

Animation is a function of time, so let’s say you want to animate a vertex from point A to point B for a duration animationTotalTime set in milliseconds. First you need the absolute frame time of your animation , let’s call it deltaTime (the percent of its progression if you want). You can calculate it by dividing the current time relative to the animation’s start to the total animation’s time :

float currentTime = ofGetElapsedTimeMillis(); 
float deltaTime = (currentTime - animationStartTime) / animationTotalTime;
deltaTime = ofClamp(deltaTime, 0.0, 1.0);

To animate your point you will interpolate from it’s starting position to it’s
end position, using ofLerp for example :

ofPoint A(0.0f, 0.0);    // start point.
ofPoint B(10.0f, 0.0);   // end point.
ofPoint C;               // in-between point.

// Interpolation of a point from start to begin, also called "lerp".
// These expressions are equivalent :
// C = A + deltaTime * (B - A);
// C = (1.0 - deltaTime) * A + deltaTime * B;
C = ofLerp(A, B, deltaTime);

In the case of an ofPolyline you can retrieve the interpolate point of your path directly from the getPointAtPercent method.

See ofGetElapsedTimeMillis to retrieve the current time in milliseconds.

1 Like

Hey @DarkSalmon thank you so much for this explanation! Exactly what I needed and excited to take this away and play. Thank you for taking the time to teach me :slight_smile:

1 Like