Skip to content

Commit e74ed8f

Browse files
committed
Initial Submit.
1 parent e60e526 commit e74ed8f

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed

parallax/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Parallax Plot
2+
3+
Code for displaying 2 images, one being visible, the other hidden, and revealed only by
4+
rotating the axes to a new view (parallax).
5+
6+
- paralaxPlot.m - Take two B&W images that are the same size and create the plot
7+
- dfltimg_parallax.m - Get images from the default image, and transform between 4 of them.
8+
9+
![Default Images in Parallax](./parallax_demo.gif)

parallax/dfltimg_parallax.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
function dfltimg_parallax()
2+
% Get the default image cdata and display 4 images in a rotating cube.
3+
4+
I = get(groot,'defaultimageCData');
5+
defimage = pow2(I,47);
6+
7+
% Compute the images from the default CData
8+
I1 = bitslice(defimage,42,46);
9+
I2 = bitslice(defimage,37,41);
10+
I3 = bitslice(defimage,47,51);
11+
I4 = bitslice(defimage,5,8);
12+
13+
set(gca,'PositionConstraint','innerposition')
14+
15+
% Display a transition for each image in sequence.
16+
parallaxPlot(I1,I2);
17+
18+
pause(1)
19+
paratwist
20+
21+
parallaxPlot(I2,I3);
22+
23+
pause(1)
24+
paratwist
25+
26+
parallaxPlot(I3,I4);
27+
28+
pause(1)
29+
paratwist
30+
31+
parallaxPlot(I4,I1);
32+
33+
pause(1)
34+
paratwist
35+
36+
end
37+
function paratwist()
38+
% Rotate the axes to show off the paralax thing...
39+
40+
for idx=linspace(0,90,50)
41+
view([ idx (cosd(idx*4)-1)*5 ]);
42+
drawnow
43+
end
44+
45+
end
46+
function b = bitslice(a,lowbit,highbit)
47+
% BITSLICE(A,LOWBIT,HIGHBIT)
48+
%
49+
% Scales return values so that the maximum is 1.0.
50+
51+
b = a / 2^(lowbit);
52+
b = fix(b);
53+
b = b / 2^(highbit - lowbit + 1);
54+
b = b - fix(b);
55+
56+
b = b / max(b(:));
57+
58+
% To work with parallaxPlot, pull up only the brightest pixels.
59+
b = floor(b*1.8);
60+
61+
b([end 1]) = 1;
62+
end

parallax/parallaxPlot.m

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
function parallaxPlot(img1, img2)
2+
% PARAKKAXPLOT(IMG1, IMG2) - Plot scatter points that shows the black
3+
% and white IMG1 with IMG2 hidden behind IMG1 pixels.
4+
% Rotating the axes around Z will reveal IMG2, and hide IMG1 behind IMG2.
5+
6+
arguments
7+
img1 (:,:) double
8+
img2 (:,:) double
9+
end
10+
11+
[ verts1(:,2), verts1(:,1) ] = find(img1);
12+
[ verts2(:,2), verts2(:,1) ] = find(img2);
13+
14+
verts3 = parallax(verts1, verts2);
15+
16+
scatter3(verts3(:,1), verts3(:,3), verts3(:,2), 20, 'w', 'Marker','.');
17+
18+
view([ 0 0 ]);
19+
20+
axis vis3d padded on
21+
box on
22+
daspect([1 1 1]);
23+
xticks([]);
24+
yticks([]);
25+
zticks([]);
26+
set(gca,'ZDir','reverse',...
27+
'Color','none',...
28+
'BoxStyle','full',...
29+
'XColor',[.5 .5 .5],...
30+
'YColor',[.5 .5 .5],...
31+
'ZColor',[.5 .5 .5]);
32+
set(gcf,'Color','black');
33+
end
34+
35+
function verts3 = parallax(v1, v2)
36+
% Convert img1 and img2 into a single set of vertices
37+
% which represent BOTH images, where 1 image is hidden behind
38+
% the other, but revealed with a view change.
39+
40+
verts3 = v1;
41+
verts3(:,3) = -1; % Starts with img1, add Z values. -1 means not used
42+
43+
% Basic idea: V1 is the image we first show, this is the reference image.
44+
% For each vertex in V2, find an unused vertrc in V1 at the same Y and set Z to the X.
45+
% If NO MATCH, we need to add a new vertex
46+
47+
for idx = 1:height(v2)
48+
% First find points that haven't been used yet.
49+
match = find_matching_index(verts3, v2, idx, 'unused');
50+
51+
if match
52+
% We have a match, set Z of a random pt in img1 to x of img2.
53+
verts3(match,3) = v2(idx,1);
54+
else
55+
% We have no matches. Look for existing matches of the Y coord, and hide
56+
% our new point behind that.
57+
match = find_matching_index(verts3, v2, idx, 'any');
58+
if match
59+
% We found at least one, so hide this new pixel behind one of them
60+
verts3(end+1,:) = [ verts3(match,1) v2(idx,2) v2(idx,1) ]; %#ok
61+
else
62+
% No match - hide this in the margins
63+
verts3(end+1,:) = [ -1 v2(idx,2) v2(idx,1) ]; %#ok
64+
end
65+
end
66+
end
67+
68+
% Lastly, find points from the first image (V1) that don't already
69+
% have a corresponding point from the second image (V2), and move
70+
% them behind other points in V2.
71+
% Note: All points from V2 are now in our destination image VERTS3.
72+
lost = find(verts3(:,3)==-1);
73+
for lidx = 1:numel(lost)
74+
idx = lost(lidx);
75+
% Only find used points since we are finding homes for unused points.
76+
match = find_matching_index(verts3, verts3, idx, 'used');
77+
if match
78+
verts3(idx,3) = verts3(match,3);
79+
else
80+
% Just ignore it.
81+
end
82+
end
83+
84+
end
85+
86+
function match = find_matching_index(dest, src, idx, flag)
87+
% For the DEST image, find a random vertex in DEST that matches the
88+
% SRC image point at IDX.
89+
% If UNUSED is true, make sure the found vertex has not be used already.
90+
mask = dest(:,2)==src(idx,2);
91+
switch flag
92+
case 'unused'
93+
% Only match vertices not yet used.
94+
mask = mask & dest(:,3)==-1;
95+
case 'used'
96+
% Only match vertices that have been used.
97+
mask = mask & dest(:,3)~=-1;
98+
end
99+
% Get the indices to the found points
100+
match_indices = find(mask);
101+
if isempty(match_indices)
102+
match = 0;
103+
else
104+
% Of the found points, find a random vertex from that list.
105+
match = match_indices(randi(numel(match_indices)));
106+
end
107+
end

parallax/parallax_demo.gif

6.61 MB
Loading

0 commit comments

Comments
 (0)