Генерирование треугольных/шестиугольных координат (xyz)

Я пытаюсь придумать повторяющуюся функцию, которая генерирует xyz координаты для шестиугольной сетки. Со стартовым шестнадцатеричным положением (говорят 0,0,0 для простоты), я хочу вычислить координаты для каждого последовательного "кольца" шестиугольников, как проиллюстрировано здесь:

До сих пор все, что мне удалось придумать, является этим (пример в JavaScript):

var radius = 3
var xyz = [0,0,0];

// for each ring
for (var i = 0; i < radius; i++) {
    var tpRing = i*6;
    var tpVect = tpRing/3;
    // for each vector of ring
    for (var j = 0; j < 3; j++) {
        // for each tile in vector
        for(var k = 0; k < tpVect; k++) {
            xyz[0] = ???;
            xyz[1] = ???;
            xyz[2] = ???;
            console.log(xyz);
        }
    }
}

Я знаю, что каждое кольцо содержит еще шесть точек, чем предыдущее и каждый вектор на 120 ° содержат одну дополнительную точку для каждого шага от центра. Я также знаю это x + y + z = 0 для всех мозаик. Но как я могу генерировать список координат, которые следуют за последовательностью ниже?

    0, 0, 0

    0,-1, 1
    1,-1, 0
    1, 0,-1
    0, 1,-1
   -1, 1, 0
   -1, 0, 1

    0,-2, 2
    1,-2, 1
    2,-2, 0
    2,-1,-1
    2, 0,-2
    1, 1,-2
    0, 2,-2
   -1, 2,-1
   -2, 2, 0
   -2, 1, 1
   -2, 0, 2
   -1,-1, 2
28
задан Michael 23 March 2018 в 21:46
поделиться

3 ответа

Другое возможное решение, которое работает в o (радиус 2 ), в отличие от O (радиус 4 ) Решение Техмика (за счет большого количества стиля) это:

radius = 4
for r in range(radius):
    print "radius %d" % r
    x = 0
    y = -r
    z = +r
    print x,y,z
    for i in range(r):
        x = x+1
        z = z-1
        print x,y,z
    for i in range(r):
        y = y+1
        z = z-1
        print x,y,z
    for i in range(r):
        x = x-1
        y = y+1
        print x,y,z
    for i in range(r):
        x = x-1
        z = z+1
        print x,y,z
    for i in range(r):
        y = y-1
        z = z+1
        print x,y,z
    for i in range(r-1):
        x = x+1
        y = y-1
        print x,y,z

или написано немного более кратко:

radius = 4
deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]
for r in range(radius):
    print "radius %d" % r
    x = 0
    y = -r
    z = +r
    print x,y,z
    for j in range(6):
        if j==5:
            num_of_hexas_in_edge = r-1
        else:
            num_of_hexas_in_edge = r
        for i in range(num_of_hexas_in_edge):
            x = x+deltas[j][0]
            y = y+deltas[j][1]
            z = z+deltas[j][2]            
            print x,y,z

это вдохновлено тем фактом, что шестиугольники на самом деле на внешней стороне самих шестиугольников, так Вы можете найти координаты из 1 его очков, а затем рассчитать других, двигаясь на его 6 краях.

13
ответ дан 28 November 2019 в 03:41
поделиться

Это зависит от используемого цветового пространства. Если RGBA находится в предварительно умноженном цветовом пространстве и полупрозрачен, необходимо разделить альфа, чтобы получить правильный цвет RGB. Если цвет находится в неумноженном цветовом пространстве, то альфа-канал можно просто отбросить.

-121--87922-

Сбой загрузки HTML-страниц с «Доверенного сайта» для моего локального приложения ( http ://localhost/) - пока я не добавлю localhost в список Доверенных сайтов.

Silverlight предотвращает «кросс-зональные» вызовы (в моем случае Локальная сеть против доверенных сайтов) и «кросс-схемные» вызовы (например, http против https).

И пока работает только с файлом «crossdomain.xml». Сначала я попробовал «clientaccesspolicy.xml», но не получил его.

-121--2720426-

Не только является x + y + z = 0 , но абсолютные значения x, y и z равны удвоенному радиусу кольца. Этого должно быть достаточно для идентификации каждого шестиугольника на каждом последовательном кольце:

 var radius = 4; для (var i = 0; i < радиус; i++) {для (var j = -i; j < = i; j++) для (var k = -i; k < = i; k++) для (var l = -i; l < = i; l++) если (Math.abs (j) + Math.abs (k) + Math.abs (l) = = i * 2 & & j + k + l = = 0) console.log (j + «,» + k + «,» + l); console.log (»»);} 
14
ответ дан 28 November 2019 в 03:41
поделиться

Существует два пакета ГРУШИ и Zend Рамки v1.10 также будет иметь класс BarCode.

Я не использовал ни один из них, поэтому я не могу рекомендовать его.

-121--3329781-

с использованием теоремы Пифагора (где x1, y1 - точка ребра):

x1 = x + r cos (theta)
y1 = y + r
sin (theta)

в C #, это будет выглядеть следующим образом:

x1 = x + radius * Math.Cos(angle * (Math.PI / 180));
y1 = y + radius * Math.Sin(angle * (Math.PI / 180));

, где все переменные являются двойными и угол в градусах

-121--1506134-

Хорошо, попробовав оба варианта, я остановился на решении Офри, поскольку оно немного быстрее и облегчило предоставление начального значения смещения. Теперь мой код выглядит следующим образом:

var xyz = [-2,2,0];
var radius = 16;
var deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]];
for(var i = 0; i < radius; i++) {
        var x = xyz[0];
        var y = xyz[1]-i;
        var z = xyz[2]+i;
        for(var j = 0; j < 6; j++) {
                for(var k = 0; k < i; k++) {
                        x = x+deltas[j][0]
                        y = y+deltas[j][1]
                        z = z+deltas[j][2]
                        placeTile([x,y,z]);
                }
        }
}

Метод «pleyTile» использует cloneNode для копирования предопределенного элемента svg, и для его выполнения требуется приблизительно 0,5 мс на плитку, что более чем достаточно. Большое спасибо техМику и Офри за вашу помощь!

JS

1
ответ дан 28 November 2019 в 03:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: