Как «Надуть» (как в прямоугольнике) или масштабировать шестиугольник - PullRequest
1 голос
/ 23 мая 2019

Сейчас я работаю над проектом с сеткой, заполненной шестиугольниками.Каждый шестиугольник имеет одинаковый размер, и я рисую границы для каждого из них.

Ответы [ 2 ]

1 голос
/ 23 мая 2019

Есть несколько подходов к проблеме. Давайте сначала упростим:

  • Вы можете создать шестиугольник в нужном размере и месте с самого начала. Это просто, по крайней мере, если вы хотите симметричные многоугольники.

Посмотрим:

List<PointF> Polygon(PointF center, int count, float radius, float angle)
{
    List<PointF> pts = new List<PointF>();
    for (float i = angle; i < 360; i+= 360f/count)
    {
        float rad = (float)(Math.PI / 180 * i);
        pts.Add(new PointF(center.X + (float)Math.Sin(rad) * radius,
                            center.Y + (float)Math.Cos(rad) * radius));
    }
    return pts;
}

Это позволяет выбрать местоположение центра, симметрию, размер и начальный угол. Чтобы получить шестиугольник, направленный вверх на (99,99) с высотой 160, используйте этот вызов:

List<PointF> points = Polygon(new PointF(99, 99), 6, 80, 0);
  • Или вы можете преобразовать данный многоугольник. Для этого вы можете использовать любой многоугольник (или любой набор точек), но вам нужно определить центр фигуры и рассчитать необходимый коэффициент масштабирования.

Чтобы использовать коэффициент 1.25f для обеих осей и перевести на (40, 10), используйте это:

var points2 = points.ToArray();  // create a copy
using (Matrix m = new Matrix())
{
    m.Scale(1.25f, 1.25f, MatrixOrder.Append);
    m.Translate(40, 10, MatrixOrder.Append);
    m.TransformPoints(points2);
}

Результат:

hexagons

Обратите внимание, что для создания регулярной сетки вы, вероятно, избежите меньшего количества кода, используя первый метод.

Давайте нарисуем сетку из шестиугольников:

int r = 80;
float w = (float)(Math.Sin(Math.PI / 180 * 60) * r);
float h = (float)(Math.Cos(Math.PI / 180 * 60) * r);

for (int i = 0; i < 4; i++)
{
    e.Graphics.ResetTransform();
    e.Graphics.TranslateTransform(0, (r * 2  + h * 2)  * i);
    for (int j = 0; j < 4; j++)
    {
        e.Graphics.TranslateTransform(w * 2, 0);
        e.Graphics.DrawPolygon(Pens.Green, points.ToArray());
        e.Graphics.TranslateTransform(w, r + h);
        e.Graphics.DrawPolygon(Pens.Green, points.ToArray());
        e.Graphics.TranslateTransform(-w, -r- h );
    }
}

Результат:

hex-grid

1 голос
/ 23 мая 2019

Для того, чтобы это работало с матрицей, вам нужно будет построить матрицу из единичной матрицы X и матрицы перевода, чтобы переместить центр многоугольника в начало координат (0, 0) X масштабной матрицы для масштабированиякоординаты немного меньше (или больше) на основе соотношения X матрицы перевода, чтобы переместить координаты туда, где они были до начала.Затем вы можете применить полученную матрицу к каждой из ваших координат (как к векторам), и каждая из них будет преобразована.

Матрица полезна, если у вас есть много одинаковых преобразований для работы с большим количеством координат,потому что вы рассчитываете матрицу один раз и быстро применяете ее ко многим векторам.В этом случае у вас есть только 6 векторов (координат), так что это не сильно вас спасет.Ваш подход добавления целых чисел к координатам будет выполняться быстрее, и при условии, что вы инкапсулируете, что это метод с хорошим именем и многократного использования, например, GetInlayPolygonForTile(), он будет достаточно читабельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...