autojs画六边形

简介: 我们一组一组的计算六边形中心点, 一组有两排六边形:第一排5个第二排4个下一组, 往下移动 3 个边长,因为第一组, 我们已经检查过画板右侧

牙叔教程 简单易懂

界面基础代码

"nodejs ui";

require("rhino").install();

const ui = require("ui");

class MainActivity extends ui.Activity {

 constructor() {

   super();

 }

 get layoutXmlFile() {

   return "layout.xml";

 }

 onContentViewSet() {}

}

ui.setMainActivity(MainActivity);



创建Hexagon类

class Hexagon {}

至于需要的属性, 有需求的时候再写

界面布局

<column>

<canvas id="canvas" w="*" h="*">

</canvas>

</column>


画板事件

 onContentViewSet(view) {

   const canvasView = view.binding.canvas;

   canvasView.on("draw", (canvas) => {

     canvas.drawColor(canvasBgColor);

   });

 }


计算并绘制六边形中心点

let canvasWidth = canvasView.getWidth();

let canvasHeight = canvasView.getHeight();

let centerX = canvasWidth / 2;

let centerY = canvasHeight / 2;

canvasView.on("draw", (canvas) => {

 canvas.drawColor(canvasBgColor);

 canvas.drawPoint(centerX, centerY, paint);

});


计算六边形六个点的坐标

这个方法应该属于六边形这个类

 getSixPoints() {

   let points = [];

   let angle = 0;

   for (let i = 0; i < 6; i++) {

     let x = this.centerX + this.sideLength * Math.cos(angle);

     let y = this.centerY - this.sideLength * Math.sin(angle);

     points.push({ x, y });

     angle += Math.PI / 3;

   }

   return points;

 }


计算六边形的path

这个也属于六边形的方法

 getPath() {

   const path = new Path();

   let points = this.getSixPoints();

   path.moveTo(points[0].x, points[0].y);

   for (let i = 1; i < points.length; i++) {

     path.lineTo(points[i].x, points[i].y);

   }

   path.close();

   return path;

 }


绘制六边形

let hexagon = new Hexagon(centerX, centerY, config.sideLength);

let hexagonPath = hexagon.getPath();

canvasView.on("draw", (canvas) => {

 canvas.drawColor(canvasBgColor);

 canvas.drawPoint(centerX, centerY, paint);

 canvas.drawPath(hexagonPath, paint);

});


绘制一排六边形

要绘制一排, 那么六边形左右两边需要是数直的, 把 getSixPoints 方法里的 sin 和 cos 对调一下即可

let x = this.centerX + this.sideLength * Math.sin(angle);

let y = this.centerY - this.sideLength * Math.cos(angle);

确定边界条件

所有六边形都要在画板内, 我们画左上角第一个六边形;

计算中心点要考虑的条件

  • 画笔的宽度
  • 六边形边长

let angle = Math.PI / 3;

let firstHexagonCenterX = config.sideLength * Math.sin(angle) + config.paintConfig.width;

let firstHexagonCenterY = config.sideLength + config.paintConfig.width;


考虑两个相邻的六边形连接处

两个挨着的竖边, 应该只需要画一条, 那么来计算第二个六边形的中心位置, 以第一个六边形为参照物

let secondHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle) * 2;

let secondHexagonCenterY = firstHexagonCenterY;

绘制出的两个六边形

改了一下宽度, 方便观察


限制一排六边形最后一个的边界

最后一个六边形的最右侧的边, 不能超过画板

let hexagonPaths = [];

let count = 1;

while (1) {

 let nextHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle) * 2 * count;

 if (nextHexagonCenterX + config.sideLength * Math.sin(angle) + config.paintConfig.width > canvasWidth) {

   break;

 }

 let nextHexagonCenterY = firstHexagonCenterY;

 let nextHexagon = new Hexagon(nextHexagonCenterX, nextHexagonCenterY, config.sideLength);

 let nextHexagonPath = nextHexagon.getPath();

 hexagonPaths.push(nextHexagonPath);

 count++;

}

for (let i = 0; i < hexagonPaths.length; i++) {

 canvas.drawPath(hexagonPaths[i], paint);

}


画第二排六边形

计算第二排第一个六边形的中心点

let nextRowFirstHexagonCenterX = firstHexagonCenterX + config.sideLength * Math.sin(angle);

let nextRowFirstHexagonCenterY = firstHexagonCenterY + config.sideLength * Math.cos(angle) + config.sideLength;

let nextRowFirstHexagon = new Hexagon(nextRowFirstHexagonCenterX, nextRowFirstHexagonCenterY, config.sideLength);

let nextRowFirstHexagonPath = nextRowFirstHexagon.getPath();


与第一排同理, 画第二排


绘制多排六边形

很明显, 我们要使用循环, 横着要循环, 竖着也要循环, 那么这个循环怎么写呢?

我们一组一组的计算六边形中心点, 一组有两排六边形:

  • 第一排5个
  • 第二排4个

下一组, 往下移动 3 个边长,

