Created
May 12, 2019 13:23
-
-
Save tejashah88/81984b8a66a8696c1d14c70fa50ac1e6 to your computer and use it in GitHub Desktop.
A rainbow analog clock animation in MATLAB for my ENGIN-136 class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% Final Project: Rainbow Analog Clock | |
% Author: Tejas Shah | |
% Class: ENGIN-136 - Intro to MATLAB | |
% Clear any vars and current figure and show it on top of screen | |
clear, clf, shg | |
% Setup drawing board for clock | |
axis([-1.1 1.1 -1.1 1.1]); | |
axis square | |
axis off | |
% Used for 1-second markings | |
sec_x = sin(2*pi*(1:60)/60); | |
sec_y = cos(2*pi*(1:60)/60); | |
% Used for 5-second markings | |
sec_marks = 5:5:60; | |
% Draw border of clock with 1 second markings | |
line(sec_x, sec_y,... | |
'LineStyle', 'none',... | |
'Marker', 'o',... | |
'Color', 'black',... | |
'MarkerSize', 2); | |
line(sec_x(sec_marks), sec_y(sec_marks),... | |
'LineStyle', 'none',... | |
'Marker', '*',... | |
'Color', 'red',... | |
'MarkerSize', 8); | |
% Draw 5-second markings | |
for i = 1:length(sec_marks) | |
x_pos = 1.1 * (sec_x(sec_marks(i)) - 0.05); | |
y_pos = 1.1 * (sec_y(sec_marks(i))); | |
text(x_pos, y_pos, num2str(i), 'fontsize', 16); | |
end | |
% Initialize the various time hands | |
hour = RainbowLine(20, 4); | |
min = RainbowLine(20, 4); | |
sec = RainbowLine(20, 2); | |
msec = RainbowLine(20, 1); | |
% Add a close button | |
close_btn = uicontrol('string', 'close', 'style', 'toggle'); | |
% Increases drawing speed by using any available hardware for openGL | |
% acceleration. If not present, it'll default to using the software version | |
opengl hardware | |
while ishandle(close_btn) && ~get(close_btn, 'value') | |
c = clock; | |
% Draw the datetime text below the clock | |
datetime_text = text(0, -1.2,... | |
datestr(datetime('now')),... | |
'FontSize', 16,... | |
'HorizontalAlignment', 'center'); | |
% Draw hours hand | |
t = c(4)/12 + c(5)/(60 * 12) + c(6)/(60 * 60 * 12); | |
hour.Draw([0 0.8*sin(2*pi*t)], [0 0.8*cos(2*pi*t)], [0 .3]); | |
% Draw minutes hand | |
t = c(5)/60 + c(6)/(60 * 60); | |
min.Draw([0 sin(2*pi*t)], [0 cos(2*pi*t)], [.5 .8]); | |
% Draw seconds hand, changing its color based on second | |
t = floor(c(6)) / 60; | |
sec.Draw([0 sin(2*pi*t)], [0 cos(2*pi*t)], t); | |
% Draw milliseconds hand | |
t = floor((c(6) - floor(c(6))) * 1000) / 1000; | |
msec.Draw([0 0.5*sin(2*pi*t)], [0 0.5*cos(2*pi*t)], t); | |
% Force draw the figure to update hand positions | |
% NOTE: average draw time is 10 ms +/- 5 ms | |
drawnow; | |
% Delete the datetime text for redrawing it after current loop iteration | |
delete(datetime_text); | |
end | |
% Close the figure once we're done | |
close(gcf); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
classdef RainbowLine < handle | |
properties | |
X | |
Y | |
NumPoints | |
LineWidth | |
LineHandle | |
end | |
methods | |
function obj = RainbowLine(NumPoints, LineWidth) | |
% set colormap to HSV to properly draw the rainbow effect | |
colormap(hsv); | |
% by default, the color axis will scale based on the colors | |
% that are drawn, based on the HSV scale from 0 to 1 | |
% ex. if the colors present are from 0 to 0.8, and all of a | |
% sudden, a 0.9 appears, the color axis is automatically scaled | |
% to 0 to 0.9, affecting all the other drawn colors | |
caxis('manual') | |
% Number of points for linear spacing generation | |
obj.NumPoints = NumPoints; | |
obj.LineWidth = LineWidth; | |
% Initialize the line handle | |
obj.Draw([0 0], [0 0]); | |
end | |
function obj = Draw(obj, X, Y, CRange) | |
% Compute the linspace for X and Y | |
obj.X = linspace(X(1), X(2), obj.NumPoints); | |
obj.Y = linspace(Y(1), Y(2), obj.NumPoints); | |
XData = [obj.X; obj.X]; | |
YData = [obj.Y; obj.Y]; | |
% Create an array of zeros for the Z axis (no 3D drawing) | |
z = zeros(size(obj.X)); | |
ZData = [z; z]; | |
if ~exist('CRange', 'var'); CRange = [0 1]; end | |
if length(CRange) == 1; CRange = [CRange CRange]; end | |
% The color range is from 0 to 1, via HSV, so make a series of | |
% colored points from red to orange to yellow to green to cyan | |
% to blue to purple back to red with the same amount of points | |
col = linspace(CRange(1), CRange(2), obj.NumPoints); | |
ColorData = [col; col]; | |
if ~ishandle(obj.LineHandle) | |
% Create line handle if it doesn't exist | |
obj.LineHandle = surface(... | |
XData, YData, ZData, ColorData,... | |
'FaceColor', 'none',... | |
'EdgeColor', 'interp',... | |
'LineWidth', obj.LineWidth); | |
else | |
% Update existing line handle with new data | |
obj.LineHandle.XData = XData; | |
obj.LineHandle.YData = YData; | |
obj.LineHandle.CData = ColorData; | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment