Connectingrods and crankshaft.... for flapping bird

Hello everyone
I try to code a little sketch that allows me to visualize the linkage between the wings and the crankshaft of a plane with flapping wings.

For now I have “done” this allows me according to some configuration to have something that “works”.

I would like to be able to do something more eficace and also the display will be done more quickly.

According to the settings the connectingrods change length during the race …

Here is what I have (a revolution for the elements to be put in place):


float x =0;

float course= 25;
float a= 40; // distance bielle pivot d'aile
float Bielle=80;  // longueur de la bielle
float Angle = 40;  // angle de décalage entre deux mannetons
float AxeAile=10;  //distance du pivot de l'aile depuis l'axe
float Dist_Pivot_Vilo=75;

float H=0;
float c=0;

int i=1;
int D=0;
int G=90;
float old_DD=0;
float old_DG=0;
float old_BielleD=0;
float old_BielleG=0;
int sens = 1;

void setup() { 
  size(600, 600); //
  frameRate(25);
  background(255);
  strokeWeight(.2);
  stroke(0);
  noFill();
  smooth();
}

void draw() {
  scale(1.5);
  background(255);
  translate(200, 300);
  strokeWeight(.01);
  stroke(0);
  //axes
  ellipse(0, 0, course, course); // course maneton vilebrequin
  line(0, 70, 0, -150);  // axe vertical vilebrequin
  line(70, 0, -70, 0);  //  axe horizontal vilebrequin
  line(70, -Dist_Pivot_Vilo, -70, -Dist_Pivot_Vilo);  //  axe horizontal pivot d'ailes
  line(AxeAile, -Dist_Pivot_Vilo+15, AxeAile, -Dist_Pivot_Vilo-15);  // axe vertical pivot d'aile droite
  line(-AxeAile, -Dist_Pivot_Vilo+15, -AxeAile, -Dist_Pivot_Vilo-15);  // axe vertical pivot d'aile gauche

  strokeWeight(.5);
  stroke(255, 176, 18);
  // orange droite
  ellipse (course/2*sin(radians(-270+i)), course/2*cos(radians(-270+i)), 5, 5);

  PVector WingD = new PVector(AxeAile+a/2*sin(radians(sens*-270+D)), -Dist_Pivot_Vilo+ a/2*cos(radians(-270+D)));
  PVector WingG = new PVector(AxeAile+a/2*sin(radians(-sens*270+G)), -Dist_Pivot_Vilo+ a/2*cos(radians(270+G)));

  PVector MannetonD = new PVector(course/2*sin(radians(-270+i)), course/2*cos(radians(-270+i)));
  PVector MannetonG = new PVector(course/2*sin(radians(-270+i+Angle)), course/2*cos(radians(-270+i+Angle)));
  //(course/2*sin(radians(-270+i+Angle)), course/2*cos(radians(-270+i+Angle)), 5, 5);

  PVector WingAxelD = new PVector (30, -Dist_Pivot_Vilo);
  PVector WingAxelG = new PVector (30, -Dist_Pivot_Vilo);

  float DD = MannetonD.dist(WingAxelD);
  float DG = MannetonG.dist(WingAxelG);
  float BielleD = MannetonD.dist(WingD); // longueur de la bielle droite
  float BielleG = MannetonG.dist(WingG); // longueur de la bielle gauche
  //println ((radians(-270+i)));
  println(" ");
  print("D");
  println(int(BielleD));  // 
  print("G");
  println(int(BielleG));
  println(" ");
  print("D");
  println(DD);
  print("G");
  println(DG);
  if (BielleD>Bielle) {
    D--;
  }
  if (BielleD<Bielle) {
    D++;
  }

  if (old_DD > DD) {
    WingD.sub(0, 0);
    WingD.mult(1);
    line(MannetonD.x, MannetonD.y, WingD.x, WingD.y);
    ellipse (AxeAile, -Dist_Pivot_Vilo, a, a);  
    ellipse (WingD.x, WingD.y, 5, 5);   // axe bielle d'aile
    D++;
  } else {
    WingD.sub(0, 0);
    WingD.mult(1);
    line(MannetonD.x, MannetonD.y, WingD.x, WingD.y);
    ellipse (AxeAile, -Dist_Pivot_Vilo, a, a);   
    ellipse (WingD.x, WingD.y, 5, 5);   // axe bielle d'aile
    D--;
  }


  strokeWeight(.5);
  stroke(2, 201, 23);
  // vert gauche
  ellipse (course/2*sin(radians(-270+i+Angle)), course/2*cos(radians(-270+i+Angle)), 5, 5); // 90 pour 90º entre le violet et le bleu

  if (BielleG>Bielle) {
    G++;
  }
  if (BielleG<Bielle) {
    G--;
  }

  if (old_DG > DG) {
    WingG.sub(0, 0);
    WingG.mult(1);
    line(MannetonG.x, MannetonG.y, -WingG.x, WingG.y);
    ellipse (-AxeAile, -Dist_Pivot_Vilo, a, a);  
    ellipse (-WingG.x, WingG.y, 5, 5);   // axe bielle d'aile
    G--;
  } else {
    WingG.sub(0, 0);
    WingG.mult(1);
    line(MannetonG.x, MannetonG.y, -WingG.x, WingG.y);
    ellipse (-AxeAile, -Dist_Pivot_Vilo, a, a);   
    ellipse (-WingG.x, WingG.y, 5, 5);   // axe bielle d'aile
    G++;
  }

  old_BielleD = BielleD;
  old_BielleG = BielleG;
  old_DD = DD;
  old_DG = DG;
  i++;
}

You will certainly have noticed that some of the variable names are in French … I am French speaking. :wink:

1 Like
  • first i like that program, even i not understand it.

  • speed ?

  • if the program is slow

    • disable printing
    • disable frameRate()
    • disable smooth ??

but a test with printing frameRate shows that your program is NOT SLOW

it is your code / show:
to run it faster use instead of

i++;

i = i + 2;

at the end.

Tres bien! I built an ornithopter a long time ago and this program would have been a big help in the construction.

I found this site:
https://www.lucidarme.me/ball-joint-connecting-link/

:grinning:

Thanks for the link, interesting. One thing I notice about the connecting rods in your code is that they are not fixed in length? That doesn’t seem realistic unless using rubber bands for connecting rods and that’s like pushing on a rope.:crazy_face:

Edit: My comprehension is at a new low. The first post acknowledges that the rods are not fixed in length.:crazy_face:

The formula in the link has typographical mistakes, after several attempts to put it in a new code it returns to me wrong values.

On the same basis I am writing another equation

Starting from the site indicated in the previous message I used the distance between P1 and M to determine the angle Ɵ2.

I took all my sketch, the rod is less “elastic”, but only in the basic configuration. For that I had to compensate with the value “1040” (which I do not have the correspondence).

If I move the wing pivot relative to the crankshaft axis, it does not work properly either.


float l1=20;  // >> course
float l2 = 20; // distance bielle pivot d'aile >> Maneton_aile
float Bielle=0;  // longueur de la bielle
float Decalage_Maneton = 40;  // angle de décalage entre deux mannetons
float Dec_Piv_aile =0;  //distance du pivot de l'aile depuis l'axe >> AxeAile
float X=75;
float angle=0;
float Theta_2 = 0;
float Theta_2_test = 0;
float Theta_1 = 0;
float Theta_2_2 =0;
float P1_M = 0;
float L = 0;
float flag = 0;

float A = 0;
float C = 0;

float x = 0 ;
float y = 0 ;

float RPM = 360; // vitesse de rotation

int i = 0;

PVector  O, P1, M, P2, v5, H;

void setup() {
  size(600, 600); //,P2D);
  //frameRate(40);
  background(255);
  strokeWeight(.2);
  stroke(0);
  noFill();
  smooth();
  O = new PVector(0, 0); //centre du vilebrequin
  P1 = new PVector( l1, 0);  //maneton
  // M = new PVector( Dec_Piv_aile, -Dist_Pivot_Vilo); //pivot de l'aile
  M = new PVector( 0+Dec_Piv_aile, -X); //pivot de l'aile
  // P2 = new PVector( l2 + Dec_Piv_aile , -Dist_Pivot_Vilo);  // jonction bielle - aile
  P2 = new PVector( l2, -X);  // jonction bielle - aile
  v5 = new PVector(0, -50); //valeur haute de l'axe du vilebrequin
  H = new PVector( 0, P1.y);
  P1_M = PVector.dist(P1, M);
  L = PVector.dist(P1, P2);  // longueur de bielle droite
  P1.rotate(-PI/RPM);
}

