Met een beetje google-fu heb ik de volgende matlab code gevonden, niet zo gelikt als het orgineel maar het punt is duidelijk
Code: Selecteer alles
%% define the batman equation
BatmanEq = @(x,y) ...
((x/7)^2*sqrt(abs(abs(x)-3)/(abs(x)-3)) + (y/3)^2*sqrt(abs(y+3*sqrt(33)/7)/(y+3*sqrt(33)/7))-1) ...
* (abs(x/2)-((3*sqrt(33)-7)/112)*x^2 -3 +sqrt(1-(abs(abs(x)-2)-1)^2) -y) ...
* (9*sqrt(abs((abs(x)-1)*(abs(x)-0.75))/((1-abs(x))*(abs(x)-0.75))) -8*abs(x) -y) ...
* (3*abs(x) + 0.75*sqrt(abs((abs(x)-0.75)*(abs(x)-0.5))/((0.75-abs(x))*(abs(x)-0.5))) -y) ...
* (2.25*sqrt(abs((x-0.5)*(x+0.5))/((0.5-x)*(0.5+x))) -y) ...
* (6*sqrt(10)/7 + (1.5-0.5*abs(x))*sqrt(abs(abs(x)-1)/(abs(x)-1)) -6*sqrt(10)/14*sqrt(4-(abs(x)-1)^2) -y);
%% Calculate X- and Y-array defining the Batman logo
% set x-points
xx = (-7.1:0.01:7.1);
% init y line arrays
yy_pos = nan(size(xx));
yy_neg = nan(size(xx));
% set the range of y values to scan for the line
y_scan = 0:0.01:3;
% init Batman equation value arrays
EqValue = zeros(size(y_scan));
% Find y-values for each x-point
for ii = 1:length(xx)
% POSITIVE Y VALUES:
% calculate equation values for a vertical line of (x,y)-coordinates
% Note that EqValues have also imaginary part!
for jj = 1:length(y_scan)
EqValue(jj) = BatmanEq(xx(ii), y_scan(jj));
end
% Find y-coordinate around which the abs(EqValue) minimizes.
[~, mini] = min(abs(EqValue));
% list indices around that minimum
ind = max(mini-2, 1):min(mini+2,length(y_scan));
% Although the batman logo "looks" continuous, it has breaks where it is
% not defined (0 over 0 e.g. at x==3). We cannot interpolate in those
% places.
if any(isnan(EqValue(ind)))
yy_pos(ii) = nan;
else
% Use interpolation to find the Eq==0 point more accurately.
% Spline interpolation works best here:
% Spline interpolation likely finds also the points where eq gets
% values [+,0,+] or [-,0,-] (as oppose to only [-,0,+] or [+,0,-]
% found by the other methods). However, spline does not perform
% well with sharp corners. Thus interp of abs(EqValue) will not
% work as most zero points are in sharp corners thus using
% real(EqValue) is preferred.
yy_pos(ii) = interp1(real(EqValue(ind)), y_scan(ind), 0, 'spline');
% Interpolation using only real part of the eq value, may lead to
% totally false values in some circumstances. Thus we must make sure
% that absolute value of the Eq value is lower than treshold.
if abs(BatmanEq(xx(ii), yy_pos(ii))) > 1
yy_pos(ii) = nan;
end
end
% NEGATIVE Y VALUES:
% Exactly same as with positive but:
% 'y_scan' -> '-y_scan')
% 'yy_pos' -> 'yy_neg')
for jj = 1:length(y_scan)
EqValue(jj) = BatmanEq(xx(ii), -y_scan(jj));
end
[~, mini] = min(abs(EqValue));
ind = max(mini-2, 1):min(mini+2,length(y_scan));
if any(isnan(EqValue(ind)))
yy_neg(ii) = nan;
else
yy_neg(ii) = interp1(real(EqValue(ind)), -y_scan(ind), 0, 'spline');
if abs(BatmanEq(xx(ii), yy_neg(ii))) > 1
yy_neg(ii) = nan;
end
end
end
% build plot arrays and ignore nan values
nan_filter_pos = find(~isnan(yy_pos));
nan_filter_neg = find(~isnan(yy_neg));
xx_plot = [xx(nan_filter_pos), xx(nan_filter_neg(end:(-1):1))];
yy_plot = [yy_pos(nan_filter_pos), yy_neg(nan_filter_neg(end:(-1):1))];
%% plot Batman logo
% init figure
clf
axis equal
% set background to yellow
set(gca, 'Color', 'y')
% patch the Batman logo
patch(xx_plot, yy_plot, [0,0,0], ...
'EdgeColor', 'r', ...
'LineWidth', 4, ...
'LineStyle', ':')