当前位置: 首页 > 知识库问答 >
问题:

在六边形上旋转索引

曾光远
2023-03-14
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个答案

敖淮晨
2023-03-14

一种方法是将十六进制排列在圆环中,每个圆环作为一个数组,从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距离,以及知道旋转。 我的代码目前看起来像这样(当然,对象是有问题的矩形,请记住,当我应用它时,它可以具有任何维度 - 这只是一种可能性。初始宽度和高度是实际的长度和宽度,而后面引

  • 本文向大家介绍用css画一个五边形和一个六边形相关面试题,主要包含被问及用css画一个五边形和一个六边形时的应答技巧和注意事项,需要的朋友参考一下 还有 svg 转 base64 作背景图。 当然,点击范围可能会不符合需求。 另外提一句,clip-path 边框要另做,元素选择的背景图要另做,两种都不好做圆角。