T形积木(T puzzle)

目录

积木绘制

积木拼接

练习

[1. 停止标志](#1. 停止标志)

[2. 跳跃旋转](#2. 跳跃旋转)

[3. 小步平移](#3. 小步平移)


积木绘制


(1)复数欧拉公式:

(2)复数的极坐标形式:

其中

(3)T形积木问题利用了复数乘以将该复数值旋转b角的事实。
findobj 查找具有特定属性的图形对象

复制代码
function t_puzzle

% Playing pieces and puzzle shapes.

   % Four playing pieces.

   s = sqrt(2);
   T{1} = [0 1 1+2*i 3*i 0];
   T{2} = [0 s/2+s/2*i 1+(s-1)*i 1+(2*s-1)*i 2*s*i 0];
   T{3} = [0 1 i 0];
   T{4} = [0 1 1+(2-s)*i (3-s)*i 0];

   % Three puzzle shapes for subplot.

   P{1} = [2 2 1 1 0 0 -1 -1 2]-1/2 + [2 1 1 -2 -2 1 1 2 2]*i;
   P{2} = [0 2 2-s 2-s 1-s 1-s -2 0] + [2 0 0 -2 -2 0 0 2]*i;
   P{3} = [1 3 0 -2 1]-1/2 + [1 -1 -1 1 1]*i;

   init_plot(T);
   init_subplot(P);
   init_buttons

   % ------------------------
   
   function button_motion(varargin)
      % Button motion, either drag or rotate a piece.
      % Use complex arithmetic.
      
      point = get(gca,'currentpoint');
      v = point(1,1) + point(1,2)*i;
      hit = get(gca,'userdata');
      if ~isempty(hit) && ishandle(hit) && hit ~= 1
         u = get(hit,'xdata') + get(hit,'ydata')*i;
         z = get(hit,'userdata');
         % Check if closer to center or vertex.
         w  = mean(u(1:end-1));
         if abs(w-v) < min(abs(u-v))
            % Drag
            u = u - (z - v);
         else
            % Rotate about the center by an integer
            % multiple of pi/20, which is 9 degrees.
            dtheta = pi/20;
            theta = angle(v-w) - angle(z-w);
            theta = round(theta/dtheta)*dtheta;
            omega = exp(i*theta);
            u = omega*(u-w) + w;
            v = omega*(z-w) + w;
         end
         set(hit,'xdata',real(u),'ydata',imag(u),'userdata',v);
      end
   end
   
   % ------------------------
   
   function init_plot(T)
      % Initialize primary plot.
      clf
      shg
      set(gcf,'numbertitle','off','menubar','none','name','T-puzzle')
      ax(1) = axes('pos',[0 0 1 1],'color',get(gcf,'color'), ...
         'xlim',[-4 4],'ylim',[-3 3],'userdata',[]);
      hold on
      axis off
      bluegreen = [0 1/2 1/2];
      init_shift = [-2-i -1/2-i 1-i 1+i/4];
      for k = 1:4
         t = T{k} + init_shift(k);
         fill(real(t),imag(t),bluegreen, ...
            'markeredgecolor','black','linewidth',2)
      end
      set(gcf,'userdata',ax);
   end
   
   % ------------------------
   
   function init_subplot(P)
      % Initialize puzzle shapes subplot.
      ax = get(gcf,'userdata');
      ax(2) = axes('units','normal','position',[.02 .02 .24 .24]);
      shape = 1;
      t = P{shape};
      buttoncolor = [.8314 .8157 .7843];
      bluegreen = [0 1/2 1/2];
      fill(real(t),imag(t),bluegreen, ...
         'markeredgecolor','black','linewidth',1)
      set(ax(2),'xtick',[],'ytick',[],'xlim',[-4 4],'ylim',[-3 3], ...
         'color',buttoncolor,'userdata',shape);
      set(gcf,'userdata',ax);
   end
   
   % ------------------------
   
   function init_buttons
      % Initialize buttons and callbacks.
      ax = get(gcf,'userdata');
      axis(ax(1));
      set(gcf,'windowbuttondownfcn',@button_down, ...
         'windowbuttonmotionfcn',@button_motion, ...
         'windowbuttonupfcn',@button_up)
      uicontrol('units','normal','pos',[.83 .12 .12 .05],'style','toggle', ...
         'callback','t_puzzle','string','restart')
      uicontrol('units','normal','pos',[.83 .06 .12 .05],'style','push', ...
         'callback','close(gcf)','string','exit')
   end
   
   % ------------------------
   
   function button_down(varargin)
      ax = get(gcf,'userdata');
      if gca == ax(1)
         select_piece;
      else
         cycle_subplot(P)
      end
   end
   
   % ------------------------
   
   function select_piece;
      % Select a piece and remember it in ax(1) userdata.
      point = get(gca,'currentpoint');
      z = point(1,1) + point(1,2)*i;
      delete(findobj(gca,'type','line'))
      h = flipud(get(gca,'children'));
      h = h(1:4);
      hit  = [];
      for k = 1:length(h)
         x = get(h(k),'xdata');
         y = get(h(k),'ydata');
         if inregion(real(z),imag(z),x,y)
            hit = h(k);
            set(hit,'userdata',z)
            break
         end
      end
      set(gca,'userdata',hit)
   
      % Right click reflects piece about center horizontally.
   
      if ~isempty(hit) && isequal(get(gcf,'selectiontype'),'alt')
         x = 2*mean(x(1:end-1))-x;
         set(hit,'xdata',x)
      end
   end
   
   % ------------------------
   
   function cycle_subplot(P)
      % Cycle through puzzle shapes in subplot.
      ax = get(gcf,'userdata');
      shape = get(ax(2),'userdata');
      shape = mod(shape,3)+1;
      t = P{shape};
      f = get(ax(2),'child');
      set(f,'xdata',real(t),'ydata',imag(t))
      set(ax(1),'userdata',[])
      set(ax(2),'userdata',shape)
      axes(ax(1))
   end
   
   % ------------------------
   
   function button_up(varargin)
      % Button up, snap to any nearby piece, then deselect.
      % Use complex arithmetic.
   
      delete(findobj(gca,'type','line'))
      hit = get(gca,'userdata');
      set(gca,'userdata',[])
     
      % Compute distance to nearest vertex of other pieces.
   
      z = get(hit,'xdata') + get(hit,'ydata')*i;
      h = get(gca,'children');
      w = [];
      for k = 1:length(h)
         if h(k) ~= hit
            w = [w; get(h(k),'xdata')+get(h(k),'ydata')*i];
         end
      end
      dz = 1;
      for k = 1:length(z);
         d = z(k)-w;
         dw = d(find(abs(d)==min(abs(d)),1));
         if abs(dw) < abs(dz)
            dz = dw;
         end
      end
   
      % If close enough, snap to nearby piece.
   
      tol = 1/8;
      if abs(dz) < tol
         set(hit,'xdata',real(z-dz),'ydata',imag(z-dz))
         bluegreen = [0 1/2 1/2];
         set(hit,'facecolor',1.25*bluegreen)
         pause(.25)
         set(hit,'facecolor',bluegreen)
      end
   end
end % t_puzzle

积木拼接


T形&箭头形&平行四边形


练习


1. 停止标志

复制代码
n=8
z=exp(2*pi*i*(0:n)'/n)
plot(z,'-o'), axis square
s=sum(z)

2. 跳跃旋转

旋转操作是通过**固定的角度(9度或π/20弧度)**来进行的。这会导致在旋转过程中可能出现明显的跳跃,特别是在慢速旋转时,可能感觉不够平滑。

复制代码
dtheta = pi/20;
theta = angle(v-w) - angle(z-w);
theta = round(theta/dtheta)*dtheta;
omega = exp(i*theta);
u = omega*(u-w) + w;
v = omega*(z-w) + w;

3. 小步平移

程序中的button_up函数负责处理鼠标释放事件,即在将T形积木拖动到其他块体附近并释放鼠标键时,程序会检测是否有其他块体的顶点靠近被释放的积木,如果有足够近的块体,则将积木自动吸附到靠近的块体上。

复制代码
   function button_up(varargin)
      % Button up, snap to any nearby piece, then deselect.
      % Use complex arithmetic.
   
      delete(findobj(gca,'type','line'))
      hit = get(gca,'userdata');
      set(gca,'userdata',[])
     
      % Compute distance to nearest vertex of other pieces.
   
      z = get(hit,'xdata') + get(hit,'ydata')*i;
      h = get(gca,'children');
      w = [];
      for k = 1:length(h)
         if h(k) ~= hit
            w = [w; get(h(k),'xdata')+get(h(k),'ydata')*i];
         end
      end
      dz = 1;
      for k = 1:length(z);
         d = z(k)-w;
         dw = d(find(abs(d)==min(abs(d)),1));
         if abs(dw) < abs(dz)
            dz = dw;
         end
      end
   
      % If close enough, snap to nearby piece.
   
      tol = 1/8;
      if abs(dz) < tol
         set(hit,'xdata',real(z-dz),'ydata',imag(z-dz))
         bluegreen = [0 1/2 1/2];
         set(hit,'facecolor',1.25*bluegreen)
         pause(.25)
         set(hit,'facecolor',bluegreen)
      end
   end
end % t_puzzle
相关推荐
今天吃饺子1 天前
如何用MATLAB调用python实现深度学习?
开发语言·人工智能·python·深度学习·matlab
硬汉嵌入式1 天前
专为 MATLAB 优化的 AI 助手MATLAB Copilot
人工智能·matlab·copilot
Dev7z1 天前
基于Matlab遗传算法与蚁群算法的风光储并网微电网容量优化研究
算法·matlab·蚁群算法·多能源微电网
jllllyuz2 天前
基于粒子群优化(PSO)的特征选择与支持向量机(SVM)分类
开发语言·算法·matlab
一只肥瘫瘫2 天前
基于MATLAB的滑膜观测器仿真搭建
单片机·嵌入式硬件·matlab
bubiyoushang8882 天前
MATLAB 实现多能源系统(MES)多目标优化
支持向量机·matlab·能源
算法如诗2 天前
**MATLAB R2025a** 环境下,基于 **双向时间卷积网络(BITCN)+ 双向长短期记忆网络(BiLSTM)** 的多特征分类预测完整实现
开发语言·网络·matlab
bubiyoushang8883 天前
基于MATLAB的马尔科夫链蒙特卡洛(MCMC)模拟实现方法
人工智能·算法·matlab
轻微的风格艾丝凡3 天前
卷积的直观理解
人工智能·深度学习·神经网络·算法·计算机视觉·matlab·cnn