autojs画六边形

news2024/12/22 22:30:57

牙叔教程 简单易懂

界面基础代码

"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文档, 最后才是群里问问 --- 牙叔教程

声明

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/183484.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高效学 C++|继承与组合

继承是面向对象程序设计的重要特性之一。作为面向对象的编程语言&#xff0c;C语言也自然支持这个特性。继承是代码复用的基本方法之一&#xff0c;也是接口和复用设计的关键。本文介绍继承的含义和继承与组合的关系。 01、继承的含义 面向对象程序设计通过将问题域中的事物抽…

Web 应用程序的文件系统写入能力

介绍 NodeJS 之前&#xff0c;JS 操作文件只能通过 HTML <input type"file"> 元素或 XMLHttpRequest&#xff08;或之后的 fetch&#xff09;&#xff0c;来对本地文件进行一些浏览和上传操作。NodeJS 给予了 JS 操作系统底层 API 的能力&#xff0c;但这只能…

章节7 查看和处理文件内容

7-查看和处理文件内容 文本文件 ASCII、UTF-8、Unicode、ANSItxt、xml、conf、properties、yml等配置文件、日志文件、源代码 二进制文件 可执行文件、图片、音频、视频 cat 全拼&#xff1a;concatenate [kənˈkt(ə)nˌeɪt] 连接 格式&#xff1a;cat 文件名 more/…

eyeurl—一款网页批量截图工具

eyeurl使用说明 开发说明 eyeurl由作者&#xff1a;云小书 开发&#xff0c;源于日常渗透测试中&#xff0c;信息收集到的url过多&#xff0c;挨个打开查看比较繁琐&#xff0c;且效率极低&#xff0c;网上有大佬开发的eyewitness&#xff0c;且ui布局各方面都比较完善&#…

sadserver 题目思路概述

背景 从 阮一峰老师的博客 了解到 sadserver 可以在线挑战一些 linux 指令相关问题&#xff08;整体难度一般&#xff0c;但做题体验不错&#xff0c;有提示&#xff09;&#xff0c;这里将目前网站提供的的16道题进行简单解答&#xff0c;提供思路和相关指令 本文csdn 博客地…

初识Java虚拟机

1.概述 Java虚拟机&#xff1a;Java Virtual Machine。正是有了Java虚拟机&#xff0c;Java语言实现了跨平台的特性&#xff0c;一次编译&#xff0c;多处运行。 目前使用范围最广的虚拟机就是Hotspot VM&#xff0c;它是OracleJDK和OpenJDK中的默认Java虚拟机。 相比于其他…

[Android Studio]开发APP应用出现软件程序打开闪退的排错

&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Android Debug&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; Topic 发布安卓学习过程中遇到问题解决过程&#xff0c;希望我的解决方案可以对小伙伴们有帮助。 &#x1f4cb;笔记目…

你还没用过Mybatis-Plus?丝般顺滑,快速上手!

一、概述 1.1、什么是MyBatis-Plus MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 1.2、特性 无侵入&#xff1a;只做…

RabbitMQ入门前篇

本篇博文目录:一.RabbitMQ1.消息队列2.RabbitMQ3.安装RabbitMQ4.RabbitMQ常用命令二.使用RabbitMQ进行编程1.AMQP2.第一次MQ通信三.RabbitMQ六中工作模式1.RabbitMQ2.Work queues3.pub/sub订阅发布模式4.Routing模式5.主题Topic模式四.RabbitMQ消息确认机制五.源代码下载一.Rab…

我性格比较内向,适合做管理吗?

许多刚走上管理岗位的朋友&#xff0c;都有这样的困惑&#xff1a;1.我比较内向&#xff0c;不适合做管理。2.我不擅长演讲&#xff0c;没有领导才能。3.我太谨小慎微了&#xff0c;做不好领导。4.我太喜欢出风头&#xff0c;静不下心来做管理。5.我太强势了&#xff0c;团队很…

GuLi商城-项目初始结构创建,GitHub仓库创建

