MATLAB : 735 바이트-200 보너스 = 535
내 프로그램은 n = 2 경우를 처리하고 실시간 애니메이션을 그립니다. 골프와 언 골프 버전 사이에는 몇 가지 차이점이 있습니다.
ungolfed 버전 savegif = 1
에는 코드에서 설정하여 애니메이션을 파일 'g.gif'에 저장하는 옵션 만 있습니다 . 몇 가지 이유로 성 가실 수 있으므로 기본적으로 꺼져 있습니다.
- 원치 않는 파일 생성
- 가능한 지연
- 여러 개의 모니터가 있고 플롯 창이 올바른 모니터에없는 경우 오류가 발생합니다
. gif 저장은 보너스 크기를 초과하는 약 100 바이트가 걸리므로 골프 버전에서 삭제해야했습니다.
ungolfed 버전은 트레이서 정점에 원을 그립니다. 또한 더 많은 프레임을 생성하고 더 빠르게 움직입니다 (골프 버전에서는 숫자를 변경하여 조정할 수 있음).
시료:
f(11,5,90,2,99,0)
프로그램 종료 후
epic(1.3,4,2,6,6,1)
gif 출력
Ungolfed 코드
%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
골프 코드
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
명령:
같은 이름의 파일에 함수를 저장하십시오 (예 : epic.m
또는) f.m
. Matlab 콘솔에서 함수를 호출하여 실행하십시오.
사용법 : epic(r, r1, r2, n1, n2, dispPoly)
여기서 dispPoly
폴리곤을 그릴 지 여부를 결정하는 부울 변수 (거짓이면 0, 참이면 0이 아닌 숫자)입니다.
편집 : 애니메이션 이미지에 50의 보너스가 추가되었습니다.