properties (GetAccess = public, SetAccess = private)
    properties (SetAccess = public)
        speed (1, 1) double = 500
    properties (GetAccess = private)
            figure(Name='MATurtle', NumberTitle='off')
            icon = flipud(imread('turtle.png'));
            obj.im = imagesc(obj.ht, icon, ...
                XData=[-30, 30], YData=[-30, 30], ...
                AlphaData=(255 - double(rgb2gray(icon)))/255);
            obj.l = plot(obj.x, obj.y, 'k');
            obj.ax.XLim = [-500, 500];
            obj.ax.YLim = [-500, 500];
            obj.ax.DataAspectRatio = [1, 1, 1];
            obj.ax.Toolbar.Visible = 'off';
            disableDefaultInteractivity(obj.ax);
        function forward(obj, dist)
        function backward(obj, dist)
        function step(obj, delta)
                delta = delta*[cosd(obj.q), sind(obj.q)];
            obj.turnto(rad2deg(atan2(dy, dx)));
            obj.turn(obj.wrap_angle(q - obj.q, -180));
                warning('not available while filling')
        function pen_down(obj, go)
                    obj.l(end+1) = plot(obj.x, obj.y, Color=obj.l(end).Color);
        function color(obj, line_color)
                warning('not available while filling')
            obj.pen_down(plot(obj.x, obj.y, Color=line_color));
        function begin_fill(obj, FaceColor, EdgeColor, FaceAlpha)
                FaceColor = [.6, .9, .6];
                EdgeColor = [0 0.4470 0.7410];
                warning('already filling')
            obj.fill_color = FaceColor;
            obj.fill_alpha = FaceAlpha;
            obj.pen_down(patch(obj.x, obj.y, [1, 1, 1], ...
                EdgeColor=EdgeColor, FaceAlpha=0));
                warning('not filling now')
            obj.l(end).FaceColor = obj.fill_color;
            obj.l(end).FaceAlpha = obj.fill_alpha;
        function change_icon(obj, filename)
            icon = flipud(imread(filename));
            obj.im.AlphaData = (255 - double(rgb2gray(icon)))/255;
            delete(obj.ax.Children(2:end));
    methods (Access = private)
        function animated_step(obj, delta, q, initFcn, updateFcn)
            dx = delta(1)/obj.n_steps;
            dy = delta(2)/obj.n_steps;
            pause_duration = norm(delta)/obj.speed/obj.speed_reg;
                obj.ht.Matrix = makehgtform(...
                    translate=[obj.x + dx*i, obj.y + dy*i, 0], ...
                    zrotate=deg2rad(obj.q + dq*i));
            obj.x = obj.x + delta(1);
            obj.y = obj.y + delta(2);
        function obj = turn(obj, q)
            obj.animated_step([0, 0], q);
            obj.q = obj.wrap_angle(obj.q + q, 0);
        function move(obj, delta)
            updateFcn = @(dx, dy) [];
                initFcn = @() initializeLine();
                updateFcn = @(dx, dy) obj.update_end_point(obj.l(end), dx, dy);
            function initializeLine()
                obj.l(end).XData(end+1) = obj.l(end).XData(end);
                obj.l(end).YData(end+1) = obj.l(end).YData(end);
            obj.animated_step(delta, 0, initFcn, updateFcn);
        function obj = fill(obj, delta)
            initFcn = @() initializePatch();
            updateFcn = @(dx, dy) obj.update_end_point(obj.l(end), dx, dy);
            function initializePatch()
                obj.l(end).Vertices(end+1, :) = obj.l(end).Vertices(end, :);
                obj.l(end).Faces = 1:size(obj.l(end).Vertices, 1);
            obj.animated_step(delta, 0, initFcn, updateFcn);
    methods (Static, Access = private)
        function update_end_point(l, dx, dy)
            l.XData(end) = l.XData(end) + dx;
            l.YData(end) = l.YData(end) + dy;
        function q = wrap_angle(q, min_angle)
            q = mod(q - min_angle, 360) + min_angle;