LeonBrick
LeonBrick

Reputation: 41

Rotating a spring in 2D space

I have a nice implementation of a spring that can move along an axis X.

plot (N - number of spring turns):

t=0:0.01:20;
alpha=0:0.01:2*pi;
N=10;
h=4;
R=0.25;
for i=1:N
    Xpr(i)=(i-1)*1/(N-1);
    if i==1
        Ypr(i)=2.5*R+h;
    elseif i==N
        Ypr(i)=2.5*R+h;
    else
        Ypr(i)=2.5*R+h/2+h/4*(-1)^i;
    end
end
Spring=plot(Xpr*2,Ypr);

animation:

t=0:0.01:20;
alpha=0:0.01:2*pi;
x0=1;
x=x0+0.3*cos(alpha);
for i=1:length(t)  
    set(Spring,'Xdata',Xpr*x(i));  
    pause(0.01);
end

I need to spin this spring clockwise on plane. One end is fixed. How to do it?

There a lot ways have been tried. None of them is worked. Idea of animation's implementation was in using Rotate matrix. Like this:

function L = Rot2D (Vers, phi)
    L(1,:) = Vers(1,:)*cos(phi)-Vers(2,:)*sin(phi)
    L(2,:) = Vers(1,:)*sin(phi)+Vers(2,:)*cos(phi)
endfunction

Then pack each of the coils of the spring into a vector:

N=10;
h=4;
R=0.25;    
for i=1:N
    Xpr(i)=(i-1)*1/(N-1);
    if i==1
        Ypr(i)=2.5*R+h;
        SpringVector=[Xpr(i);Ypr(i)];
    elseif i==N
        Ypr(i)=2.5*R+h;
        newElem=[Xpr(i);Ypr(i)];
        SpringVector=[SpringVector; newElem];
    else
        Ypr(i)=2.5*R+h/2+h/4*(-1)^i;
        newElem=[Xpr(i);Ypr(i)];
        SpringVector=[SpringVector; newElem];
    end
end

After that invocation Rot2D has shown nothing:

y0=1;
y=y0+cos(alpha);
N=10;    
for i=1:N
    phi=-acos(y(i)-1);
    RotArrSpring=Rot2D(SpringVector,phi);
    set(Spring,'XData', RotArrSpring(1,:)*x(i), 'YData', RotArrSpring(2,:)*y(i));
    pause(0.01);
end

How to solve this problem?

Upvotes: 2

Views: 108

Answers (2)

LeonBrick
LeonBrick

Reputation: 41

Thanks for all answers. I learned how to turn the spring at an angle.

First, set up a spring

for i=1:N % N number of spring turns
Xpr(i)=(i-1)*1/(N-1);
if i==1
Ypr(i)=1.5*R+H;
elseif i==N
Ypr(i)=1.5*R+H;
else
Ypr(i)=1.5*R+H/2+H/4*(-1)^i;
end
end   
Spring=cat(1,Xpr*L,Ypr*L)
alpha=atan2(yA(1),L); % I'll explain in animation
RSpring=Rot2D(Spring,0)
RealSpring=plot(RSpring(1,:),RSpring(2,:)+h);

Rot2D:

function A = Rot2D (Vers, phi)
  A(1,:) = Vers(1,:) .* cos(phi) - Vers(2,:) .* sin(phi)
  A(2,:) = Vers(1,:) .* sin(phi) + Vers(2,:) .* cos(phi)
endfunction

Then, go to animation. Let we have a point balancing on Y. The spring is directed towards it

for i=1:length(t)
  anmPntAy = yA+y(i); %cordinate of our point.
  set(PointA,'Ydata',anmPntAy);
  
  alpha(end+1)=atan2(anmPntAy(end),L); % get an angle
  RSpring=Rot2D(Spring,-alpha(end)); % rotate our spring
  set(RealSpring,'Xdata',RSpring(1,:),'Ydata',RSpring(2,:)+h); % animate spring 

  pause(0.01);
end

Finally example:

t=0:0.01:20;
x0=2;
alpha=0:0.01:2*pi;
x0=1;
x=x0+0.3*cos(alpha);
x01=7;
x1=x01-0.3*cos(alpha);
y0=1;
y=y0+cos(alpha);
L=3;
N=10;
H=4;
R=0.15;

h=6;  
a=2;  
l=4; 
 
 

figure 
xlim([-1 10])
ylim([-2 10])
xlim manual
ylim manual
axis equal
hold on
addpath(pwd) %sometimes Rot2D don't want to be invoked

xA=4; 
yA=h-1-y; 
PointA=plot(xA,yA(1),'o'); 

% Spring
for i=1:N
Xpr(i)=(i-1)*1/(N-1);
if i==1
Ypr(i)=1.5*R+H;
elseif i==N
Ypr(i)=1.5*R+H;
else
Ypr(i)=1.5*R+H/2+H/4*(-1)^i;
end
end
Spring=cat(1,Xpr*L,Ypr*L)
alpha=atan2(yA(1),L);
RSpring=Rot2D(Spring,0)
RealSpring=plot(RSpring(1,:),RSpring(2,:)+h);

for i=1:length(t)
  anmPntAy = yA+y(i);  
  set(PointA,'Ydata',anmPntAy);
  
  alpha(end+1)=atan2(anmPntAy(end),L);
  RSpring=Rot2D(Spring,-alpha(end));
  set(RealSpring,'Xdata',RSpring(1,:)*x(i),'Ydata',RSpring(2,:)+h);  
  pause(0.01);
end

Yes, it's not a beautiful animation but changing some parameters 'll do it good. The most important thing is the result - rotation of spring.

Upvotes: 2

user158881
user158881

Reputation: 133

just finished ...

t=0:0.01:20;
alpha=0:0.01:2*pi;
N=10;
h=4;
R=0.25;
for i=1:N
    Xpr(i)=(i-1)*1/(N-1);
    if i==1
        Ypr(i)=2.5*R;
    elseif i==N
        Ypr(i)=2.5*R;
    else
        Ypr(i)=2.5*R+h/2+h/4*(-1)^i;
    end
end
Spring=plot(Xpr*2,Ypr);

t=0:0.01:20;
alpha=0:0.01:2*pi;
x0=1;
x=x0+0.3*cos(alpha);
T_rotation = 0.002 ; 

for i=1:length(t)  

    % go polar and rotate
    [theta,rho] = cart2pol(Xpr*x(i),Ypr-0.5);
    theta = theta + T_rotation * i;
    
    % go back to polar
    [x_rot,y_rot] = pol2cart(theta,rho);
    y_rot = y_rot+0.5;
    set(Spring,'Xdata',x_rot);
    set(Spring,'Ydata',y_rot);
%     set(Spring,'Xdata',Xpr*x(i));
    
    xlim([-4,4])
    ylim([-4+0.5,4+0.5])
    pause(0.01);
end

Upvotes: 0

Related Questions