因为第一组, 我们已经检查过画板右侧,

所以, 接下来的计算, 只需要考虑画板底部, 不需要判断画板右侧了;

我们改变的只有纵坐标

先画一组

let firstRow = [];

let secondRow = [];

let firstGroup = [firstRow, secondRow];

let firstRowCount = 0;

while (1) {

 let centerX = firstHexagonCenterX + firstRowCount * config.sideLength * 2 * Math.sin(angle);

 if (centerX > canvasWidth - config.sideLength * Math.sin(angle) - config.paintConfig.width) {

   break;

 }

 let centerY = firstHexagonCenterY;

 firstRow.push(new Hexagon(centerX, centerY, config.sideLength));

 firstRowCount++;

}

/* -------------------------------------------------------------------------- */

let secondRowCount = 0;

while (1) {

 let centerX = firstHexagonCenterX + secondRowCount * config.sideLength * 2 * Math.sin(angle) + config.sideLength * Math.sin(angle);

 if (centerX > canvasWidth - config.sideLength * Math.sin(angle) - config.paintConfig.width) {

   break;

 }

 let centerY = firstHexagonCenterY + config.sideLength + config.sideLength * Math.cos(angle);

 secondRow.push(new Hexagon(centerX, centerY, config.sideLength));

 secondRowCount++;

}

hexagons = firstGroup.flat();

let hexagonPaths = hexagons.map((hexagon) => hexagon.getPath());

/* -------------------------------------------------------------------------- */

canvasView.on("draw", (canvas) => {

 canvas.drawColor(canvasBgColor);

 for (let i = 0; i < hexagonPaths.length; i++) {

   canvas.drawPath(hexagonPaths[i], paint);

 }

});

这是一个二维数组, 我们用flat抹平成一维数组

一组一组的计算坐标

y坐标依次增长3个边长即可

先计算第一排, 再计算第二排

let row = 1;

while (1) {

 let nextGroupFirstRow = [];

 let nextGroupSecondRow = [];

 let nextGroup = [nextGroupFirstRow, nextGroupSecondRow];

 let firstGroupFirstRow = firstGroup[0];

 let firstGroupFirstHexagon = firstGroupFirstRow[0];

 if (firstGroupFirstHexagon.centerY + config.sideLength * 3 * row > canvasHeight) {

   break;

 }

 nextGroupFirstRow = firstGroupFirstRow.map((hexagon) => {

   let centerX = hexagon.centerX;

   let centerY = hexagon.centerY + config.sideLength * 3 * row;

   nextGroupFirstRow.push(new Hexagon(centerX, centerY, config.sideLength));

 });

 let firstGroupSecondRow = firstGroup[1];

 let firstGroupSecondHexagon = firstGroupSecondRow[0];

 if (firstGroupSecondHexagon.centerY + config.sideLength * 3 * row > canvasHeight) {

   break;

 }

 nextGroupSecondRow = firstGroupSecondRow.map((hexagon) => {

   let centerX = hexagon.centerX;

   let centerY = hexagon.centerY + config.sideLength * 3 * row;

   nextGroupSecondRow.push(new Hexagon(centerX, centerY, config.sideLength));

 });

 groups.push(nextGroup);

 row++;

}

hexagons = groups.flat(2);

let hexagonPaths = hexagons.map((hexagon) => hexagon.getPath());

环境


设备: 小米11pro
Android版本: 12
Autojs版本: 9.3.11



名人名言


思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程


声明


部分内容来自网络 本教程仅用于学习, 禁止用于其他用途


相关文章
|
存储 缓存 图形学
ABC动画插件Alembic从浅入深(Unity3D)
今天分享一下Alembic插件的使用教程,这个插件的主要作用就是将.abc文件导入到Unity,然后进行播放。 .abc文件主要是影像业界使用的数据格式,用于存储巨大的顶点缓存数据。 Alembic插件就是转化这些影像资料和动力学等的模拟结果转换为顶点缓数 据为Unity可以使用的文件
|
3月前
如何用Qt抠一个圆形头像出来
如何用Qt抠一个圆形头像出来
|
前端开发 Android开发
autojs自定义控件-移动背景
我们把背景看成一个小球, 小球可以在某个空间内自由移动, 他需要一个目标的坐标信息, 然后需要一个从当前的起点, 到目标点的移动规则, 小球也可以在移动的时候变换形态, 比如圆形, 椭圆, 圆角矩形等
349 0
|
前端开发
autojs之十二圆
使用情景 给孩子画个圆
194 0
|
编解码 数据可视化 Java
autojs多分辨率找透明图
牙叔教程 简单易懂
411 0
|
XML 前端开发 调度
autojs用MCV框架实现界面切换
牙叔教程 简单易懂
488 0
|
前端开发 数据可视化 Android开发
autojs之超椭圆
使用场景 可视化 超椭圆系数 对 曲线 的作用
183 0
|
JavaScript Java Android开发
autojs颜色渐变效果
牙叔教程 简单易学 使用场景 颜色渐变
169 0