Skip to main content
Bounty Ended with 150 reputation awarded by Calvin's Hobbies
50 bonus
Source Link
feersum
  • 31.5k
  • 9
  • 65
  • 125

#MATLAB: 735 bytes - 150200 bonus = 585535 My program handles the n=2 case and draws a real-time animation. There are a few differences between the golfed and ungolfed versions:

The ungolfed version only has an option to save the animation to a file 'g.gif', by setting savegif = 1 in the code. It is off by default as it can be annoying for a few reasons:

  • Creation of an unwanted file
  • Possible lag
  • An error is generated if you have multiple monitors and the plot window is not on the right one... The gif saving had to be dropped in the golfed version as it took about 100 bytes, exceeding the size of the bonus.The gif saving had to be dropped in the golfed version as it took about 100 bytes, exceeding the size of the bonus.

Edit: Added bonus of 50 for animated image.

#MATLAB: 735 bytes - 150 bonus = 585 My program handles the n=2 case and draws a real-time animation. There are a few differences between the golfed and ungolfed versions:

The ungolfed version has an option to save the animation to a file 'g.gif', by setting savegif = 1 in the code. It is off by default as it can be annoying for a few reasons:

  • Creation of an unwanted file
  • Possible lag
  • An error is generated if you have multiple monitors and the plot window is not on the right one... The gif saving had to be dropped in the golfed version as it took about 100 bytes, exceeding the size of the bonus.

#MATLAB: 735 bytes - 200 bonus = 535 My program handles the n=2 case and draws a real-time animation. There are a few differences between the golfed and ungolfed versions:

The ungolfed version only has an option to save the animation to a file 'g.gif', by setting savegif = 1 in the code. It is off by default as it can be annoying for a few reasons:

  • Creation of an unwanted file
  • Possible lag
  • An error is generated if you have multiple monitors and the plot window is not on the right one... The gif saving had to be dropped in the golfed version as it took about 100 bytes, exceeding the size of the bonus.

Edit: Added bonus of 50 for animated image.

Source Link
feersum
  • 31.5k
  • 9
  • 65
  • 125

#MATLAB: 735 bytes - 150 bonus = 585 My program handles the n=2 case and draws a real-time animation. There are a few differences between the golfed and ungolfed versions:

The ungolfed version has an option to save the animation to a file 'g.gif', by setting savegif = 1 in the code. It is off by default as it can be annoying for a few reasons:

  • Creation of an unwanted file
  • Possible lag
  • An error is generated if you have multiple monitors and the plot window is not on the right one... The gif saving had to be dropped in the golfed version as it took about 100 bytes, exceeding the size of the bonus.

The ungolfed version draws a circle on the tracer vertex. It also produces more frames and moves faster (though this can be adjusted in the golfed version by changing the numbers). ##Samples:

f(11,5,90,2,99,0) after program termination

golfed sample

epic(1.3,4,2,6,6,1) with gif output

ungolfed sample

##Ungolfed code

%epicyclogon animation outputs to 'g.gif' if savegif=1 as well as animating in real time

function[] = epic(r,r1,r2,n1,n2,dispPoly)

savegif = 0;  %set to 1 to write .gif

cs = @(a) [cos(a);sin(a)];
vert = @(r, n, v) r * cs(2*pi*v/n);
polyPt = @(l, s, n, r) vert(r, n, floor(l/s)) + mod(l/s,1)*(vert(r, n, floor(l/s)+1) - vert(r, n, floor(l/s)));
polyPt2 = @(i, f, n, r) vert(r, n, i) + f*(vert(r, n, i+1) - vert(r, n, i));
rotm = @(a) [cos(a) -sin(a);sin(a) cos(a)];
arrpluspt = @(a, p) a + kron(p, ones(1,length(a)));
arg = @(p) atan2(p(2), p(1));

E = 1e-9;

dispPoly = dispPoly / dispPoly;

sgn = sign(-r);
r = abs(r);

s1 = 2*r1*sin(pi/n1);
s2 = 2*r2*sin(pi/n2);

%d1 = (r1*r1 - s1*s1*.25)^.5;
d2 = (r2*r2 - s2*s2*.25)^.5;

plotmax = r1+2*r2;

astep = .05; %determines amount of frames per rotation
delay = .01; % time per frame

l = 0;

lRem = 0;
lr = 0;

P1 = vert(r1, n1, 1:n1+1) * dispPoly; 
trace = [];

