Animate bezier path logo

Hey everyone!!
I have the assignment to create a logo in processing. I already created a “logo” but I´m struggling with the animation and I need a little help:)

size (400, 400);
noFill();
stroke(0);
strokeWeight(3);
ellipse(150,325,30,30);
bezier(150, 310, 150, -150, 225, 300, 130, 220);
bezier(130, 220, 80, 150, 300, 10, 310, 160);
bezier(310, 160, 330, 300, 195, 300, 200, 190);
bezier(200, 190, 195, 110, 270, 110, 280, 170);
bezier(280, 170, 290, 230, 240, 230,240, 190);
bezier(240, 190, 245, 150, 295, 150, 290, 230);
bezier(290, 230, 295, 310, 195, 310, 185, 230);
bezier(185, 230, 160, 60, 370, 60, 330, 280);
ellipse(330, 295, 30, 30);

I want to draw the line starting from one circle to the other following the bezier path.
So its not just printed all at once but develops(?). Kind of like a Fuse! And should also be able to develop backwards(the same style).
I dont really know how to approach this( Ive tried a bit but didnt come far(Im a beginner lol)). If you have any idea please let me know.
Have a nice day:D

2 Likes

for an animation you need the functions setup and draw

check out bezierPoint, see reference bezierPoint() / Reference / Processing.org

here is an example

Warm regards,

Chrisir



int i=0;

// -------------------------------------------------------------------------------------------------------------------------

void setup() {
  //  size(1900, 1000);
  size (400, 400);
}

void draw() {
  background(211);


  noFill();
  stroke(0);
  strokeWeight(3);
  ellipse(150, 325, 30, 30);
  bezier(150, 310, 150, -150, 225, 300, 130, 220);
  bezier(130, 220, 80, 150, 300, 10, 310, 160);
  bezier(310, 160, 330, 300, 195, 300, 200, 190);
  bezier(200, 190, 195, 110, 270, 110, 280, 170);
  bezier(280, 170, 290, 230, 240, 230, 240, 190);
  bezier(240, 190, 245, 150, 295, 150, 290, 230);
  bezier(290, 230, 295, 310, 195, 310, 185, 230);
  bezier(185, 230, 160, 60, 370, 60, 330, 280);
  ellipse(330, 295, 30, 30);

  noFill();
  bezier(340, 80, 40, 40, 360, 360, 60, 320);

  int steps = 100;
  // for (int i = 0; i <= steps; i++) {
  float t = i / float(steps);
  float x = bezierPoint(340, 40, 360, 60, t);
  float y = bezierPoint(80, 40, 360, 320, t);
  ellipse(x, y, 10, 10);
  // }
  i++;
}

3 Likes

Thank you so much for your answer Chrisir!!
Is there any way I could link the line to the moving ellipse, so that the ellipse would end up “drawing” the picture?
Kind regards,
Madita

My example shows one bezier and the two bezierPoint code lines for it.

You need to reproduce this for your beziers of course.

Or work with them one after another which might be a bit tricky

bezierPoint() is one for x and one for y by the way - see reference

3 Likes

Hello @omagash ,

Who is the assignment for?

This is an achievable task.

The resources you need are here:
https://processing.org/ < Check out the documentation and learn section!

I scrutinized the two references:

A function bz_points() was written to replace this from the bezierPoint () reference:

int steps = 10;
for (int i = 0; i <= steps; i++) {
  float t = i / float(steps);
  float x = bezierPoint(340, 40, 360, 60, t);
  float y = bezierPoint(80, 40, 360, 320, t);
  ellipse(x, y, 10, 10);
}

I then used the bz_points() function after each bezier():

You can use the for() loop after each bezier() but it is really much easier to write a function, pass the parameters (they are the same and can be cut and pasted) and this is less likely to have errors introduced.

The points that are generated can be stored in an array and later used to plot or animate the data:

The last one is animated in my code and I snipped an image part way!

I would do this in steps:

  • Understand the functions in references and plot the points for each bezier().
  • Save the points in an array.
  • Use the data in array to plot the points.
  • Once the above is achieved animate the points in the draw() cycle.
  • Only after you can plot the above consider generating denser data points (more steps) and then sorting through them for equal spacing between each point.
  • See dist() function.

I enjoyed this challenge! I hope you enjoy it as well.

:)

4 Likes

I followed my advise and took on the challenge of a dense array of data (500 steps) and managed to achieve this:

It is achievable if you take it in steps.

Be sure to save working versions of code before progressing and document code.

:)

2 Likes

Thank you so much for your reply! : )
It helps a lot!! I`m looking forward to trying it :laughing:
Have a great day!!

There is always more than one way to do something, so here is an alternative approach that I used to animate your logo forwards and in reverse.

This is an assignment so I am not providing the full code solution rather an explanation of the algorithms I used.

The first thing I did was to represent the logo data in a 2D array

float[][] logoF = {
  new float[] {150, 310, 150, -150, 225, 300, 130, 220},
  new float[] {130, 220, 80, 150, 300, 10, 310, 160},
  new float[] {310, 160, 330, 300, 195, 300, 200, 190},
  new float[] {200, 190, 195, 110, 270, 110, 280, 170},
  new float[] {280, 170, 290, 230, 240, 230, 240, 190},
  new float[] {240, 190, 245, 150, 295, 150, 290, 230},
  new float[] {290, 230, 295, 310, 195, 310, 185, 230},
  new float[] {185, 230, 160, 60, 370, 60, 330, 280}
};

Each row represents a single Bezier curve, so we have 8 curves -
logoF[0], logoF[1], logoF[2], logoF[3], logoF[4], logoF[5], logoF[6] and logoF[7]

We can create a reference to any of the curves like this
float[] bc = logoF[n]; // where n is in the range 0-7 inclusive

Once we have this reference we can access the control point data like this

bc = logoF[3]; // fourth curve
println(bc[0], bc[1]); // outputs 200, 190

Using arrays allows easy access all the Bezier control point coordinates. The next stage is to look at the algorithm to trace out the entire set of curves.

To represent a point on a Bezier curve we use a parametric variable which we will call t. If we vary t in the range 0.0 to 1.0 we can calculate any position on the curve.

In our logo we have 8 Bezier curves so we create a new parametric variable, ct which varies between 0.0 and 8.0 inclusive. Consider the point ct = 3.14 the whole number part (can be zero) represents the individual Bezier curve and the decimal part the parametric position on that curve so we have

ct = 3.14;
cIdx = int(ct); // index = 3
bc = logoF[cIdx]; // reference to the coordinate array for the 4th Bezier curve
t = ct - cIdx; // parametric position = 0.14

So the algorithm for drawing the entire curve for a given ct value is

Calculate the curve number (cIdx)
Calculate the parametric variable (t)
for every curve in the range >=0 and < cIdx
   use the bezier function to draw the entire Bezier curve
Get a reference to the part traced curve (logoF[cIdx])
Draw this curve from 0.0 to `t` 

You can use the same algorithm and code to draw the logo in reverse if you create a new 2D array (logoR) and reverse the Binary curve order and for each Bezier curve reverse the coordinate pairs.

3 Likes