Please feel free to "do the math" and prove me wrong.
I've attached a simulation that I did using Maple.
Here is the Maple code:
---attempt01.txt
restart:
with(plots):
setoptions(scaling=constrained):
printf("For the mass track, use a 2-dimensional circle, centered at the origin (0, 0), with radius='RADIUS'.\n");
printf("Let the mass arm be rotating at 'RPM' rotations per minute.\n");
printf("Put the center of rotation of the mass arms at (0, OFFSET).\n");
printf("Put one end of the rotating arm at point P on the circle.\n");
printf("Let 'L'=the length from (0, OFFSET) to P.\n");
printf("Let 'A' be the angle between lines (0, 0) to (0, OFFSET), and (0, OFFSET) to P.\n\n");
printf("Using the Law of Cosines for the triangle formed by the above points, we get the following equation:\n");
printf("\tRADIUS*RADIUS = OFFSET*OFFSET+L*L-2*OFFSET*L*cos(A)\n");
EQN01 := RADIUS*RADIUS = OFFSET*OFFSET+L*L-2*OFFSET*L*cos(A):
ANS_EQN01 := solve(EQN01, L):
L := A -> OFFSET*cos(A) + sqrt(RADIUS*RADIUS+OFFSET*OFFSET*(cos(A)*cos(A)-1)):
printf("Solving '%a' for 'L' gives us:\n\tL(A)=%a\nand\n\tL(A)=%a\n\n", EQN01, ANS_EQN01[1], ANS_EQN01[2]);
printf("Let us use the first solution for L:\n\tL(%a)=%a\n\n", A, L(A));
Px_A := A -> L(A)*sin(A):
Py_A := A -> OFFSET-L(A)*cos(A):
printf("Using the relationship between the sides of our triangle, and angle A, we get the position of point P as a function of angle A:\n\tPx_A(A)=%a\n\tPy_A(A)=%a\n\n", Px_A(A), Py_A(A));
A := t -> t*(2*Pi)/RPM:
Px := t -> simplify(Px_A(A(t))):
Py := t -> simplify(Py_A(A(t))):
Vx := t -> simplify(diff(Px(t), t)):
Vy := t -> simplify(diff(Py(t), t)):
Ax := t -> simplify(diff(Vx(t), t)):
Ay := t -> simplify(diff(Vy(t), t)):
Sx := t -> simplify(diff(Ax(t), t)):
Sy := t -> simplify(diff(Ay(t), t)):
printf("Angle A is a function of time:\n\tA(t)=%a\n\n", A(t));
printf("Position of point P as a function of time:\n\tPx(t)=%a\n\tPy(t)=%a\n\n", Px(t), Py(t));
printf("Velocity vector at of point P as a function of time:\n\tVx(t)=%a\n\tVy(t)=%a\n\n", Vx(t), Vy(t));
printf("Acceleration vector at of point P as a function of time:\n\tAx(t)=%a\n\tAy(t)=%a\n\n", Ax(t), Ay(t));
printf("Surge vector at of point P as a function of time:\n\tSx(t)=%a\n\tSy(t)=%a\n\n", Sx(t), Sy(t));
RADIUS := 5: # 10" diameter mass track
OFFSET := RADIUS/2: # arbitrary
RPM := 1:
Alpha := 0: # do one full pass around the mass track
Omega := 1:
Curve := plot([Px(t), Py(t), t=Alpha..Omega], style=line, color=blue, thickness=2):
NumFrames := 30:
t := i -> Alpha + i*(Omega-Alpha)/NumFrames:
VScale := 0.1: # arbitrary
AScale := 0.01: # arbitrary
SScale := 0.001: # arbitrary
Points := display(seq(pointplot([Px(t(i)), Py(t(i))], style=point, symbol=circle, symbolsize=17, color=black), i=0..NumFrames), insequence=true):
VVectors := display(seq(arrow([Px(t(i)), Py(t(i))], VScale*<eval(Vx(a), a=t(i)), eval(Vy(a), a=t(i))>, width=.02, color=red), i=0..NumFrames), insequence=true):
AVectors := display(seq(arrow([Px(t(i)), Py(t(i))], AScale*<eval(Ax(a), a=t(i)), eval(Ay(a), a=t(i))>, width=.02, color=red), i=0..NumFrames), insequence=true):
SVectors := display(seq(arrow([Px(t(i)), Py(t(i))], SScale*<eval(Sx(a), a=t(i)), eval(Sy(a), a=t(i))>, width=.02, color=red), i=0..NumFrames), insequence=true):
printf("Here are some graphs following the point P for one full revolution of the mass arm, using the following values:\n\tRADIUS=%f\n\rOFFSET=%f\n\tRPM=%f\n\n", RADIUS, OFFSET, RPM);
display(Curve, Points, title="Mass Path");
display(Curve, VVectors, AVectors, title="Velocity+Acceleration");
display(Curve, AVectors, SVectors, title="Acceleration+Surge");