void draw() {
  scale(1.5);
  background(255);
  translate(200, 300);
  strokeWeight(.01);
  stroke(0);
  //axes
  ellipse(0, 0, l1*2, l1*2); // course maneton vilebrequin
  line(0, 70, 0, -150);  // axe vertical vilebrequin
  line(70, 0, -70, 0);  //  axe horizontal vilebrequin
  line(70, -X, -70, -X);  //  axe horizontal pivot d'ailes

  strokeWeight(1);
  stroke(200, 20, 20);
  line(O.x, O.y, P1.x, P1.y); //course droite
  line(M.x, M.y, P2.x+Dec_Piv_aile, P2.y); // aile droite
  line(P1.x, P1.y, P2.x+Dec_Piv_aile, P2.y); //bielle
  line(O.x, O.y, v5.x, v5.y); //axe vertical vilebrequin
  ellipse(O.x, O.y, 5, 5);   // axe de vilebrequin
  ellipse(M.x, M.y, 5, 5);  // pivot d'aile droite
  ellipse(P2.x+Dec_Piv_aile, P2.y, 5, 5); // connection bielle - aile droite
  ellipse(P1.x, P1.y, 5, 5);  // articulation maneton bielle droite

  angle = PVector.angleBetween(P1, M); // angle entre le manneton et la ligne centre vilo_pivot d'aile
  Theta_1= (degrees(angle));
  println (degrees(angle));

  print("P1_M  = ");
  println(P1_M);

  A = flag*-acos((-sq(l1) + sq(P1_M) + sq(X)) / (2 * P1_M * X)) ;
  C = acos((sq(l2) + sq(P1_M) - sq(L)) / (2 * P1_M * l2)) ;

  if (P1.x > 0 ) {
    flag = 1;
    Theta_2 =  degrees(PI-((A)-(C)));
    Theta_2_2 =degrees((Theta_2-180)/1042/PI);
    println("ok1");
  } else {
    flag = -1;
    Theta_2 =  degrees(PI-((A)-(C)));
    //    Theta_2 =  degrees(PI+((C)+(A)));
    Theta_2_2 =degrees((Theta_2-180)/1042/PI);
    println("ok2");
  }

  y = cos(Theta_2_2)*l2;  //coordonnée x du point p2
  x = sin(Theta_2_2)*l2;  //coordonnée y du point p2

  stroke(#6282FA);//bleu
  ellipse(x, -X, 5, 5); // point P2
  stroke(#FC96FC); //rose
  ellipse(0, y-X, 5, 5);
  stroke(#FFAF2E); //orange
  ellipse(x, y-X, 5, 5);
  stroke(#62FA75); //vert
  H.y=P1.y;
  ellipse(H.x, H.y, 2, 2); // point H

  P1.rotate(-PI/RPM);  //rotation du vilebrequin
  P1_M = PVector.dist(P1, M);

  P2.x=x;
  P2.y=y-75;

  println(degrees(A)+", "+degrees(C));
  print("Theta_2 : ");
  println((Theta_2));
  print("Theta_1      : ");
  println((Theta_1));  
  print("Theta_2_test : ");
  println(Theta_2_test);
  print(" P1_M  = ");
  println(P1_M);
  print("bielle           : ");
  println(L);
  println("bielle Effective : "+PVector.dist(P1, P2));
  println(flag*degrees(angle));
  println("x = "+x+"; y = "+y);
  println(P1);
  println(P2);
  println();
  println();
}

If anyone has an idea to fix all this …:face_with_raised_eyebrow:

hi,
i try to read & run your code ,
and not understand the angle thing,
but:

  • -a- first you use “flag” to calc “A”
    and later you set “flag” depending on “P1.x > 0”
    should be reversed.

  • -b- but the Theta_2 and Theta_2_2 calc is the same,
    even it is made under the flag condition ( the descr. is different from the calc )

    Theta_2 =  degrees(PI-((A)-(C)));
    //    Theta_2 =  degrees(PI+((C)+(A)));

  • -c- PI, A, C are “rad”
    “Theta_2” alread degrees
    so
Theta_2_2 =degrees((Theta_2-180)/1042/PI);

just makes no sense to me, with or without “1042”

  • -d- for mechanic and numeric reasons i would suggest that you ensure
    that l2 > l1 like
float l1 = 20;  // >> course
float l2 = 20.001; // distance bielle pivot d'aile >> Maneton_aile

but i can not solve your problem,
even i have a small idea for the show


float l1 = 20;  // >> course
float l2 = 20.001; // distance bielle pivot d'aile >> Maneton_aile
float Bielle=0;  // longueur de la bielle
float Decalage_Maneton = 40;  // angle de décalage entre deux mannetons
float Dec_Piv_aile =0;  //distance du pivot de l'aile depuis l'axe >> AxeAile
float X=75;
float angle=0;
float Theta_2 = 0;
float Theta_2_test = 0;
float Theta_1 = 0;
float Theta_2_2 =0;
float P1_M = 0;
float L = 0;
float flag = 0;

float A = 0;
float C = 0;

float x = 0 ;
float y = 0 ;

float RPM = 90; //360; // vitesse de rotation

int i = 0;

PVector  O, P1, M, P2, v5, H;

boolean dbug = true;
String ok = "";
float dgx=0.0;

void setup() {
  size(600, 430); //,P2D);
  //frameRate(40);
  background(255);
  strokeWeight(.2);
  stroke(0);
  noFill();
  smooth();
  O = new PVector(0, 0); //centre du vilebrequin
  P1 = new PVector( l1, 0);  //maneton
  // M = new PVector( Dec_Piv_aile, -Dist_Pivot_Vilo); //pivot de l'aile
  M = new PVector( 0+Dec_Piv_aile, -X); //pivot de l'aile
  // P2 = new PVector( l2 + Dec_Piv_aile , -Dist_Pivot_Vilo);  // jonction bielle - aile
  P2 = new PVector( l2, -X);  // jonction bielle - aile
  v5 = new PVector(0, -50); //valeur haute de l'axe du vilebrequin
  H = new PVector( 0, P1.y);
  P1_M = PVector.dist(P1, M);
  L = PVector.dist(P1, P2);  // longueur de bielle droite
  P1.rotate(-PI/RPM);
}

void draw() {
//  scale(1.5);
//  background(255);

  noStroke();
  fill(200,200,0);
  rect(0,0,600,30);
  fill(0,200,0);
  rect(100,120,200,300);
  fill(0);
  text("P1_M: = "+nf(P1_M,1,1)+" angle: "+nf(degrees(angle),3,1)+" A: "+nf((A),1,1)+" C: "+nf((C),1,1)+" Theta_2: "+nf((Theta_2),3,1)+" Theta_2_2: "+nf((Theta_2_2),3,1)+"  "+ok,20,20);
  noFill();

  translate(200, 300);
//  strokeWeight(.01);
  stroke(0);
  //axes
  ellipse(0, 0, l1*2, l1*2); // course maneton vilebrequin
  line(0, 70, 0, -150);  // axe vertical vilebrequin
  line(70, 0, -70, 0);  //  axe horizontal vilebrequin
  line(70, -X, -70, -X);  //  axe horizontal pivot d'ailes

  strokeWeight(1);
  stroke(200, 20, 20);
  line(O.x, O.y, P1.x, P1.y); //course droite
  line(M.x, M.y, P2.x+Dec_Piv_aile, P2.y); // aile droite
  line(P1.x, P1.y, P2.x+Dec_Piv_aile, P2.y); //bielle
  line(O.x, O.y, v5.x, v5.y); //axe vertical vilebrequin
  ellipse(O.x, O.y, 5, 5);   // axe de vilebrequin
  ellipse(M.x, M.y, 5, 5);  // pivot d'aile droite
  ellipse(P2.x+Dec_Piv_aile, P2.y, 5, 5); // connection bielle - aile droite
  ellipse(P1.x, P1.y, 5, 5);  // articulation maneton bielle droite

  angle = PVector.angleBetween(P1, M); // angle entre le manneton et la ligne centre vilo_pivot d'aile
  Theta_1= (degrees(angle));


  A = flag*-acos((-sq(l1) + sq(P1_M) + sq(X)) / (2 * P1_M * X)) ;
  C = acos((sq(l2) + sq(P1_M) - sq(L)) / (2 * P1_M * l2)) ;

  if (P1.x > 0 ) {
    flag = 1;
    Theta_2 =  degrees(PI-((A)-(C)));
    Theta_2_2 =degrees((Theta_2-180)/1042/PI);
    ok = "ok1"; //println("ok1");
  } else {
    flag = -1;
    Theta_2 =  degrees(PI-((A)-(C)));
    //    Theta_2 =  degrees(PI+((C)+(A)));
    Theta_2_2 =degrees((Theta_2-180)/1042/PI);
    ok = "ok2"; //println("ok2");
  }

  y = cos(Theta_2_2)*l2;  //coordonnée x du point p2
  x = sin(Theta_2_2)*l2;  //coordonnée y du point p2

  stroke(#6282FA);//bleu
  ellipse(x, -X, 5, 5); // point P2
  stroke(#FC96FC); //rose
  ellipse(0, y-X, 5, 5);  
  // KLL as graph
  stroke(255);
  line(100+dgx+1,-150,100+dgx+1,150);  // clean up
  stroke(#FC96FC); //rose
  ellipse(100+dgx, y-X, 1, 1);  // KLL as graph
//  dgx++; if ( dgx > width/2 ) dgx = 0;

  stroke(#FFAF2E); //orange
  ellipse(x, y-X, 5, 5);
  stroke(#62FA75); //vert
  H.y=P1.y;
  ellipse(H.x, H.y, 2, 2); // point H
  // KLL as graph
  ellipse(100+dgx, H.y, 1, 1);  // KLL as graph
  dgx+=0.3; if ( dgx > width/2 ) dgx = 0;  // next pix


  P1.rotate(-PI/RPM);  //rotation du vilebrequin
  P1_M = PVector.dist(P1, M);

  P2.x=x;
  P2.y=y-75;

  
  if (dbug) {
    println(degrees(A)+", "+degrees(C));
    print("Theta_2 : ");
    println((Theta_2));
    print("Theta_1      : ");
    println((Theta_1));  
    print("Theta_2_test : ");
    println(Theta_2_test);
    print(" P1_M  = ");
    println(P1_M);
    print("bielle           : ");
    println(L);
    println("bielle Effective : "+PVector.dist(P1, P2));
    println(flag*degrees(angle));
    println("x = "+x+"; y = "+y);
    println(P1);
    println(P2);
    println();
    println();
  }
}


Hi,

The value 1042 is to slow down l2 to go at the same speed as l1.
I do not understand why l2 runs faster than l1 if I do not put this value.

Thank you for the cosmetic suggestions.

using that word “speed” here made me wonder what you talk about until i tested,
yes crazy rotation of the upper circle…

but finally i found it,
as i mentioned a
degrees ( (angle-180) / PI ) or degrees ( (angle-180) /1042 PI )
can not be right, its just

angle-180

the problem was actually here:

cos( angle -180 )

easy fix:

cos(radians(angle -180))

here again my play version with this fix ( and small restructure only )



float l1 = 20;  // >> course
float l2 = 20.001; // distance bielle pivot d'aile >> Maneton_aile
float Bielle=0;  // longueur de la bielle
float Decalage_Maneton = 40;  // angle de décalage entre deux mannetons
float Dec_Piv_aile =0;  //distance du pivot de l'aile depuis l'axe >> AxeAile
float X=75;
float angle=0;
float Theta_2 = 0;
float Theta_2_test = 0;
float Theta_1 = 0;
float Theta_2_2 =0;
float P1_M = 0;
float L = 0;
float flag = 0;

float A = 0;
float C = 0;

float x = 0 ;
float y = 0 ;

float RPM = 360; //360; // vitesse de rotation

int i = 0;

PVector  O, P1, M, P2, v5, H;

boolean dbug = false;
float dgx=0.0;

void setup() {
  size(600, 430); //,P2D);
  frameRate(40);
  background(255);
  strokeWeight(.2);
  stroke(0);
  noFill();
  smooth();
  O = new PVector(0, 0); //centre du vilebrequin
  P1 = new PVector( l1, 0);  //maneton
  // M = new PVector( Dec_Piv_aile, -Dist_Pivot_Vilo); //pivot de l'aile
  M = new PVector( 0+Dec_Piv_aile, -X); //pivot de l'aile
  // P2 = new PVector( l2 + Dec_Piv_aile , -Dist_Pivot_Vilo);  // jonction bielle - aile
  P2 = new PVector( l2, -X);  // jonction bielle - aile
  v5 = new PVector(0, -50); //valeur haute de l'axe du vilebrequin
  H = new PVector( 0, P1.y);
  P1_M = PVector.dist(P1, M);
  L = PVector.dist(P1, P2);  // longueur de bielle droite
  P1.rotate(-PI/RPM);
  
  println(" press key [space] for print ");
}



void do_calc() {
  angle = PVector.angleBetween(P1, M); // angle entre le manneton et la ligne centre vilo_pivot d'aile
  Theta_1= (degrees(angle));

  if (P1.x > 0 )  flag =  1;  //_______________________________________ change
  else            flag = -1;

  A = flag*-acos((-sq(l1) + sq(P1_M) + sq(X)) / (2 * P1_M * X)) ;
  C = acos((sq(l2) + sq(P1_M) - sq(L)) / (2 * P1_M * l2)) ;
  Theta_2 =  degrees(PI-((A)-(C)));
  Theta_2_2 =  Theta_2-180;        //degrees((Theta_2-180)/1042/PI);   //_______________________________________ change

  y = cos(radians(Theta_2_2))*l2;  //coordonnée x du point p2          //_______________________________________ change
  x = sin(radians(Theta_2_2))*l2;  //coordonnée y du point p2          //_______________________________________ change
  
  H.y=P1.y;

  P1.rotate(-PI/RPM);  //rotation du vilebrequin
  P1_M = PVector.dist(P1, M);

  P2.x=x;
  P2.y=y-75;
 
}

void draw() {
  //  scale(1.5);      //_______________________________________ change
  //  background(255); //_______________________________________ change
  do_calc();           //_______________________________________add

  noStroke();
  fill(200, 200, 0);
  rect(0, 0, 600, 30);
  fill(0, 200, 0);
  rect(100, 120, 200, 300);
  fill(0);
  //_______________________________________add
  if (dbug) text("P1_M: = "+nf(P1_M, 1, 1)+" angle: "+nf(degrees(angle), 3, 1)+" A: "+nf((A), 1, 3)+" C: "+nf((C), 1, 3)+" Theta_2_2: "+nf((Theta_2_2), 3, 1), 20, 20);
  noFill();

  translate(200, 300);
  //  strokeWeight(.01);
  stroke(0);
  //axes
  ellipse(0, 0, l1*2, l1*2); // course maneton vilebrequin
  line(0, 70, 0, -150);  // axe vertical vilebrequin
  line(70, 0, -70, 0);  //  axe horizontal vilebrequin
  line(70, -X, -70, -X);  //  axe horizontal pivot d'ailes

  strokeWeight(1);
  stroke(200, 20, 20);
  line(O.x, O.y, P1.x, P1.y); //course droite
  line(M.x, M.y, P2.x+Dec_Piv_aile, P2.y); // aile droite
  line(P1.x, P1.y, P2.x+Dec_Piv_aile, P2.y); //bielle
  line(O.x, O.y, v5.x, v5.y); //axe vertical vilebrequin
  ellipse(O.x, O.y, 5, 5);   // axe de vilebrequin
  ellipse(M.x, M.y, 5, 5);  // pivot d'aile droite
  ellipse(P2.x+Dec_Piv_aile, P2.y, 5, 5); // connection bielle - aile droite
  ellipse(P1.x, P1.y, 5, 5);  // articulation maneton bielle droite


  stroke(#6282FA);//bleu
  ellipse(x, -X, 5, 5); // point P2
  stroke(#FC96FC); //rose
  ellipse(0, y-X, 5, 5);  
  //_______________________________________add as graph
  stroke(255);
  line(100+dgx+1, -150, 100+dgx+1, 150);  // clean up
  stroke(#FC96FC); //rose
  ellipse(100+dgx, y-X, 1, 1);  // KLL as graph

  stroke(#FFAF2E); //orange
  ellipse(x, y-X, 5, 5);
  stroke(#62FA75); //vert
  ellipse(H.x, H.y, 2, 2); // point H
  // KLL as graph
  ellipse(100+dgx, H.y, 1, 1);  // KLL as graph
  dgx+=0.3; 
  if ( dgx > width/2 ) dgx = 0;  // next pix

  if (dbug) {  //_______________________________________add
    println("calc P1_M: P1_M "+nf(P1_M, 1, 1)+" P1 "+P1+" M "+M);
    println(degrees(A)+", "+degrees(C));
    print("Theta_2 : ");
    println((Theta_2));
    print("Theta_1      : ");
    println((Theta_1));  
    print("Theta_2_test : ");
    println(Theta_2_test);
    print(" P1_M  = ");
    println(P1_M);
    print("bielle           : ");
    println(L);
    println("bielle Effective : "+PVector.dist(P1, P2));
    println(flag*degrees(angle));
    println("x = "+x+"; y = "+y);
    println(P1);
    println(P2);
    println();
    println();
  }
}

void keyReleased(){ //_______________________________________add
 if (key == ' ') dbug=!dbug;  
}

snap-082

Cool, it works well.
I had not noticed the + brought sinusoides to see the fluidity of the movement of the rod, it’s great.

Now I have another problem. When to move the pivot of the wing in relation to the center I change this value it becomes elastic again and the passage to the Low Dead Point is lame:

float Dec_Piv_aile = 20;

yes, so much for the:

you not even run my code ( i noticed that )

//__
well, i checked on one coding mistake, i did not even try to understand
your angle calculation ( would need a added drawing where all elements with length and angles are identified.

but i did play with l2 = 20.001 … 50 and that works good,
so why you not try first :
if Dec_Piv_aile > 0; just add it to l2
and no need to do that very difficult calculation.

I am probably speaking badly, certainly due to the French English translation.

When everything is centered it works perfectly, I also do the tests playing only with l2 and it’s nickel.

it’s when I want to offset the pivot of the wing that it does not go anymore, because the diagram changes and the distance between O and M is different.

I look at the proposed solution :wink:

And I forgot to post all the code in the message before :roll_eyes:


float l1 = 20;  // >> course
float l2 = 40; // distance bielle pivot d'aile >> Maneton_aile
float Bielle=0;  // longueur de la bielle
float Decalage_Maneton = 40;  // angle de décalage entre deux mannetons
float Dec_Piv_aile =20;  //distance du pivot de l'aile depuis l'axe 
float X=75;
float angle=0;
float angle_Pivot = 0 ;
float angle_P1 = 0 ;
float Theta_2 = 0;
float Theta_2_test = 0;
float Theta_1 = 0;
float Theta_2_2 =0;
float P1_M = 0;
float O_M = 0;
float L = 0;
float flag = 1;
float A = 0;
float C = 0;
float x = 0 ;
float y = 0 ;
float RPM = 360; //360; // vitesse de rotation

int i = 0;

PVector  O, P1, M, P2, v5, H;

boolean dbug = false;
float dgx=0.0;

void setup() {
  size(600, 600); //,P2D);
  frameRate(40);
  background(255);
  strokeWeight(.2);
  stroke(0);
  noFill();
  smooth();
  O = new PVector(0, 0); //centre du vilebrequin
  P1 = new PVector( l1, 0);  //maneton
  // M = new PVector( Dec_Piv_aile, -Dist_Pivot_Vilo); //pivot de l'aile
  M = new PVector( 0+Dec_Piv_aile, -X); //pivot de l'aile
  // P2 = new PVector( l2 + Dec_Piv_aile , -Dist_Pivot_Vilo);  // jonction bielle - aile
  P2 = new PVector( l2, -X);  // jonction bielle - aile ///// possibilité de changer la position au départ en changeant "y"
  v5 = new PVector(0, -50); //valeur haute de l'axe du vilebrequin
  H = new PVector( 0, P1.y);
  P1_M = PVector.dist(P1, M);
  O_M = PVector.dist(O, M);
  L = PVector.dist(P1, P2);  // longueur de bielle droite
  //P1.rotate(-PI/RPM);
  
  println(" press key [space] for print ");
}



void do_calc() {
  angle = degrees(PVector.angleBetween(P1, v5)); // angle entre le manneton et le pivot d'aile
  angle_Pivot = degrees(PVector.angleBetween(v5, M)); // angle entre centre du vilebrequi et le pivot d'aile
  angle_P1 = degrees(PVector.angleBetween(v5, P1)); // angle entre le manneton et le centre du vilebrequin
  Theta_1= angle;
  

  if (P1.x < 0 )  angle_P1= -angle_P1;  //_______________________________________ change
 // else            flag = -1;
 
  if ( angle_P1-angle_Pivot > 0) flag =  1;  //_______________________________________ add
  else                           flag = -1;  //_______________________________________ add
 println(angle_Pivot);
println(angle_P1);
println (flag);
println();
println();
  A = flag*-acos((-sq(l1) + sq(P1_M) + sq(O_M)) / (2 * P1_M * O_M)) ;
  C = acos((sq(l2) + sq(P1_M) - sq(L)) / (2 * P1_M * l2)) ;
  Theta_2 =  degrees(PI-((A)-(C)));
  Theta_2_2 =  Theta_2-180;        //degrees((Theta_2-180)/1042/PI);   

  y = cos(radians(Theta_2_2))*l2;  //coordonnée x du point p2          
  x = sin(radians(Theta_2_2))*l2;  //coordonnée y du point p2         
  
  H.y=P1.y;

  P1.rotate(-PI/RPM);  //rotation du vilebrequin
  P1_M = PVector.dist(P1, M);

  P2.x=x;
  P2.y=y-75;
 
}

void draw() {
    //scale(1.5);      
  //  background(255); 
  do_calc();           

  noStroke();
  fill(200, 200, 0);
  rect(0, 0, 600, 30);
  fill(0, 200, 0);
  rect(100, 120, 200, 300);
  fill(0);
 
  if (dbug) text("P1_M: = "+nf(P1_M, 1, 1)+" angle: "+nf(degrees(angle), 3, 1)+" A: "+nf((A), 1, 3)+" C: "+nf((C), 1, 3)+" Theta_2_2: "+nf((Theta_2_2), 3, 1), 20, 20);
  noFill();

  translate(200, 300);
  //  strokeWeight(.01);
  stroke(0);
  //axes
  ellipse(0, 0, l1*2, l1*2); // course maneton vilebrequin
  //ellipse(M.x, -X, l2*2, l2*2); // course maneton d'aile
  line(0, 70, 0, -150);  // axe vertical vilebrequin
  line(70, 0, -70, 0);  //  axe horizontal vilebrequin
  line(70, -X, -70, -X);  //  axe horizontal pivot d'ailes

  strokeWeight(1);
  stroke(200, 20, 20);
  line(O.x, O.y, P1.x, P1.y); //course droite
  line(M.x, M.y, P2.x+Dec_Piv_aile, P2.y); // aile droite  //_______________________________________ change
  line(P1.x, P1.y, P2.x+Dec_Piv_aile, P2.y); //bielle      //_______________________________________ change
  line(O.x, O.y, v5.x, v5.y); //axe vertical vilebrequin
  ellipse(O.x, O.y, 5, 5);   // axe de vilebrequin
  ellipse(M.x, M.y, 5, 5);  // pivot d'aile droite
  ellipse(P2.x+Dec_Piv_aile, P2.y, 5, 5); // connection bielle - aile droite     //_______________________________________ change
  ellipse(P1.x, P1.y, 5, 5);  // articulation maneton bielle droite


  stroke(#6282FA);//bleu
  ellipse(x, -X, 5, 5); // point P2
  stroke(#FC96FC); //rose
  ellipse(0, y-X, 5, 5);  
  //_______________________________________add as graph
  stroke(255);
  line(100+dgx+1, -150, 100+dgx+1, 150);  // clean up
  stroke(#FC96FC); //rose
  ellipse(100+dgx, y-X, 1, 1);  // KLL as graph

  stroke(#FFAF2E); //orange
  ellipse(x, y-X, 5, 5);
  stroke(#62FA75); //vert
  ellipse(H.x, H.y, 5, 5); // point H
  // KLL as graph
  ellipse(100+dgx, H.y, 1, 1);  // KLL as graph
  dgx+=0.3; 
  if ( dgx > width/2 ) dgx = 0;  // next pix

  if (dbug) {  //_______________________________________add
    println("calc P1_M: P1_M "+nf(P1_M, 1, 1)+" P1 "+P1+" M "+M);
    println(degrees(A)+", "+degrees(C));
    print("Theta_2 : ");
    println((Theta_2));
    print("Theta_1      : ");
    println((Theta_1));  
    print("Theta_2_test : ");
    println(Theta_2_test);
    print(" P1_M  = ");
    println(P1_M);
    print("bielle           : ");
    println(L);
    println("bielle Effective : "+PVector.dist(P1, P2));
    println(flag*(angle));
    println("x = "+x+"; y = "+y);
    println(P1);
    println(P2);
    println();
    println();
  }
}

void keyReleased(){ //_______________________________________add
 if (key == ' ') dbug=!dbug;  
}

I also commented on the changes

not works out,
my idea was just to say
l2 = l2 + Dec_Piv_aile;

and not use it in the later angle calc as that goes wrong!

i did for me add a plot on A and C for more understanding, possibly helps you
to find the mistake?

  if (dbug) {  //_______________________________________add as graph
    stroke(255);
    line(100+dgx+1, -180, 100+dgx+1, 150);  // clean up
    stroke(#FC96FC); //rose
    ellipse(100+dgx, y-X, 1, 1);  // KLL as graph
    stroke(200,0,0);
    ellipse(100+dgx, 10*A-2*X, 1, 1);  // KLL as graph   show A
    ellipse(100+dgx, 10*C-2*X, 1, 1);  // KLL as graph   show C
  }

this picture shows that with Dec_Piv_aile > 0
your flag ( red line ) logic is wrong!

snap-086

To give me a different look on the skit and to give me some ideas that I will not think about are already of great help to me.

Thank’s :hugs: