Code covered by the BSD License  

Highlights from
Curtains

image thumbnail
from Curtains by Nicolas Petit
Real-time simulation of waving sliding curtains.

curtains.m
% CURTAINS
%
% Centre Automatique et Systmes
% MINES ParisTech 
% 
% Nicolas Petit 2009
%
% nicolas.petit@mines-paristech.fr
%
% move the mouse and watch the curtains slide and wave

clear all;  
L=1.;  % rope  length in  m
A_max= 1.5*L ; % amplitude of horizontal motion  depth  in  m
g=9.81; % garvity in  m/s^2
T_max=2*sqrt(A_max/g);  % interval of motion (s)
DT=2*sqrt(L/g);
scale=min(11., 11/max(A_max*14/19,L)); 

% space mesh 
dx=L/40.;
x=[0:dx:L];
nx=length(x);
H=zeros(1,nx);
% time step 
dt0=DT/50;
dt=dt0; 
dtmin=DT/1000;
dtmax=DT/3.;

YY=0*[-DT:dt0:DT];
mt=length(YY);
m0=(mt+1)/2.;
mm=[1:mt-1];

Y=0*[-5*DT:dt:0]; D=Y;t=Y;
nt=length(Y);
nn=[1:nt-1];





figure(1),clf;
          

   
%  trolley

Xt=1+[0   1  1  0  ]+scale*H(nx);
Yt=12+[0   0  1/2  1/2  ];
trol=fill(Xt,Yt,'g');


% cable

Xc=1.5 + scale*H;
Yc=12+scale*(x-1);
lw=2;
% chain=line(Xc,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain2=line(Xc+1,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain3=line(Xc+2,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain4=line(Xc+3,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain5=line(Xc+4,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain6=line(Xc+5,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain7=line(Xc+6,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain8=line(Xc+7,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain9=line(Xc+8,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);
% chain10=line(Xc+9,Yc,'LineWidth', lw, 'Color', [0 0 0 ]);

bigtable=ones(100,1)*Xc;

%  ref
Xr=1+[0   1  0.5  0  ] + scale*H(nx);
Yr=0.3+[0   0  1/2  0  ];
%ref=fill(Xr,Yr,'k','EraseMode','background');


set(gcf,'WindowButtonMotionFcn','1;');


% Hplay=uicontrol('style','push',...
%                 'units','normalized','position',[15/19 12.6/14 2/19 .5/14], ....
%                 'string','Plot','callback', ...
%                 ['figure(2);clf;' ...
%                  'subplot(211);' ...
%                  'plot(t,Y);'...
%                  'title(''flat output  (m) versus time'');'...
%                  'subplot(212);'...
%                  'plot(t,D);'...
%                  'title(''troley position (m/s)versus time''); pause(2);figure(1);'...
%                 ]);
%              
% set(Hplay,'visible','off');
%              
% Hrun=uicontrol('style','push',...
%                 'units','normalized','position',[1/19 12.7/14 2/19 .5/14], ....
%                 'string','stop','callback', ...
%                 ' ; ' ,'visible','off');
%              
             
             
             
  % title
% text(9.5,13.5,'HEAVY CHAIN: MOUSE-DRIVEN MOTION PLANNING','color',[0 0 0],...
%    'HorizontalAlignment','center');
% text(9.5,13,'display speed slider','color',[0 0 0],'HorizontalAlignment','center');
p1=[7.5/19 12.6/14 4/19 0.2/14];
% Hslider=uicontrol(figure(1),'units','normalized','style','slider','position',p1,...
% 			'min',log(dtmin),'max',log(dtmax),'value',log(dt0),...
%          'callback',['buf=get(Hslider,''value'');dt=exp(buf);']); 
           
             
             
             

figure(1);
%pause(1)
% set(Hrun,'string','Stop','callback','i=2;');
% set(Hplay,'visible','on')
% set(Hrun,'visible','on')



set(GCF,'renderer','opengl')

st=.1*3;
tt=0:st:(2*pi); tt2=(0-pi/6):st/2:(2*pi-pi/6);
cx=[cos(tt) 1]; cy=[sin(tt) 0]; cx2=cos(tt2); cy2=sin(tt2);

mx=[]; my=[];

lfond=size(cx2);
mx2=[cx2 fliplr(cx2)]; my2=[cy2 fliplr(cy2)]; fond=zeros(lfond);
cx3=[cx2; cx2]; cy3=[cy2; cy2];
ggg=zeros(size(cx2));



t1=T_max/5/10;
t2=t1;
seuil=A_max/5;
y1=0;
y2=0;

i=0;

dth=pi/100;
th=[0:dth:pi];
Sth=sin(th);

tt=0.;
y1_old=y1;

re=4;
damp=.9;

MATY=ones(19,1)*Yc;
   MATZ=.5*[1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1 -1 1]'*ones(size(Xc));
plancher=surf([0,0,36,36],[-3 3 3 -3],2+zeros(4,4),zeros(4,4)-100)
   curtain=surface(MATY*0,MATZ,MATY,ones(size(MATZ)));
 curtain2=surface(MATY*0,MATZ,MATY,ones(size(MATZ)));
  % axis([-3,33, -3, 3, 0, 12]*1.2);
light('position',[0,-2,10])
light('position',[33,-2,10])
light('position',[0,-2,10])
tringle=line([0, 36],[0 0],[0,0]+max(Yc)+.1); set(tringle,'linewidth',4);
ind=0;
% hold on
% colonne1=surface(cx3,cy3,16/2*[ggg; 2*ones(size(cy2))],[ggg; 2*ones(size(cy2))]*10);
% top1=surface(cx3(1,:),cy3(1,:),16*ones(max(size(cx3)),max(size(cx3))))
% colonne2=surface(36+cx3,cy3,16/2*[ggg; 2*ones(size(cy2))],[ggg; 2*ones(size(cy2))]*10);
% top2=surface(36+cx3(1,:),cy3(1,:),16*ones(max(size(cx3)),max(size(cx3))))
% hold off
% material metal
% axis equal
while (i < 1)
   ind=ind+.1;
   wind=(sin(ind))*5;
   
    buf=get(gca,'CurrentPoint');
  % ref=[ min(3,max(-3,buf(2,1))) ; min(2.5,max(-2.5,buf(2,2))) ] ;
   ref=[ min(16.5,max(0,buf(2,1))) ] ;
   A=ref(1)+wind*0;
   
  %  buf=get(gca,'CurrentPoint');
  %  A=(buf(1,1)-1.5)/scale;
    A=max(0,A);
    A=min(16.5,A); 
    
   y1=(y1+dt*y2/t1)/(1+dt/t1);
   t2b=t2*max(1,abs(A-y2)/seuil);
   y2=(y2+dt*A/t2b)/(1+dt/t2b);
   
   tt=tt+dt;
   if (tt >= dt0);
      ii=floor(tt/dt0);
      dy1=(y1-y1_old)/tt;
      for iii=1:ii;
         YY(mm)=YY(mm+1);YY(mt)=y1_old+iii*dt0*dy1;
      end;
      y1_old=y1-dy1*(tt-ii*dt0);
      tt=0.;
   end;
    
    
    for ix=1:nx;
       tau=2*sqrt(x(ix)/g);
       s=tau*Sth;
       ns=floor((mt-m0)*s/DT);
       H(ix)=(dth/2/pi)*sum(YY(m0+ns)+YY(m0-ns));
    end   

    
    
    Y(nn)=Y(nn+1); Y(nt)=H(1);
    D(nn)=D(nn+1); D(nt)=H(nx);
    t(nn)=t(nn+1); t(nt)=t(nt)+dt;
 
    scale=1;
    
    Xt=1+[0   1  1  0  ] + scale*H(nx);
    Xr=1+[0   1  0.5  0  ] + scale*A;
    Xc= scale*H;
    bigtable=[bigtable(2:100,:); Xc-Xc(41)];
   
    
%     set(trol, 'XData',Xt); 
%     set(chain,'XData',Xc); 
%     set(chain2,'XData',(bigtable(100-re,:)*damp+Xc(41))*(1-1/9)); 
%     set(chain3,'XData',(bigtable(100-2*re,:)*damp^2+Xc(41))*(1-2/9)); 
%     set(chain4,'XData',(bigtable(100-3*re,:)*damp^3+Xc(41))*(1-3/9)); 
%     set(chain5,'XData',(bigtable(100-4*re,:)*damp^4+Xc(41))*(1-4/9)); 
%     set(chain6,'XData',(bigtable(100-5*re,:)*damp^5+Xc(41))*(1-5/9)); 
%     set(chain7,'XData',(bigtable(100-6*re,:)*damp^6+Xc(41))*(1-6/9)); 
%     set(chain8,'XData',(bigtable(100-7*re,:)*damp^7+Xc(41))*(1-7/9)); 
%     set(chain9,'XData',(bigtable(100-8*re,:)*damp^8+Xc(41))*(1-8/9)); 
%     set(chain10,'XData',(bigtable(100-9*re,:)*damp^8+Xc(41))*0); 
   
   MATX=[Xc;...
           (bigtable(100-.5*re,:)*damp^.5+Xc(41))*(1-.5/9); ...
   (bigtable(100-re,:)*damp+Xc(41))*(1-1/9); ...
   (bigtable(100-1.5*re,:)*damp^1.5+Xc(41))*(1-1.5/9); ...
   (bigtable(100-2*re,:)  *damp^2  +Xc(41))*(1-2/9); ...
   (bigtable(100-2.5*re,:)*damp^2.5+Xc(41))*(1-2.5/9); ...
   (bigtable(100-3*re,:)  *damp^3  +Xc(41))*(1-3/9); ...
   (bigtable(100-3.5*re,:)*damp^3.5+Xc(41))*(1-3.5/9); ...
   (bigtable(100-4*re,:)  *damp^4  +Xc(41))*(1-4/9); ...
   (bigtable(100-4.5*re,:)*damp^4.5+Xc(41))*(1-4.5/9); ...
   (bigtable(100-5*re,:)  *damp^5  +Xc(41))*(1-5/9); ...
   (bigtable(100-5.5*re,:)*damp^5.5+Xc(41))*(1-5.5/9); ...
   (bigtable(100-6*re,:)  *damp^6  +Xc(41))*(1-6/9); ...
   (bigtable(100-6.5*re,:)*damp^6.5+Xc(41))*(1-6.5/9); ...
   (bigtable(100-7*re,:)  *damp^7  +Xc(41))*(1-7/9); ...
   (bigtable(100-8.5*re,:)*damp^7.5+Xc(41))*(1-7.5/9); ...
   (bigtable(100-8*re,:)  *damp^8  +Xc(41))*(1-8/9); ...
   (bigtable(100-9.5*re,:)*damp^8.5+Xc(41))*(1-8.5/9); ...
   (bigtable(100-9*re,:)  *damp^9  +Xc(41))*0; ...
         ];
   
   
  set(curtain,'Xdata',1.5+MATX);
  set(curtain2,'Xdata',34.5-MATX);
    %set(ref,'XData',Xr); 
    drawnow;
   
end;


close(figure(1));
close(figure(2));

return

Contact us at files@mathworks.com