first = 1;
while 1
    
    if lr %exists while rotating about a corner of the stationary
        rotA = 2*pi/n1;
    else
        rotA = 2*pi/n2;
    end
    rotPt = polyPt(l, s1, n1, r1);
    lb = l + lRem;
    side1 = floor(l / s1 - E);
    side1up = side1 + lr;
    p2cen = polyPt2(side1, lb/s1 -side1 - .5 * s2/s1, n1, r1) + d2 * cs(2*pi*(side1+.5)/n1);
    if first
        p2cen0 = p2cen;
        r = r + arg(p2cen0)/(2*pi);
    end
   
    for a = 0:astep:rotA    
        P2 = vert(r2, n2, 0:n2);
        P2 = rotm( pi +pi/n1 -pi/n2   +2*pi*side1/n1) * P2;
        P2 = arrpluspt(P2, p2cen);
        P2 = arrpluspt(P2, -rotPt);
        P2 = rotm(a) * P2;
        P2 = arrpluspt(P2, rotPt);
        trV = mod(floor(l/s2 + E) + lr, n2) + 1;

        cen = rotm(a) * (p2cen - rotPt) + rotPt;
        trace = [trace,P2(:,trV)]; 
  
        plot(P1(1,:), sgn*P1(2,:), P2(1,:)*dispPoly, sgn*P2(2,:)*dispPoly, trace(1,:),sgn*trace(2,:),P2(1,trV), sgn*P2(2,trV),'o');
      
        %plot(P1(1,:), P1(2,:), P2(1,:), P2(2,:), trace(1,:),trace(2,:),...
        %[0,p2cen0(1)],[0,p2cen0(2)],[0,cen(1)],[0,cen(2)], P2(1,trV), P2(2,trV),'o');

        axis([-plotmax,plotmax,-plotmax,plotmax]);
        axis square
        figure(1);
       if savegif
           drawnow
           frame = getframe(1); % plot window must be on same monitor!
           img = frame2im(frame);
           [img1,img2] = rgb2ind(img,256);
       end
       if first
           if savegif
               imwrite(img1,img2,'g','gif','DelayTime',2*delay); %control animation speed(but not really)
           end
           first = 0;
       else
           if savegif
               imwrite(img1,img2,'g','gif','WriteMode','append','DelayTime', 2*delay);
           end
       end
       pause(.01);

        adf = mod(arg(cen) - r*2*pi, 2*pi);
        if adf < astep & l/(n1*s1) + .5 > r
            return
        end

    end

%cleanup for next iteration 
    jump = lRem + ~lr * s2; 
    lnex = l + jump; 

    if floor(lnex / s1 - E) > side1up 
        lnex = s1*(side1up+1);
        lRem = jump - (lnex - l);
        lr = 1;
    else    
        lRem = 0;
        lr = 0;
    end
    l = lnex;
end

##Golfed code

function[]=f(r,h,H,n,N,d)
P=pi;T=2*P;F=@floor;C=@(a)[cos(a);sin(a)];g=@(i,f,n,r)r*C(T*i/n)*(1-f)+f*r*C(T*(i+1)/n);R=@(a)[C(a),C(a+P/2)];W=@(a,p)[a(1,:)+p(1);a(2,:)+p(2)];b=@(p)atan2(p(2),p(1));E=1e-9;d=d/d;S=1-2*(r>0);r=-r*S;x=2*h*sin(P/n);X=2*H*sin(P/N);M=h+2*H;l=0;z=0;L=0;A=h*C(T*(0:n)/n)*d;t=[];while 1
v=l/x;D=F(v-E);q=g(D,v-D,n,h);Z=D+L;c=g(D,v+z/x-D-.5*X/x,n,h)+H*cos(P/N)*C(T*D/n+P/n);r=r+~(l+L)*b(c)/T;for a=0:.1:T/(L*n+~L*N)
O=@(p)W(R(a)*W(p,-q),q);B=O(W(R(P+P/n-P/N+T*D/n)*H*C(T*(0:N)/N),c));t=[t,B(:,mod(F(l/X+E)+L,N)+1)];plot(A(1,:),S*A(2,:),d*B(1,:),d*S*B(2,:),t(1,:),t(2,:)*S)
axis([-M,M,-M,M],'square');pause(.1);if.1>mod(b(O(c))-r*T,T)&v/n+.5>r
return;end;end;j=z+~L*X;J=l+j;L=F(J/x-E)>Z;l=L*x*(Z+1)+~L*J;z=L*(J-l);end

##Instructions: Save the function to a file with the same name, i.e. epic.m or f.m. Run it by calling the function from the Matlab console.

Usage: epic(r, r1, r2, n1, n2, dispPoly) where dispPoly is a Boolean variable (zero if false, a nonzero number if true) determining whether to draw the polygons.