- /
-
Moonlit Night
on 4 Nov 2024
- 67
- 391
- 0
- 2
- 1584
Cite your audio source here (if applicable): Audio - https://www.youtube.com/watch?v=q6UB8sKMZrA
drawframe(1);
Write your drawframe function below
% This entry is a remix of the previous two entries from last years:
% 1) 'Midnattsol' created by Jenny Boston
% https://www.mathworks.com/matlabcentral/communitycontests/contests/6/entries/12937
% 2) 'the mountains are calling' created by Jr
% https://www.mathworks.com/matlabcentral/communitycontests/contests/4/entries/3246
% Thanks to both of them. While remixing, I learned a lot.
% I will explain the changes I've made throughout the code.
function drawframe(f)
% Modified the RGB triplets to create a moonlit night sky view:
% Black-Navy-Blue-White
g1 = [0 0 0; 10 24 46; 30 60 100; 90 130 180; 180 210 240; 240 240 255];
g2 = [0 0 0; 5 15 30; 15 30 60; 80 100 160; 150 180 220; 240 240 255];
tf = 96; % Total number of frames
z = linspace(1, 6, 100);
d = [linspace(10, 30, tf / 2), linspace(30, 10, tf / 2)];
x(:, :, 1) = interp1(1:6, g1, z);
x(:, :, 2) = interp1(1:6, g2, z);
x = permute(x, [3, 1, 2]);
x = permute(interp1([1, tf], x, 1:2:tf), [2, 3, 1]) ./ 255;
x = cat(3, x, x(:, :, end:-1:1));
a = 1000;
X = linspace(-255, 255, a);
% Removed the linearly generated vectors 'q' & 'm' used for creating
% the sunset & sunrise view in the original entry.
% Moon effect
% Changed [t, r] = cart2pol(X - q(f), 100 + X' - 100 * cos(m(f)))
% to make the moon static.
[t, r] = cart2pol(X, 100 + X');
[x_i, y_i] = find(r < 15);
[x_i2, y_i2] = find(r < 5);
b = x(:, :, f);
j = [0.9 0.9 1]; % Light gray for the moon glow
colormap([j; flipud(b)]);
r(r < 14) = 0.9;
% To keep the mountains static throughout the animation, I added
% 'rng default' in the createMountains function. Therefore, I added
% 'rng shuffle' here to preserve randomness in the river current.
rng shuffle
for k = 1:300
% Adjusted some parameters
y(k, :) = circshift(r(min(x_i), :), randi(30) - 15);
y(k, y_i2 + round(randi(round(d(f))) - d(f) / 2)) = 0.9;
end
imagesc([r(100:600, :); y]);
axis equal;
axis off;
xlim([100 900]);
% Draw Mountains
mountains = createMountains();
hold on;
for i = length(mountains):-1:1
mountainColor = i / 8 * [30 60 100] / 255;
fill(mountains{i}(:, 1), mountains{i}(:, 2), mountainColor, 'EdgeColor', 'none');
end
hold off;
camva(5.9);
end
% Mountain Range
function mountains = createMountains()
% Set the random number generator to default so that the sequence
% remains the same across frames, ensuring the mountain range stays fixed.
rng default
c = 900; % Maximum x-coordinate
n = 800;
m = 0.8;
mountains = cell(8, 1); % Store mountain data
% Set the height range for the mountains: the base is at y = 500
% and the peak can rise up to y = 370. Set the peak to a low value and
% the foot to a high value because of 'circshift'.
peak = 370;
foot = 500;
% Create 8 mountains
for i = 8:-1:1
y_mountain = peak + i / (8 + 3) * (foot - peak); % Height between peak and foot
a = 160 * m^(i - 1);
u = c * (1 - (i - 1) / 8);
x_mountain = linspace(100, c, n);
p = y_mountain / 700 * 4 * pi;
t = x_mountain * 2 * pi / u;
q = sin(p + t) + sin(p + 0.3 * t);
r_mountain = y_mountain + q * a + cumsum(sqrt(0.4 * a) * randn(1, n)) + 3.2^(i - 1);
% Normalize r_mountain to be between the peak and foot
r_mountain = foot - (foot - peak) * (r_mountain - min(r_mountain)) / ...
(max(r_mountain) - min(r_mountain));
v = [x_mountain' r_mountain'; c foot; 0 foot];
mountains{i} = v; % Store the mountain polygon
end
end