- #1
bnshrdr
- 3
- 0
I know there are programs out there that can do this already, but I want to keep sharp on my programming skills.
All I want to do is animate a grashof 4 bar mechanism. The program I wrote does this correctly for the most part. The problem is that when the crank gets around to around -45 degrees with the horizontal, my coupler link stretches for maybe about 20 degrees and then it goes and rotates how it should.
I have been pounding my head and just can't figure out where the problem in the code lies. I know I am asking a lot because my program is using formulas I derived on paper and they look rather sloppy. However it is commented and if anyone is willing to take a look I would appreciate it.
Here is a video of the mechanism:
Here is the code:
PS: I use the gnu libplot to do my plotting for me. Was pretty simple for me to figure out.
All I want to do is animate a grashof 4 bar mechanism. The program I wrote does this correctly for the most part. The problem is that when the crank gets around to around -45 degrees with the horizontal, my coupler link stretches for maybe about 20 degrees and then it goes and rotates how it should.
I have been pounding my head and just can't figure out where the problem in the code lies. I know I am asking a lot because my program is using formulas I derived on paper and they look rather sloppy. However it is commented and if anyone is willing to take a look I would appreciate it.
Here is a video of the mechanism:
Here is the code:
Code:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <plot.h>
int plotdata (double (*plot)[3][4], char (*fname)[10])
{
plPlotter *plotter;
plPlotterParams *plotter_params;
FILE *fp;
int buf = 1000;
plotter_params = pl_newplparams ();
pl_setplparam (plotter_params, "PAGESIZE", "letter");
fp = fopen(*(fname), "wb");
if ((plotter = pl_newpl_r ("png", stdin, fp, stderr, plotter_params)) == NULL)
{
fprintf (stderr, "Couldn't create Plotter\n");
return 1;
}
if (pl_openpl_r (plotter) < 0)
{
fprintf (stderr, "Couldn't open Plotter\n");
return 1;
}
pl_fspace_r (plotter, 0.0, 0.0, 3000.0, 3000.0);
pl_flinewidth_r (plotter, 0.25);
pl_pencolorname_r (plotter, "red");
pl_erase_r (plotter);
pl_line_r(plotter, buf, buf, (*plot)[0][2] + buf, (*plot)[0][3] + buf);
pl_line_r(plotter, (*plot)[0][2] + buf, (*plot)[0][3] + buf, (*plot)[1][2] + buf, (*plot)[1][3] + buf);
pl_line_r(plotter, (*plot)[1][2] + buf, (*plot)[1][3] + buf, (*plot)[2][2] + buf, (*plot)[2][3] + buf);
if (pl_closepl_r (plotter) < 0)
{
fprintf (stderr, "Couldn't close Plotter\n");
return 1;
}
if (pl_deletepl_r (plotter) < 0)
{
fprintf (stderr, "Couldn't delete Plotter\n");
return 1;
}
fclose(fp);
return 0;
}
int main (void)
{
double L0, L1, L2, L3, Ld, theta, theta2, phi;
double plot[3][4];
char fname[10];
int i;
L0 = 700;
L1 = 300;
L2 = 800;
L3 = 600;
/* theta = angle between ground and driver */
theta = M_PI;
for (i = 0; i < 72; i++)
{
/* decrease theta by 5 degrees each cycle */
theta = ((theta * 180 / M_PI) - 5) * M_PI / 180;
/* Ld = distance from end of driver to end of follower */
Ld = sqrt(pow(L0, 2) + pow(L1, 2) - (2*L0*L1*cos(theta)));
/* phi = angle between coupler and follower */
phi = acos((pow(L2, 2) + pow(L3, 2) - pow(Ld, 2)) / (2*L2*L3));
/* calculate angle between follower and ground outside of mechanism */
theta2 = M_PI - asin(L1/Ld*sin(theta)) - asin(L2/Ld*sin(phi));
/* coordinates for driver (x1,y1,x2,y2) */
plot[0][0] = 0;
plot[0][1] = 0;
plot[0][2] = L1*cos(theta);
plot[0][3] = L1*sin(theta);
/* coordinates for coupler (x1,y1,x2,y2) */
plot[1][0] = plot[0][2];
plot[1][1] = plot[0][3];
plot[1][2] = L0 + (L3*cos(theta2));
plot[1][3] = (L3*sin(theta2));
/* coordinates for follower (x1,y1,x2,y2) */
plot[2][0] = plot[1][2];
plot[2][1] = plot[1][3];
plot[2][2] = L0;
plot[2][3] = 0;
/* format the file name for plot */
itoa(i, fname, 10);
if (i > 9)
strcpy(fname+2, ".png");
else
strcpy(fname+1, ".png");
/* plot the data into a file */
plotdata(&plot, &fname);
}
return 0;
}
PS: I use the gnu libplot to do my plotting for me. Was pretty simple for me to figure out.
Last edited by a moderator: