news 2026/2/10 9:25:50

Flutter for OpenHarmony 实战_魔方应用3D数据结构与旋转算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Flutter for OpenHarmony 实战_魔方应用3D数据结构与旋转算法

Flutter for OpenHarmony 实战:魔方应用3D数据结构与旋转算法

文章目录

  • Flutter for OpenHarmony 实战:魔方应用3D数据结构与旋转算法
    • 前言
    • 一、魔方数据结构
      • 1.1 三维数组设计
      • 1.2 面的索引
      • 1.3 颜色映射
    • 二、面旋转算法
      • 2.1 顺时针旋转
      • 2.2 逆时针旋转
      • 2.3 旋转矩阵原理
    • 三、边缘联动系统
      • 3.1 前面旋转联动
      • 3.2 上面旋转联动
      • 3.3 边缘映射表
    • 四、CustomPainter绘制
      • 4.1 展开图布局
      • 4.2 单面绘制
      • 4.3 边框绘制
    • 五、交互控制
      • 5.1 面选择
      • 5.2 旋转按钮
      • 5.3 手势旋转
    • 六、状态管理
      • 6.1 移动计数
      • 6.2 历史记录
    • 总结

欢迎加入开源鸿蒙跨平台社区: 开源鸿蒙跨平台开发者社区

前言

魔方应用的核心在于如何用二维数据结构模拟三维魔方,以及如何实现正确的旋转算法。本文将详细介绍魔方的三维数组表示、面旋转算法、边缘联动机制、CustomPainter绘制技术以及状态管理系统。

一、魔方数据结构

1.1 三维数组设计

lateList<List<List<int>>>cube;voidinitCube(){cube=List.generate(6,(face){returnList.generate(3,(row){returnList.generate(3,(col){returnface;// 每个面初始为相同的颜色});});});}

使用6×3×3的三维数组表示魔方。第一维表示6个面(前、后、左、右、上、下),后两维表示每个面的3×3网格。

1.2 面的索引

// 0: 前面 (Front)// 1: 后面 (Back)// 2: 左面 (Left)// 3: 右面 (Right)// 4: 上面 (Up)// 5: 下面 (Down)

使用整数0-5表示不同的面,便于颜色映射和旋转计算。

1.3 颜色映射

ColorgetFaceColor(int face){switch(face){case0:returnColors.green;// 前面-绿色case1:returnColors.blue;// 后面-蓝色case2:returnColors.orange;// 左面-橙色case3:returnColors.red;// 右面-红色case4:returnColors.white;// 上面-白色case5:returnColors.yellow;// 下面-黄色default:returnColors.grey;}}

标准魔方配色方案。

二、面旋转算法

2.1 顺时针旋转

voidrotateFaceClockwise(int faceIndex){List<List<int>>face=cube[faceIndex];List<List<int>>newFace=List.generate(3,(i)=>List.generate(3,(j)=>0));for(int i=0;i<3;i++){for(int j=0;j<3;j++){newFace[j][2-i]=face[i][j];}}cube[faceIndex]=newFace;_rotateAdjacentEdges(faceIndex,true);}

使用旋转矩阵公式:newFace[j][2-i] = face[i][j],实现90度顺时针旋转。

2.2 逆时针旋转

voidrotateFaceCounterClockwise(int faceIndex){List<List<int>>face=cube[faceIndex];List<List<int>>newFace=List.generate(3,(i)=>List.generate(3,(j)=>0));for(int i=0;i<3;i++){for(int j=0;j<3;j++){newFace[2-j][i]=face[i][j];}}cube[faceIndex]=newFace;_rotateAdjacentEdges(faceIndex,false);}

逆时针旋转公式:newFace[2-j][i] = face[i][j]。

2.3 旋转矩阵原理

顺时针旋转90度: (0,0) -> (0,2) (0,1) -> (1,2) (0,2) -> (2,2) (1,0) -> (0,1) (1,1) -> (1,1) (1,2) -> (2,1) (2,0) -> (0,0) (2,1) -> (1,0) (2,2) -> (2,0) 公式:new[j][2-i] = old[i][j]

三、边缘联动系统

3.1 前面旋转联动

void_rotateFrontEdges(bool clockwise){if(clockwise){// 上面的下行 -> 右面的左列// 右面的左列 -> 下面的上行// 下面的上行 -> 左面的右列// 左面的右列 -> 上面的下行List<int>temp=[cube[4][2][0],cube[4][2][1],cube[4][2][2]];for(int i=0;i<3;i++){cube[4][2][i]=cube[2][2-i][2];cube[2][2-i][2]=cube[5][0][2-i];cube[5][0][2-i]=cube[3][i][0];cube[3][i][0]=temp[i];}}}

旋转前面时,需要同时旋转上、右、下、左四个面与前面相邻的边缘。

3.2 上面旋转联动

void_rotateUpEdges(bool clockwise){if(clockwise){List<int>temp=[cube[0][0][0],cube[0][0][1],cube[0][0][2]];for(int i=0;i<3;i++){cube[0][0][i]=cube[3][0][i];cube[3][0][i]=cube[1][0][i];cube[1][0][i]=cube[2][0][i];cube[2][0][i]=temp[i];}}}

旋转上面时,前、右、后、左四个面的顶行需要同步旋转。

3.3 边缘映射表

每个面的旋转都影响相邻面的特定行或列,需要精确的映射关系。

四、CustomPainter绘制

4.1 展开图布局

voidpaint(Canvascanvas,Sizesize){finalcellSize=50.0;// 绘制前面_drawFace(canvas,0,Offset(150,150),cellSize);// 绘制上面_drawFace(canvas,4,Offset(150,50),cellSize);// 绘制下面_drawFace(canvas,5,Offset(150,250),cellSize);// 绘制左面_drawFace(canvas,2,Offset(50,150),cellSize);// 绘制右面_drawFace(canvas,3,Offset(250,150),cellSize);// 绘制后面_drawFace(canvas,1,Offset(350,150),cellSize);}

使用十字形展开图布局,前面为中心,其他面围绕排列。

4.2 单面绘制

void_drawFace(Canvascanvas,int faceIndex,Offsetoffset,double cellSize){for(int row=0;row<3;row++){for(int col=0;col<3;col++){finalrect=Rect.fromLTWH(offset.dx+col*cellSize,offset.dy+row*cellSize,cellSize-2,cellSize-2,);finalpaint=Paint()..color=getFaceColor(cube[faceIndex][row][col])..style=PaintingStyle.fill;canvas.drawRect(rect,paint);}}}

绘制单个面的3×3网格,每个小方格根据颜色值填充。

4.3 边框绘制

finalborderPaint=Paint()..color=Colors.black..strokeWidth=2..style=PaintingStyle.stroke;canvas.drawRect(rect,borderPaint);

每个小方格绘制黑色边框,增强视觉分离。

五、交互控制

5.1 面选择

int?selectedFace;void_handleTap(TapDownDetailsdetails){finallocalPosition=details.localPosition;for(int face=0;face<6;face++){if(_isPointInFace(localPosition,face)){setState((){selectedFace=face;});return;}}}

点击选择要旋转的面。

5.2 旋转按钮

Row(children:[ElevatedButton(onPressed:selectedFace!=null?()=>rotateFaceClockwise(selectedFace!):null,child:constText('顺时针'),),ElevatedButton(onPressed:selectedFace!=null?()=>rotateFaceCounterClockwise(selectedFace!):null,child:constText('逆时针'),),],)

提供顺时针和逆时针旋转按钮。

5.3 手势旋转

double?previousAngle;void_handlePanStart(DragStartDetailsdetails){if(selectedFace==null)return;finaldx=details.localPosition.dx-getFaceCenter(selectedFace!).dx;finaldy=details.localPosition.dy-getFaceCenter(selectedFace!).dy;previousAngle=atan2(dy,dx);}void_handlePanUpdate(DragUpdateDetailsdetails){if(selectedFace==null||previousAngle==null)return;finaldx=details.localPosition.dx-getFaceCenter(selectedFace!).dx;finaldy=details.localPosition.dy-getFaceCenter(selectedFace!).dy;finalcurrentAngle=atan2(dy,dx);if((currentAngle-previousAngle!).abs()>pi/4){rotateFaceClockwise(selectedFace!);previousAngle=currentAngle;}}

支持手势滑动旋转,每45度触发一次旋转。

六、状态管理

6.1 移动计数

int moveCount=0;voidrotateFaceClockwise(int faceIndex){// ...旋转逻辑setState((){moveCount++;});}

记录旋转次数,用于评估解法效率。

6.2 历史记录

List<String>moveHistory=[];voidaddMove(int face,bool clockwise){moveHistory.add('$face${clockwise?"CW":"CCW"}');}

记录每次旋转,支持撤销功能。

总结

本文详细介绍了魔方应用的3D数据结构和旋转算法。从三维数组设计到面旋转算法,从边缘联动到CustomPainter绘制,每个技术点都直接影响应用的功能性和用户体验。通过这些技术的综合应用,实现了功能完整且交互流畅的魔方应用。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/10 6:27:50

办公党必存|输入法自动切换神器+6款纯净版输入法

谁懂啊家人们&#xff01;切换窗口手动切输入法&#xff0c;五笔拼音来回乱跳&#xff0c;敲字效率直接砍半&#x1f62d; 今天给大家安排王炸组合——基于AutoHotkey&#xff08;Ahk版本1.1.33.10&#xff09;的中英文输入法自动切换工具&#xff0c;搭配6款今日更新/精选纯净…

作者头像 李华
网站建设 2026/2/9 20:38:15

程序猿实测五大模块!盲盒小程序不踩雷[特殊字符]

程序猿实测五大模块&#xff01;盲盒小程序不踩雷&#x1f4a1; 作为软件开发领域的从业者&#xff0c;这次针对盲盒小程序做了深度测评&#x1f4f1;。核心功能覆盖一番赏、无限赏、福袋、登天阶、快乐集合赏五大模块&#xff0c;逐一拆解体验细节&#xff1a; 1. 一番赏模块&…

作者头像 李华
网站建设 2026/2/10 7:34:02

AI智能体重构知识服务:创客匠人如何助力知识IP高效变现

在2026年OpenAI闭门会议的行业共识中&#xff0c;AI运行成本将大幅下降&#xff0c;这一趋势正在重塑知识服务的生产模式。当AI成本从"昂贵"变为"随用随取"&#xff0c;知识变现不再仅仅是内容创作的问题&#xff0c;而是系统性运营的问题。作为知识服务行…

作者头像 李华
网站建设 2026/2/9 21:52:39

java+vue基于springboot的校园商店零售管理系统

目录 摘要内容 开发技术路线结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01; 摘要内容 该系统基于SpringBoot后端框架和Vue.js前端框架&#xff0c;构建了一个校园商店零售管理系统&#xff0c;旨在优化校园零售业务流程&#xff0c;…

作者头像 李华
网站建设 2026/2/10 8:06:49

Flutter for OpenHarmony 实战_吃豆人游戏移动控制与碰撞检测

Flutter for OpenHarmony 实战&#xff1a;吃豆人游戏移动控制与碰撞检测 欢迎加入开源鸿蒙跨平台社区&#xff1a;开源鸿蒙跨平台开发者社区 文章目录Flutter for OpenHarmony 实战&#xff1a;吃豆人游戏移动控制与碰撞检测前言一、移动控制系统1.1 键盘输入处理1.2 触摸屏控…

作者头像 李华