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
相关推荐
matlabgoodboy19 小时前
Matlab代编电气仿真电力电子电机控制自动化新能源微电网储能能量
开发语言·matlab·自动化
IT猿手21 小时前
超多目标优化:基于导航变量的多目标粒子群优化算法(NMOPSO)的无人机三维路径规划,MATLAB代码
人工智能·算法·机器学习·matlab·无人机
Evaporator Core1 天前
MATLAB学习之旅:数据建模与仿真应用
开发语言·学习·matlab
项目申报小狂人1 天前
改进收敛因子和比例权重的灰狼优化算法【期刊论文完美复现】(Matlab代码实现)
开发语言·算法·matlab
IT猿手2 天前
2025最新智能优化算法:鲸鱼迁徙算法(Whale Migration Algorithm,WMA)求解23个经典函数测试集,MATLAB
android·数据库·人工智能·算法·机器学习·matlab·无人机
GIS遥感数据处理应用2 天前
MATLAB | 设置滑动窗口计算栅格数据的CV变异系数
matlab·arcgis·数据分析
圆滚滚的龙猫2 天前
matlab和java混合编程经验分享
java·matlab
studyer_domi2 天前
matlab 七自由度车辆模型轮毂电机驱动电动汽车的振动分析
matlab
没有不重的名么3 天前
MATLAB基础学习相关知识
数据结构·学习·matlab
青橘MATLAB学习3 天前
时间序列预测实战:指数平滑法详解与MATLAB实现
人工智能·算法·机器学习·matlab