Datei:Rohn Ellipsograph a.gif
aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen
Zur Suche springen
Rohn_Ellipsograph_a.gif (500 × 500 Pixel, Dateigröße: 2,81 MB, MIME-Typ: image/gif, Endlosschleife, 200 Bilder, 8,0 s)
Diese Datei und die Informationen unter dem roten Trennstrich werden aus dem zentralen Medienarchiv Wikimedia Commons eingebunden.
Beschreibung
BeschreibungRohn Ellipsograph a.gif |
English: Karl Rohn Ellipsograph (similar to the HAFF-Ellipsograph)
Deutsch: Ellipsenzeichner (Ellipsenzirkel) nach Karl Rohn (ähnlich dem HAFF-Ellipsograph).
Er funktioniert auf Basis der Papierstreifenkonstruktion 1. Art und verwendet hierfür die Idee der gleitenden Kreise.
|
Datum | |
Quelle | Eigenes Werk |
Urheber | Jahobr |
Andere Versionen |
|
GIF‑Erstellung InfoField | |
Quelltext InfoField | MATLAB codefunction Rohn_Ellipsograph()
% source code for drawing Rohn_Ellipsograph
% produces a GIF and a SVG
%
% 2017-05-28 Jahobr
p = 1;
nFrames = 200;
xySize = 500;
scaleReduction = 2; % reduction for nice antialiasing
angleSmall = linspace(0,2*pi,nFrames+1); % define gear position in frames
angleSmall = angleSmall(1:end-1); % remove last frame, it would be double
angleSmall = circshift(angleSmall',round(nFrames*0.82)); % shift a view frames to get good visibility of all lines in frame 1
[pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
figHandle = figure(15677755); clf
set(figHandle, 'Units','pixel');
set(figHandle, 'position',[1 1 [xySize xySize]*scaleReduction]); % big start image for antialiasing later [x y width height]
%set(figHandle, 'GraphicsSmoothing','on') % requires at least version 2014b
axesHandle = axes;
hold(axesHandle,'on')
set(axesHandle,'position',[-0.05 -0.05 1.1 1.1]); % stretch axis bigger as figure, easy way to get rid of ticks [x y width height]
xyLim = p*[-2.73 2.73];
xlim(xyLim); ylim(xyLim);
axis equal; drawnow;
diamScale = 1.4;
col.E = round([1 0 0 ]*255)/255; % red
col.Hori = round([0 0.7 0 ]*255)/255; % green
col.Vert = round([0.2 0.2 1 ]*255)/255; % blue
col.HoriDark = round([0 0.6 0 ]*255)/255; % green
col.VertDark = round([0 0 1 ]*255)/255; % blue
reducedRGBimage = uint8(ones(xySize,xySize,3,nFrames)); % allocate
for iFrame = 1:nFrames
currentAngle = angleSmall(iFrame);
cla(axesHandle) % fresh frame
disc(p*cos(currentAngle),0,p*diamScale,currentAngle,col.Hori,col.Hori,4,'-') % green disc
plotBox(1.25*diamScale*[p,-p], diamScale*p*[1.02 1.25],col.HoriDark,col.HoriDark,6) % horizontal bar
plotBox(1.25*diamScale*[p,-p],-diamScale*p*[1.02 1.25],col.HoriDark,col.HoriDark,6) % horizontal bar
disc(0,p*sin(currentAngle),p*diamScale,currentAngle,col.Vert,col.Vert,4,'-') % blue disc outline
plotBox( diamScale*p*[1.02 1.25],1.25*diamScale*[p,-p],col.VertDark,col.VertDark,6) % vertical bar
plotBox(-diamScale*p*[1.02 1.25],1.25*diamScale*[p,-p],col.VertDark,col.VertDark,6) % vertical bar
plot([0 0],[p,-p],'-.','linewidth',3,'color',col.VertDark) % vertical line
plot([p,-p],[0 0],'-.','linewidth',3,'color',col.HoriDark) % horizontal line
plot(p*cos(currentAngle),0,'.','MarkerSize',40,'linewidth',4,'color',col.Hori*0.7) % small dot to indicate the precise position
plot(0,p*sin(currentAngle),'.','MarkerSize',40,'linewidth',4,'color',col.Vert*0.7) % small dot to indicate the precise position
ellTwoOffset = 0.2;
% ellipse(0,0,ellTwoOffset,p-ellTwoOffset,col.E,4);
% plot(ellTwoOffset*cos(currentAngle),(p-ellTwoOffset)*sin(currentAngle),'.','MarkerSize',40,'linewidth',3,'color',col.E);
ellipse(0,0,p-ellTwoOffset,ellTwoOffset,col.E,4);
plot((p-ellTwoOffset)*cos(currentAngle),ellTwoOffset*sin(currentAngle),'.','MarkerSize',40,'linewidth',3,'color',col.E);
%% save animation
xlim(xyLim); ylim(xyLim); drawnow % set axis limits
if iFrame == 1 % save SVG
if ~isempty(which('plot2svg'))
plot2svg(fullfile(pathstr, [fname '_a.svg']),figHandle) % by Juerg Schwizer, See http://www.zhinst.com/blogs/schwizer/
else
disp('plot2svg.m not available; see http://www.zhinst.com/blogs/schwizer/');
end
end
f = getframe(figHandle);
reducedRGBimage(:,:,:,iFrame) = imReduceSize(f.cdata,scaleReduction); % the size reduction: adds antialiasing
end
map = createImMap(reducedRGBimage,64,[1 1 1;struct2map(col)]); % colormap
im = uint8(ones(xySize,xySize,1,nFrames)); % allocate
for iFrame = 1:nFrames
im(:,:,1,iFrame) = rgb2ind(reducedRGBimage(:,:,:,iFrame),map,'nodither');
end
imwrite(im,map,fullfile(pathstr, [fname '_a.gif']),'DelayTime',1/25,'LoopCount',inf) % save gif1
disp([fname '_a.gif has ' num2str(numel(im)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 50 MP limit
%%
function disc(x,y,r,rot,colFa,colEd,linWi,linSt)
% x coordinates of the center
% y coordinates of the center
% r is the radius of the circle
% rot rotation of the slit in "rad"
% colFa facecolor
% colEd edgecolor
% linWi linewidth
% linSt linestyle
angleOffPoints = linspace(0,2*pi,300);
xc = x + r*sin(angleOffPoints);
yc = y + r*cos(angleOffPoints);
xs = 0.9* [r r -r -r r r]; % x slit
ys = 0.05*[0 -r -r r r 0]; % y slit
rotM = [cos(-rot) -sin(-rot); sin(-rot) cos(-rot)];
vecTemp = rotM*[xs; ys]; % rotate slit
xs = vecTemp(1,:)+x;
ys = vecTemp(2,:)+y;
[boolX,boolY] = polybool('subtraction', xc,yc, xs,ys);
boolX = boolX(~isnan(boolX)); % I do not know why there is an NaN
boolY = boolY(~isnan(boolY)); % I do not know why there is an NaN
patch(boolX,boolY,'k','linewidth',4,'edgecolor','none','facecolor',colFa,'FaceAlpha',.3); % ,'FaceAlpha',0.2% transparencc does onl work in 'renderer','OpenGL' but that fails in combination with "getframe"
plot(xc,yc,'linewidth',linWi,'linestyle',linSt,'color',colEd);
plot(xs,ys,'linewidth',linWi,'linestyle',linSt,'color',colEd);
xl = [0 0];
yl = r*[0.1 0.9];
vecTemp = rotM*[xl; yl];
plot( vecTemp(1,:)+x, vecTemp(2,:)+y,'k','linewidth',linWi,'linestyle',linSt,'color',colEd);
plot(-vecTemp(1,:)+x,-vecTemp(2,:)+y,'k','linewidth',linWi,'linestyle',linSt,'color',colEd);
function h = ellipse(x,y,a,b,col,linw)
% x coordinates of the center
% y coordinates of the center
% a radius1
% b radius2
angleOffPoints = linspace(0,2*pi,300);
xe = x + a*cos(angleOffPoints);
ye = y + b*sin(angleOffPoints);
h = plot(xe,ye,'-','linewidth',linw,'color',col);
function plotBox(x,y,colFa,colEd,linw)
% x [left right]
% y [top bottom]
% colFa face color [r g b]
% colEd edge color [r g b]
% linw line width
xs = [x(1) x(1) x(2) x(2) x(1) x(1)]; % x
ys = [mean(y) y(1) y(1) y(2) y(2) mean(y)]; % y joint in the middle of an edge to get nice corners
patch(xs,ys,colFa,'EdgeColor',colEd,'LineWidth',linw,'FaceAlpha',.3); %
function map = struct2map(RGB)
% RGB: struct of depth 1 with [r g b] in each field
fNames = fieldnames(RGB);
nNames = numel(fNames);
map = NaN(nNames,3); % allocate
for iName = 1:nNames
map(iName,:) = RGB.(fNames{iName}); %
end
function im = imReduceSize(im,redSize)
% Input:
% im: image, [imRows x imColumns x nChannel x nStack] (unit8)
% imRows, imColumns: must be divisible by redSize
% nChannel: usually 3 (RGB) or 1 (grey)
% nStack: number of stacked images
% usually 1; >1 for animations
% redSize: 2 = half the size (quarter of pixels)
% 3 = third the size (ninth of pixels)
% ... and so on
% Output:
% imNew: unit8([imRows/redSize x imColumns/redSize x nChannel x nStack])
%
% an alternative is : imNew = imresize(im,1/reduceImage,'bilinear');
% BUT 'bicubic' & 'bilinear' produces fuzzy lines
% IMHO this function produces nicer results as "imresize"
[nRow,nCol,nChannel,nStack] = size(im);
if redSize==1; return; end % nothing to do
if redSize~=round(abs(redSize)); error('"redSize" must be a positive integer'); end
if rem(nRow,redSize)~=0; error('number of pixel-rows must be a multiple of "redSize"'); end
if rem(nCol,redSize)~=0; error('number of pixel-columns must be a multiple of "redSize"'); end
nRowNew = nRow/redSize;
nColNew = nCol/redSize;
im = double(im).^2; % brightness rescaling from "linear to the human eye" to the "physics domain"; see youtube: /watch?v=LKnqECcg6Gw
im = reshape(im, nRow, redSize, nColNew*nChannel*nStack); % packets of width redSize, as columns next to each other
im = sum(im,2); % sum in all rows. Size of result: [nRow, 1, nColNew*nChannel]
im = permute(im, [3,1,2,4]); % move singleton-dimension-2 to dimension-3; transpose image. Size of result: [nColNew*nChannel, nRow, 1]
im = reshape(im, nColNew*nChannel*nStack, redSize, nRowNew); % packets of width redSize, as columns next to each other
im = sum(im,2); % sum in all rows. Size of result: [nColNew*nChannel, 1, nRowNew]
im = permute(im, [3,1,2,4]); % move singleton-dimension-2 to dimension-3; transpose image back. Size of result: [nRowNew, nColNew*nChannel, 1]
im = reshape(im, nRowNew, nColNew, nChannel, nStack); % putting all channels (rgb) back behind each other in the third dimension
im = uint8(sqrt(im./redSize^2)); % mean; re-normalize brightness: "scale linear to the human eye"; back in uint8
function map = createImMap(imRGB,nCol,startMap)
% createImMap creates a color-map including predefined colors.
% "rgb2ind" creates a map but there is no option to predefine some colors,
% and it does not handle stacked images.
% Input:
% imRGB: image, [imRows x imColumns x 3(RGB) x nStack] (unit8)
% nCol: total number of colors the map should have, [integer]
% startMap: predefined colors; colormap format, [p x 3] (double)
imRGB = permute(imRGB,[1 2 4 3]); % step1; make unified column-image (handling possible nStack)
imRGBcolumn = reshape(imRGB,[],1,3,1); % step2; make unified column-image
fullMap = double(permute(imRGBcolumn,[1 3 2]))./255; % "column image" to color map
[fullMap,~,imMapColumn] = unique(fullMap,'rows'); % find all unique colores; create indexed colormap-image
% "cmunique" could be used but is buggy and inconvenient because the output changes between "uint8" and "double"
nColFul = size(fullMap,1);
nColStart = size(startMap,1);
disp(['Number of colors: ' num2str(nColFul) ' (including ' num2str(nColStart) ' self defined)']);
if nCol<=nColStart; error('Not enough colors'); end
if nCol>nColFul; warning('More colors than needed'); end
isPreDefCol = false(size(imMapColumn)); % init
for iCol = 1:nColStart
diff = sum(abs(fullMap-repmat(startMap(iCol,:),nColFul,1)),2); % difference between a predefined and all colores
[mDiff,index] = min(diff); % find matching (or most similar) color
if mDiff>0.05 % color handling is not precise
warning(['Predefined color ' num2str(iCol) ' does not appear in image'])
continue
end
isThisPreDefCol = imMapColumn==index; % find all pixel with predefined color
disp([num2str(sum(isThisPreDefCol(:))) ' pixel have predefined color ' num2str(iCol)]);
isPreDefCol = or(isPreDefCol,isThisPreDefCol); % combine with overall list
end
[~,mapAdditional] = rgb2ind(imRGBcolumn(~isPreDefCol,:,:),nCol-nColStart,'nodither'); % create map of remaining colors
map = [startMap;mapAdditional];
|
Lizenz
Ich, der Urheber dieses Werkes, veröffentliche es unter der folgenden Lizenz:
Diese Datei wird unter der Creative-Commons-Lizenz „CC0 1.0 Verzicht auf das Copyright“ zur Verfügung gestellt. | |
Die Person, die das Werk mit diesem Dokument verbunden hat, übergibt dieses weltweit der Gemeinfreiheit, indem sie alle Urheberrechte und damit verbundenen weiteren Rechte – im Rahmen der jeweils geltenden gesetzlichen Bestimmungen – aufgibt. Das Werk kann – selbst für kommerzielle Zwecke – kopiert, modifiziert und weiterverteilt werden, ohne hierfür um Erlaubnis bitten zu müssen.
http://creativecommons.org/publicdomain/zero/1.0/deed.enCC0Creative Commons Zero, Public Domain Dedicationfalsefalse |
In dieser Datei abgebildete Objekte
Motiv
Einige Werte ohne einen Wikidata-Eintrag
image/gif
Dateiversionen
Klicke auf einen Zeitpunkt, um diese Version zu laden.
Version vom | Vorschaubild | Maße | Benutzer | Kommentar | |
---|---|---|---|---|---|
aktuell | 17:54, 24. Okt. 2017 | 500 × 500 (2,81 MB) | Jahobr | graph smoothing, thick border | |
16:32, 28. Mai 2017 | 500 × 500 (1,98 MB) | Jahobr | User created page with UploadWizard |
Dateiverwendung
Keine Seiten verwenden diese Datei.
Globale Dateiverwendung
Die nachfolgenden anderen Wikis verwenden diese Datei:
- Verwendung auf es.wikipedia.org
- Verwendung auf fr.wikipedia.org
Abgerufen von „https://de.wikipedia.org/wiki/Datei:Rohn_Ellipsograph_a.gif“