GitHub账号和密码 账号&#xff1a;11360XXXXXqq.com 密码&#xff1a;ZH**SH*19**1016 新建仓库&#xff1a; gulimall 记得勾选下Add a README file&#xff0c;上面忘记勾选了&#xff0c;实际建议还是要勾选下 复制路径&#xff1a; 打开IDEA检出项目 创建商品微服务模…

芯片设计|FPGA 设计的指导原则(一)

这一部分主要介绍 FPGA/CPLD 设计的指导性原则&#xff0c;如 FPGA 设计的基本原则、基本设计思想、基本操作技巧、常用模等。 FPGA/CPLD 设计的基本原则、思想、技巧和常用模块是一个非常大的问题&#xff0c;在此不可能面面俱到&#xff0c;只能我们公司项目中常用的一些设计…

权值线段树 详解+操作模板(c++)

文章目录权值线段树添加一个数字求某数出现的次数查询一段区间中数字出现的次数查询整个值域中第k小的数查询整个值域中第k大的数例子&#xff1a;求逆序对关于基本线段树与线段树的模板&#xff0c;请看我们之前发布的博客&#xff1a; 线段树入门详解 维护加法乘法&#xff0…

关于“茴香豆的‘茴’有几种写法”:学习过程中,若时间精力有限则优先记住最好用的一种

学习过程中的细节整理和精力节省权衡 我平时学习有整理总结、记笔记的习惯。 我学新东西总是很慢&#xff0c;因为细节处几乎都不会放过&#xff0c;会去发散&#xff0c;去深挖&#xff0c;去比较之前。 刚才上网&#xff0c;查了C语言中二维数组的赋值方式&#xff0c;某个…

UVM实战笔记(七)

第七章. UVM中的寄存器模型 7.1 寄存器模型简介 7.1.1 带寄存器配置总线的DUT 本章节使用的DUT带寄存器配置&#xff0c;代码如下&#xff1a; module dut(clk,rst_n,bus_cmd_valid,bus_op,bus_addr,bus_wr_data,bus_rd_data,rxd,rx_dv,txd,tx_en)input clk; …

DaVinci:Camera Raw(Sony RAW)

本文主要介绍 Sony RAW 格式素材相关的 Camera Raw 参数。解码质量Decode Quality解码质量决定了图像解拜耳之后所呈现的素质。默认为“使用项目设置” Use project setting&#xff0c;表示使用项目设置对话框中的“Camera RAW”解码质量设置。还可选择&#xff1a;全分辨率 -…

JavaEE-网络编程

目录一、网络编程套接字二、UDP Socket2.1 客户端服务器程序-回显服务(EchoServer)2.1.1 UdpEchoServer2.1.2 UdpEchoClient2.1.3 一个简单程序三、TCP 客户端服务器程序3.1 TCP API一、网络编程套接字 网络编程套接字就是操作系统给应用程序提供的一组API(叫做socket API)。 …

NLP学习笔记(七) BERT简明介绍

大家好&#xff0c;我是半虹&#xff0c;这篇文章来讲 BERT\text{BERT}BERT (Bidirectional Encoder Representations from Transformers) 原始论文请戳这里 0 概述 从某种程度上来说&#xff0c;深度学习至关重要的一环就是表征学习&#xff0c;也就是学习如何得到数据的向…

怎么把两个PDF合并?教你们几个简单的方法

不知道大家平时处理文件的数量多不多&#xff0c;但是小编日常处理文件真的特别多&#xff0c;所以小编经常会使用专业的格式转换器来处理文件&#xff0c;这样就可以高效处理文件了&#xff0c;例如我们需要将多个PDF文件合并&#xff0c;这样就只需要传输一个文件就可以了&am…

自定义starter解决请求绕过网关问题

引言 微服务项目中网关是一个常见的模块&#xff0c;通过网关的分发可以实现负载均衡、鉴权等操作&#xff1b;但是搭建好网关可以发现&#xff0c;虽然可以通过网关端口请求后端&#xff0c;如果有其他服务的地址依然可以使用其他服务地址绕过网关请求&#xff0c;这里我提供…