Size 1:
0
Size 2:
0 1
2 3 4
5 6
Size 3:
0 1 2
3 4 5 6
7 8 9 A B
C D E F
101112
Size 1:
0
Size 2:
2 0
5 3 1
6 4
Size 3:
7 3 0
C 8 4 1
10 D 9 5 2
11 E A 6
12 F B
function hex(n) {
return 3 * +n * (+n + 1) + 1;
}
function reverse_hex(n) {
n = (+n - 1) / 3;
var i = Math.floor(Math.sqrt(n));
// null if not a hex number
return i * (i + 1) === n ? i : null;
}
我可以轻松地做0度和180度的旋转。我可以从旋转60度几次得到60度的其他倍数。
function rotate(index, direction, size) {
// The unit of direction is 60 degrees. So "1" == rotate by 60 degrees.
direction = ((+direction % 6) + 6) % 6;
switch (direction) {
case 0:
return index;
case 1:
// Something?
return transformed_index;
case 2:
return rotate(rotate(index, 1, size), 1, size);
case 3:
return hex(size) - index - 1;
case 4:
return rotate(rotate(index, 3, size), 1, size);
case 5:
return rotate(rotate(index, 3, size), 2, size);
default: // (NaN or +/-Infinity) % 6 is NaN
return null;
}
}
但我想不出一个算法来做到这一点。
一种方法是将十六进制排列在圆环中,每个圆环作为一个数组,从1到6,依此类推。要旋转,从顶部移动每个环形阵列到底部。所以如果你有一个大小为4的十六进制,那么外环从外环的顶部移动3到底部,然后从下一个环移动2,以此类推。
这使得在2D中获取索引变得很棘手。您可以通过创建第二个行数组来解决这个问题。每一行都是进入环形结构的索引数组。因此,如果您想要第2行左起第4的单元格,请查找数组pos[2][4]以获得环索引。在本例中,我对环索引进行了编码,所以您只需要一个数字就可以查找环,然后在环中定位。
该示例显示了一个大小为5的十六进制,从左到右创建了编号,然后从左到右创建了下一行。十六进制旋转60°。
const ctx = canvas.getContext("2d");
const font = "arial";
const fontSize = 14;
function createHex(size) {
// create object to hold a hexagon
const hexagon = {
count: 0,
hex: [],
};
// do first two rows manualy
if (size >= 1) {
hexagon.hex.push([0]);
hexagon.count += 1;
}
if (size >= 2) {
hexagon.hex.push([0, 1, 2, 3, 4, 5]);
hexagon.count += 6;
}
// keep adding rings until correct size
for (var i = 3; i <= size; i++) {
const ring = [];
for (var j = 0; j < i * 2 + 2 + (i - 2) * 4; j++) {
ring.push(j);
}
hexagon.hex.push(ring);
hexagon.count += ring.length;
}
// get the max rign size to use as modulo for row column lookup
hexagon.maxRingLen = size * 2 + 2 + (size - 2) * 4
// create an array for row column lookup
hexagon.pos = [];
// pos to prevent the array from becoming a sparse array
// create each row array and fill with dummy data
for (var i = 0; i < size + size - 1; i++) {
const row = [];
for (var j = 0; j < ((size + size - 1) - (Math.abs((size - 1) - i) - 1)) - 1; j++) {
row.push(0); // add dummy data
}
hexagon.pos.push(row);
}
// this array contains row, column steps for the six ring sizes
const steps = [1, 0, 1, 1, -1, 1, -1, 0, 0, -1, 0, -1];
// each ring starts at the top left and goes round clockwise
for (var i = 0; i < size; i++) {
const ringIndex = size - 1 - i
const ring = hexagon.hex[ringIndex];
var x = size - 1 - ringIndex;
var y = size - 1 - ringIndex;
for (var j = 0; j < ring.length; j++) {
// add the ring position index
hexagon.pos[y][x] = ringIndex * hexagon.maxRingLen + j
// find the next row column pos
const side = Math.floor(j / ringIndex) * 2;
x += steps[side];
y += steps[side + 1];
}
}
// now that we have the row column lookup you can
// create the correct sequence of numbers in the hexagon
// starting at top left moving from left to right all the way to the
// bottom right last number
var count = 0;
for (var i = 0; i < hexagon.pos.length; i++) {
const row = hexagon.pos[i];
for (var j = 0; j < row.length; j++) {
const ringPos = row[j] % hexagon.maxRingLen;
const ringIndex = Math.floor(row[j] / hexagon.maxRingLen);
hexagon.hex[ringIndex][ringPos] = count++;
}
}
return hexagon;
}
// rotates a hexagon 60deg
function rotateHex(hexagon) {
const size = hexagon.hex.length;
for (var i = 1; i < size; i++) { // from inner ring do each ring
const ring = hexagon.hex[i];
for (var j = 0; j < i; j++) {
// move the top to bottom of ring array
ring.unshift(ring.pop());
}
}
}
// just renders for testing.
function renderHex(hexagon, pos) {
const steps = [1, 0, 0.5, 1, -0.5, 1, -1, 0, -0.5, -1, 0.5, -1]
ctx.font = (fontSize-4) + "px " + font;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const size = hexagon.length;
for (var i = 0; i < size; i++) {
const ringIndex = size - 1 - i
const ring = hexagon[ringIndex];
var x = pos.x - (ringIndex * fontSize * 0.5);
var y = pos.y - (ringIndex * fontSize);
for (var j = 0; j < ring.length; j++) {
ctx.fillText(ring[j].toString(36), x, y);
const side = Math.floor(j / ringIndex) * 2;
x += steps[side] * fontSize;
y += steps[side + 1] * fontSize;
}
}
}
var h = createHex(5);
renderHex(h.hex, {
x: canvas.width * (1 / 4),
y: canvas.height * (2 / 4)
});
rotateHex(h);
renderHex(h.hex, {
x: canvas.width * (3 / 4),
y: canvas.height * (2 / 4)
});
<canvas id="canvas"></canvas>
我写了一个方法,随机生成多边形形状,然后在屏幕上旋转和移动。因为我想检测与这些形状的碰撞,所以我没有使用Graphics2D旋转它们,而是使用仿射变换来旋转它们。但由于某些原因,某些形状被旋转弄得一团糟,而其他形状则不受影响。下面是一个导致问题的形状示例。 如果用以下直线替换这些点,则形状基本保持不变。下面的形状当然是对称的,但是旋转方法确实适用于其他随机生成的不均匀形状。
我正在做一个WebGL(带有2d画布后备照片编辑器)。 我决定将旋转直接纳入裁剪工具,以类似于iOS8照片裁剪器的方式。也就是说,当您旋转照片时,照片的大小和位置会动态变化,以便裁剪区域始终包含在照片本身中。 但是,我正在为一些数学而苦苦挣扎。 我有两个矩形,照片和裁剪区域。 两者都被定义为: 定义照片本身的矩形也有一个以弧度表示的< code>rotation属性,它当然描述了照片的角度(以弧度
我使用预先训练好的mobilenet模型构建了Tensorflow Lite演示摄像头应用程序,如所述https://www.tensorflow.org/lite/convert/cmdline_examples. 据我所知,AndroidNNAPI(神经网络api)支持高通六边形数字信号处理器。如果可能的话,我想让Tensorflow Lite的演示应用程序在我手机上的六边形数字信号处理器芯片
问题内容: 我在本教程中使用了六边形代码,并创建了一个createHex类(我应该发布代码吗?)。链接的网页已使用以下代码通过createHex中的数学运算实际绘制六边形: 我遇到的问题是Android没有包含所有必需方法的Graphics类。我在android文档上做了大约一个半小时的钓鱼,而我发现最接近的东西是Path类,但是它没有我需要的方法。我想在顶部的链接文章中使用六边形代码,但找不到等
我在AS3工作。 我有一个通用的矩形。这个矩形可以有任何长度、任何宽度和任何旋转。我正在尝试求解矩形四个角的x和y坐标。我知道矩形中心的坐标,我知道它的宽度、高度、最高点和最低点之间的y距离以及最远左侧和最远右侧之间的x距离,以及知道旋转。 我的代码目前看起来像这样(当然,对象是有问题的矩形,请记住,当我应用它时,它可以具有任何维度 - 这只是一种可能性。初始宽度和高度是实际的长度和宽度,而后面引
这更多的是一个方法问题,而不仅仅是技术问题。 我有一个生成的球体,分解成六边形作为一个网格。每一个六边形瓷砖都是一种不同的地形,例如,山,丘陵,海洋,飞机等。我想在3D中把每一种地形类型画成几个网格的集合,代表一种相应的地形类型。 现在最大的问题是如何在运行时将地形网格调整到每个六边形面,这取决于地形类型,在运行时地形类型也会发生变化,例如,地形变形。同时,考虑到六边形并不是完全正则或相等的。 缩