We will learn how to depict a hexagonal prism in various positions.

Learn different ways to build a regular hexagon, draw hexagon drawings, check if they are correct. Draw hex prisms from the hexagons.

Consider the hex prism in fig. 3.52 and its orthogonal projections in Fig. 3.53. Regular hexagons lie at the base of the hexagonal prism (hexagon), the side faces are identical rectangles. In order to correctly depict a hexagon in perspective, you must first learn how to correctly depict its base in perspective (Fig. 3.54). In the hexagon in Fig. 3.55 peaks are marked with numbers from one to six. If you connect points 1 and 3, 4 and 6 with vertical lines, you can see that these lines, together with the point of the center of the circle, divide the diameter 5 - 2 into four equal segments (these segments are indicated by arcs). Opposite sides of a hexagon are parallel to each other and a line passing through its center and connecting two vertices (for example, sides 6 - 1 and 4 - 3 are parallel to line 5 - 2). These observations will help you construct the hexagon in perspective, as well as verify the correctness of this construction. There are two ways to construct a regular hexagon from a representation: on the basis of the circumcircle and on the basis of the square.

Based on the circumscribed circle. Consider fig. 3.56. All vertices of a regular hexagon belong to the circumcircle, the radius of which is equal to the side of the hexagon.


Horizontal hexagon. Draw a horizontal, freehand ellipse, that is, the circumscribed circle in perspective. Now you need to find six points on it, which are the vertices of the hexagon. Draw any diameter of the given circle through its center (fig. 3.57). The extreme points of the diameter - 5 and 2, lying on the ellipse, are the vertices of the hexagon. To find the rest of the vertices, you need to divide this diameter into four equal segments. The diameter is already divided by the center point of the circle into two radii, it remains to divide each radius in half. In the perspective drawing, all four segments are evenly cut off with distance from the viewer (Fig. 3.58). Now draw through the midpoints of the radii - points A and B - straight lines perpendicular to the straight line 5 - 2. You can find their direction using the tangents to the ellipse at points 5 and 2 (Fig. 3.59). These tangents will be perpendicular to the diameter 5 - 2, and the lines drawn through points A and B parallel to these tangents will also be perpendicular to the line 5 - 2. Designate the points obtained at the intersection of these lines with the ellipse as 1, 3, 4, 6 ( (See Figure 3.60) Connect all six vertices with straight lines (Fig. 3.61).

Check the correctness of your construction in different ways. If the construction is correct, then the lines connecting the opposite vertices of the hexagon intersect at the center of the circle (Fig. 3.62), and the opposite sides of the hexagon are parallel to the corresponding diameters (Fig. 3.63). Another way to check is shown in Fig. 3.64.

Vertical hexagon. In such a hexagon, the straight lines connecting points 7 and 3, b and 4, as well as tangents to the circumscribed circle at points 5 and 2, have a vertical direction and retain it in the perspective drawing. Thus, drawing two vertical tangents to the ellipse, we find points 5 and 2 (points of tangency). Connect them with a straight line, and then divide the resulting diameter 5 - 2 into 4 equal segments, taking into account their perspective cuts (Fig. 3.65). Draw vertical lines through points A and B, and at their intersection with the ellipse find points 1,3,6L4. Then connect points 1 - 6 in series with straight lines (Fig. 3.66). Check the correctness of the construction of the hexagon in the same way as in the previous example.

The described method of constructing a hexagon allows you to get this figure based on a circle, which is easier to draw in perspective than a square of given proportions. Therefore, this method of constructing a hexagon seems to be the most accurate and versatile. The construction method based on a square makes it easy to depict a hexagon in the case when there is already a cube in the drawing, in other words, when the proportions of the square and the direction of its sides are determined.

Based on a square. Consider fig. 3.67. A hexagon inscribed in a square in the horizontal direction 5 - 2 is equal to the side of the square, and in the vertical direction it is less than its length.

Vertical hexagon. Draw a vertical square in perspective. Draw a straight line through the intersection of the diagonals parallel to its horizontal sides. Divide the resulting segment 5 - 2 into four equal parts and draw vertical lines through points A and B (Fig. 3.68). The top and bottom lines of the hexagon do not line up with the sides of the square. Draw them at some distance (1114 a) from the horizontal sides of the square and parallel to them. Connecting the points 1 and 3 found in this way with point 2, and points 6 and 4 with point 5, we get a hexagon (Fig. 3.69).

The horizontal hexagon is constructed in the same sequence (Fig. 3.70 and 3.71).

This construction method is only appropriate for hexagons with sufficient opening. If the disclosure of the hexagon is insignificant, it is better to use the circumcircle method. You can use the methods you already know to test a hexagon built through a square.

In addition, there is another one - to describe a circle around the resulting hexagon (in your drawing - an ellipse). All vertices of the hexagon must belong to this ellipse.

Having mastered the skills of drawing a hexagon, you will freely move on to drawing a hexagonal prism. Take a close look at the diagram in fig. 3.72, as well as schemes for constructing hexagonal prisms based on the circumscribed circle (Fig. 3.73; 3.74 and 3.75) and on the basis of a square (Fig. 3.76; 3.77 and 3.78). Draw vertical and horizontal hexagons in different ways. In the drawing of a vertical hexagon, the long sides of the side faces will be parallel to each other vertical straight lines, and the base hexagon will be the more open the further it is from the horizon line. In the drawing of a horizontal hexagon, the long sides of the side faces will converge at the vanishing point on the horizon, and the opening of the base hexagon will be the greater the further from the viewer it is. When depicting a hexagon, also make sure that the parallel faces of both bases converge in perspective (Fig. 3.79; 3.80).

Creates a regular hexagon inscribed in a circle. Constructs a regular pentagon along a given side. Move the compass needle to the intersection of the arc you just drawn with the circle. This construction can be done using a square and a compass. A regular hexagon can be built using a rail and a 30X60 ° square. Plot the vertex points of the corners of a regular hexagon.


Construction of an equilateral triangle inscribed in a circle. The vertices of such a triangle can be built using a compass and a square with angles of 30 and 60 °, or just one compass. To build side 2-3, set the raceway to the position shown by dashed lines, and draw a straight line through point 2, which will define the third vertex of the triangle.

Method 1 of 3: Draw a perfect hexagon using a compass

We mark point 1 on the circle and take it as one of the vertices of the pentagon. Let a circle of diameter D be given; you need to inscribe a regular heptagon into it (Fig. 65). We divide the vertical diameter of the circle into seven equal parts. From point 7 with a radius equal to the diameter of the circle D, we describe an arc up to the intersection with the continuation of the horizontal diameter at point F. Point F will be called the pole of the polygon.

It is on the ability to construct the bisectors of angles and the median perpendiculars of segments that the technique for constructing regular polygons is based on.

The first column of this table shows the number of sides of a regular inscribed polygon, and the second - the coefficients. The length of a side of a given polygon is obtained by multiplying the radius of a given circle by a factor corresponding to the number of sides of this polygon.

The topic of this video tutorial is "Constructing Regular Polygons." We will also once again define a regular polygon, depict it graphically, and then once again make sure that the centers of the inscribed and circumscribed circles around such a figure will coincide. You can always inscribe a circle into this polygon, and you can always describe a circle around it. In the course of the previous lessons, we found out that the bisectors of its corners and the median perpendiculars to its sides play a basic role for describing the properties of polygons.

4. Received the required regular triangle ABC. The problem has been solved. 3. Having placed one leg of the compass at an arbitrary point A1 on the circle, using the second leg, mark point A2 on the same circle and connect it to point A1. We get the first side of the hexagon. 3. Using the middle perpendiculars to the sides of the polygon, dropped from the point O, we divide all its sides and all arcs of the circle, enclosed between its adjacent vertices, in half.

Geometric construction is one of the important parts of training. The needle should pierce the drawn line. The more accurately the compass is set, the more accurate the construction will be. Draw another arc that intersects the circle. Consecutively connect all six points of intersection of the arcs with the originally drawn circle. In this case, the hexagon may turn out to be wrong.

To obtain the vertices / - // - /// from points IV, V and VI, draw horizontal lines to the intersection with the circle

We connect the found vertices in series with each other. A heptagon can be constructed by drawing rays from the F pole and through odd divisions of the vertical diameter. The centers of both circles coincide (point O in Fig. 1). The figure also shows the radii of the circumscribed (R) and inscribed (r) circles.

The construction of a hexagon is based on the fact that its side is equal to the radius of the circumscribed circle. In this lesson, we will look at ways to build regular polygons using a compass and a ruler. The second method is based on the fact that if you build a regular hexagon inscribed in a circle, and then connect its vertices through one, you get an equilateral triangle. The given method is suitable for constructing regular polygons with any number of sides.

Hexagonal grids (hexagonal grids) are used in some games, but they are not as simple and common as rectangle grids. I've been collecting resources on hex grids for almost 20 years now, and I've written this guide to some of the most elegant approaches in the simplest code. This article often uses the tutorials of Charles Fu and Clark Verbrugge. I will describe the different ways to create hex meshes, how they relate, and the most common algorithms. Many parts of this article are interactive: choosing a grid type changes the corresponding schematics, code, and texts. (Approx. Lane: this applies only to the original, I advise you to study it. In the translation, all the information of the original is preserved, but without interactivity.).

The code examples in this article are written in pseudocode, so they are easier to read and understand in order to write your own implementation.

Geometry

Hexagons are hex polygons. Regular hexagons have all sides (faces) of the same length. We will only work with regular hexagons. Typically, hex grids use horizontal (pointed top) and vertical (flat top) orientations.


Flat (left) and pointed (right) top hexagons

Hexagons have 6 faces. Each face is common to two hexagons. Hexagons have 6 corner points. Each corner point is shared by three hexagons. You can read more about centers, edges and corner points in my article on mesh parts (squares, hexagons and triangles).

Corners

In a regular hexagon, the interior angles are 120 °. There are six "wedges", each of which is an equilateral triangle with internal angles of 60 °. Corner point i is at a distance of (60 ° * i) + 30 °, size units from center. In the code:

Function hex_corner (center, size, i): var angle_deg = 60 * i + 30 var angle_rad = PI / 180 * angle_deg return Point (center.x + size * cos (angle_rad), center.y + size * sin (angle_rad) )
To fill the hexagon, you need to get the vertices of the polygon from hex_corner (..., 0) to hex_corner (..., 5). To draw the outline of the hexagon, use these vertices and then draw the line again in hex_corner (..., 0).

The difference between the two orientations is that x and y change places, which causes the angles to change: the angles of the flat-top hexagons are 0 °, 60 °, 120 °, 180 °, 240 °, 300 °, and the sharp-top hexagons are 30 °, 90 °, 150 °, 210 °, 270 °, 330 °.


Angles of flat and sharp top hexagons

Size and location

Now we want to position several hexagons together. In a horizontal orientation, the height of the hexagon is height = size * 2. The vertical distance between adjacent hexagons vert = height * 3/4.

The width of the hexagon is width = sqrt (3) / 2 * height. The horizontal distance between adjacent hexagons horiz = width.

Some games use pixel art for hexagons that doesn't exactly match regular hexagons. The angle and position formulas described in this section will not match the dimensions of these hexagons. The rest of the article describing the hex grid algorithms applies even if the hexagons are slightly stretched or compressed.



Coordinate systems

Let's start assembling the hexagons into a grid. In the case of grids of squares, there is only one obvious way to assemble. For hexagons, there are many approaches. I recommend using cubic coordinates as the primary representation. Axis coordinates or offset coordinates should be used to store maps and display coordinates for the user.

Offset coordinates

The most common approach is to offset each subsequent column or row. Columns are designated col or q. Rows are designated row or r. Odd or even columns / rows can be offset, so horizontal and vertical hexagons have two options.


Odd-r horizontal layout


Even-r horizontal arrangement


Odd-q vertical arrangement


Even-q vertical arrangement

Cubic coordinates

Another way to look at grids of hexagons is to see in them three major axes, not two as in grids of squares. They show elegant symmetry.

Take a grid of cubes and cut out the diagonal plane at x + y + z = 0. This is a strange idea, but it will help us simplify the hex grid algorithms. In particular, we will be able to use standard operations from Cartesian coordinates: addition and subtraction of coordinates, multiplication and division by a scalar, and distances.

Notice the three major axes on the grid of cubes and their relationship to the six. diagonal directions of the grid of hexagons. The diagonal axes of the grid correspond to the base direction of the hex grid.


Hexagons


Cuba

Since we already have algorithms for grids of squares and cubes, using cubic coordinates allows us to adapt these algorithms to grids of hexagons. I will use this system for most of the algorithms in the article. To use algorithms with a different coordinate system, I transform the cubic coordinates, run the algorithm, and then transform them back.

Explore how cubic coordinates work for a grid of hexagons. When you select hexagons, the cubic coordinates corresponding to the three axes are highlighted.

  1. Each direction of the grid of cubes corresponds the lines on a grid of hexagons. Try to select a hexagon with z equal to 0, 1, 2, 3 to see the connection. The line is marked in blue. Try the same for x (green) and y (purple).
  2. Each hex grid direction is a combination of two cube grid directions. For example, the north of the hex grid is between + y and -z, so each step north increases y by 1 and decreases z by 1.
Cubic coordinates are a smart choice for the hex grid coordinate system. The condition is x + y + z = 0, so it must be preserved in algorithms. The condition also ensures that there will always be a canonical coordinate for each hexagon.

There are many different coordinate systems for cubes and hexagons. In some of them, the condition differs from x + y + z = 0. I have shown only one of many systems. You can also create cubic coordinates with x-y, y-z, z-x, which will have their own set of interesting properties, but I will not cover them here.

But you might argue that you don't want to store 3 numbers for coordinates, because you don't know how to store the map like this.

Axial coordinates

An axial coordinate system, sometimes called a "trapezoidal" coordinate system, is constructed from two or three coordinates from a cubic coordinate system. Since we have the condition x + y + z = 0, the third coordinate is not needed. Axis coordinates are useful for storing maps and displaying coordinates to the user. As with cubic coordinates, you can use standard Cartesian addition, subtraction, multiplication, and division operations with them.

There are many cubic coordinate systems and many axial ones. I will not cover all combinations in this tutorial. I will select two variables, q (column) and r (row). In the diagrams of this article, q corresponds to x, and r corresponds to z, but this correspondence is arbitrary, because you can rotate and rotate the diagrams, getting different correspondences.

The advantage of this system over displacement grids is that the algorithms are more understandable. The disadvantage of the system is that storing a rectangular map is a bit odd; see the section on saving maps. Some algorithms are even clearer in cubic coordinates, but since we have the condition x + y + z = 0, we can calculate the third implied coordinate and use it in these algorithms. In my projects, I call the axes q, r, s, so the condition looks like q + r + s = 0, and I can calculate s = -q - r when needed.

Axles

Offset coordinates are the first thing most people think of because they are the same as the standard Cartesian coordinates used for square grids. Unfortunately, one of the two axes has to go against the grain, and this complicates things as a result. The cubic and axial systems go along the grain and they have simpler algorithms, but the storage of maps is a little more complicated. There is another system called "alternating" or "double", but we will not consider it here; some find it easier to work with than cubic or axial.


Offset coordinates, cubic and axial

Axis is the direction in which the corresponding coordinate is increased. The perpendicular to the axis is the line on which the coordinate remains constant. The grid diagrams above show perpendicular lines.

Coordinate transformation

It is likely that you will use axial coordinates or offset coordinates in your project, but many algorithms are easier to express in cubic coordinates. Therefore, we need to be able to transform coordinates between systems.

Axial coordinates are closely related to cubic coordinates, so the transformation is simple:

# convert cubic to axial coordinates q = x r = z # convert axial to cubic coordinates x = q z = r y = -x-z
In code, these two functions can be written as follows:

Function cube_to_hex (h): # axial var q = hx var r = hz return Hex (q, r) function hex_to_cube (h): # cubic var x = hq var z = hr var y = -xz return Cube (x, y , z)
The offset coordinates are quite a bit tricky:

Adjacent hexagons

Given one hexagon, what six hexagons is it adjacent to? As you might expect, the answer is easiest in cubic coordinates, fairly straightforward in axial coordinates, and a little more complex in offset coordinates. You may also need to calculate six "diagonal" hexagons.

Cubic coordinates

Moving one space in the coordinates of the hexagons changes one of the three cubic coordinates by +1 and the other by -1 (the sum must remain equal to 0). Three possible coordinates can change by +1, and the remaining two can be changed by -1. This gives us six possible changes. Each corresponds to one of the directions of the hexagon. The simplest and fastest way is to pre-compute the changes and place them in the Cube (dx, dy, dz) table at compile time:

Var directions = [Cube (+1, -1, 0), Cube (+1, 0, -1), Cube (0, +1, -1), Cube (-1, +1, 0), Cube ( -1, 0, +1), Cube (0, -1, +1)] function cube_direction (direction): return directions function cube_neighbor (hex, direction): return cube_add (hex, cube_direction (direction))

Axial coordinates

As before, we start with the cube system. Take the Cube table (dx, dy, dz) and convert it to Hex (dq, dr) table:

Var directions = [Hex (+1, 0), Hex (+1, -1), Hex (0, -1), Hex (-1, 0), Hex (-1, +1), Hex (0, +1)] function hex_direction (direction): return directions function hex_neighbor (hex, direction): var dir = hex_direction (direction) return Hex (hex.q + dir.q, hex.r + dir.r)

Offset coordinates

In axial coordinates, we make changes depending on where we are on the grid. If we are in a column / row offset, then the rule differs from the case of a column / row without offset.

As before, we create a table of numbers to add to col and row. However, this time we will have two arrays, one for the odd columns / rows and the other for the even ones. Look at (1,1) in the gridmap above and notice how col and row change as you move in each of the six directions. Now we repeat the process for (2,2). The tables and code will be different for each of the four types of displacement grids, here is the corresponding code for each type of grid.

Odd-r
var directions = [[Hex (+1, 0), Hex (0, -1), Hex (-1, -1), Hex (-1, 0), Hex (-1, +1), Hex (0 , +1)], [Hex (+1, 0), Hex (+1, -1), Hex (0, -1), Hex (-1, 0), Hex (0, +1), Hex ( +1, +1)]] function offset_neighbor (hex, direction): var parity = hex.row & 1 var dir = directions return Hex (hex.col + dir.col, hex.row + dir.row)


Even-r
var directions = [[Hex (+1, 0), Hex (+1, -1), Hex (0, -1), Hex (-1, 0), Hex (0, +1), Hex (+1 , +1)], [Hex (+1, 0), Hex (0, -1), Hex (-1, -1), Hex (-1, 0), Hex (-1, +1), Hex (0, +1)]] function offset_neighbor (hex, direction): var parity = hex.row & 1 var dir = directions return Hex (hex.col + dir.col, hex.row + dir.row)


Grid for even (EVEN) and odd (ODD) rows

Odd-q
var directions = [[Hex (+1, 0), Hex (+1, -1), Hex (0, -1), Hex (-1, -1), Hex (-1, 0), Hex (0 , +1)], [Hex (+1, +1), Hex (+1, 0), Hex (0, -1), Hex (-1, 0), Hex (-1, +1), Hex (0, +1)]] function offset_neighbor (hex, direction): var parity = hex.col & 1 var dir = directions return Hex (hex.col + dir.col, hex.row + dir.row)


Even-q
var directions = [[Hex (+1, +1), Hex (+1, 0), Hex (0, -1), Hex (-1, 0), Hex (-1, +1), Hex (0 , +1)], [Hex (+1, 0), Hex (+1, -1), Hex (0, -1), Hex (-1, -1), Hex (-1, 0), Hex (0, +1)]] function offset_neighbor (hex, direction): var parity = hex.col & 1 var dir = directions return Hex (hex.col + dir.col, hex.row + dir.row)


Grid for even (EVEN) and odd (ODD) columns

Diagonals

Moving in the "diagonal" space in the coordinates of the hexagons changes one of the three cubic coordinates by ± 2 and the other two by ∓1 (the sum must remain equal to 0).

Var diagonals = [Cube (+2, -1, -1), Cube (+1, +1, -2), Cube (-1, +2, -1), Cube (-2, +1, +1 ), Cube (-1, -1, +2), Cube (+1, -2, +1)] function cube_diagonal_neighbor (hex, direction): return cube_add (hex, diagonals)
As before, we can convert these coordinates to axial ones, discarding one of the three coordinates, or convert to offset coordinates, after calculating the results.


Distances

Cubic coordinates

In a cubic coordinate system, each hexagon is a cube in three dimensions. Adjacent hexagons are 1 space apart in the hex grid, but 2 space apart in the cube grid. This makes calculating distances easy. In a grid of squares, the Manhattan distances are abs (dx) + abs (dy). In a grid of cubes, the Manhattan distances are abs (dx) + abs (dy) + abs (dz). The distance in the grid of hexagons is equal to half of them:

Function cube_distance (a, b): return (abs (a.x - b.x) + abs (a.y - b.y) + abs (a.z - b.z)) / 2
The equivalent of this notation would be expressing that one of the three coordinates should be the sum of the other two, and then getting it as a distance. You can choose the bisection form or the maximum value form below, but they give the same result:

Function cube_distance (a, b): return max (abs (a.x - b.x), abs (a.y - b.y), abs (a.z - b.z))
In the figure, the maximum values ​​are highlighted in color. Notice also that each color represents one of six "diagonal" directions.

GIF


Axial coordinates

In the axial system, the third coordinate is implicitly expressed. Let's convert from axial to cubic to calculate the distance:

Function hex_distance (a, b): var ac = hex_to_cube (a) var bc = hex_to_cube (b) return cube_distance (ac, bc)
If the compiler in your case inline hex_to_cube and cube_distance, then it will generate the following code:

Function hex_distance (a, b): return (abs (a.q - b.q) + abs (a.q + a.r - b.q - b.r) + abs (a.r - b.r)) / 2
There are many different ways to write the distances between hexagons in axial coordinates, but regardless of the way of writing the distance between the hexagons in the axial system is extracted from the Manhattan distance in the cubic system... For example, the described “difference of differences” is obtained by writing a.q + a.r - b.q - b.r as a.q - b.q + a.r - b.r and using the maximum value form instead of the bisection form cube_distance. They are all similar if you see the relationship with cubic coordinates.

Offset coordinates

As with the axial coordinates, we convert the offset coordinates to cubic coordinates and then use the cubic distance.

Function offset_distance (a, b): var ac = offset_to_cube (a) var bc = offset_to_cube (b) return cube_distance (ac, bc)
We'll use the same pattern for many algorithms: convert from hexagons to cubes, run the cubic version of the algorithm, and convert the cubic results to hex coordinates (axial or offset coordinates).

Drawing lines

How do I draw a line from one hexagon to another? I am using linear interpolation to draw lines. The line is sampled uniformly at N + 1 points and it is calculated in which hexagons these samples are located.

GIF


  1. We first calculate N, which will be the hex distance between the endpoints.
  2. Then we uniformly sample N + 1 points between points A and B. Using linear interpolation, determine that for values ​​of i from 0 to N, including them, each point will be A + (B - A) * 1.0 / N * i. In the figure, these control points are shown in blue. The result is floating point coordinates.
  3. Convert each control point (float) back to hexagons (int). The algorithm is called cube_round (see below).
Putting it all together to draw a line from A to B:

Function lerp (a, b, t): // for float return a + (b - a) * t function cube_lerp (a, b, t): // for hexagons return Cube (lerp (ax, bx, t), lerp (ay, by, t), lerp (az, bz, t)) function cube_linedraw (a, b): var N = cube_distance (a, b) var results = for each 0 ≤ i ≤ N: results.append ( cube_round (cube_lerp (a, b, 1.0 / N * i))) return results
Notes:

  • There are times when cube_lerp returns a point exactly on the edge between two hexagons. Then cube_round shifts it one way or the other. Lines look better when moved in the same direction. This can be done by adding an epsilon-hex cube (1e-6, 1e-6, -2e-6) to one or both of the endpoints before starting the loop. This will "nudge" the line in one direction so that it does not hit the edge boundaries.
  • The DDA line algorithm in grids of squares equates N to the maximum distance along each of the axes. We do the same in cubic space, which is analogous to the distance in a grid of hexagons.
  • The cube_lerp function should return a cube with coordinates in float. If you are programming in a statically typed language, you cannot use the Cube type. Instead, you can define the FloatCube type, or inline a function in your line drawing code if you don't want to define another type.
  • You can optimize your code by inline cube_lerp and then calculating B.x-A.x, B.x-A.y and 1.0 / N outside of the loop. Multiplication can be converted to repeated summation. The result will be something like a DDA line algorithm.
  • I use axial or cubic coordinates to draw the lines, but if you want to work with offset coordinates then learn.
  • There are many options for drawing lines. Sometimes overcoating is required. They sent me the code for drawing lines with overcoating in hexagons, but I haven't looked into it yet.

Travel range

Coordinate range

For a given center of a hexagon and a range of N, which hexagons are within N steps of it?

We can do the opposite work from the formula for the distance between the hexagons distance = max (abs (dx), abs (dy), abs (dz)). To find all hexagons within N, we need max (abs (dx), abs (dy), abs (dz)) ≤ N. This means that all three values ​​are needed: abs (dx) ≤ N and abs (dy) ≤ N and abs (dz) ≤ N. By removing the absolute value, we get -N ≤ dx ≤ N and -N ≤ dy ≤ N and -N ≤ dz ≤ N. In code, this will be a nested loop:

Var results = for each -N ≤ dx ≤ N: for each -N ≤ dy ≤ N: for each -N ≤ dz ≤ N: if dx + dy + dz = 0: results.append (cube_add (center, Cube (dx , dy, dz)))
This loop will work, but it will be rather ineffective. Of all the dz values ​​that we iterate over in the loop, only one actually satisfies the cubes condition dx + dy + dz = 0. Instead, we will directly compute the dz value that satisfies the condition:

Var results = for each -N ≤ dx ≤ N: for each max (-N, -dx-N) ≤ dy ≤ min (N, -dx + N): var dz = -dx-dy results.append (cube_add ( center, Cube (dx, dy, dz)))
This cycle runs only along the required coordinates. In the figure, each range is a pair of lines. Each line is an inequality. We take all hexagons that satisfy six inequalities.

GIF


Overlapping ranges

If you need to find hexagons that are in multiple ranges, you can traverse the ranges before generating the list of hexagons.

You can approach this problem in terms of algebra or geometry. Algebraically, each region is expressed as inequality conditions in the form -N ≤ dx ≤ N, and we need to find the intersection of these conditions. Geometrically, each area is a cube in three-dimensional space, and we will intersect two cubes in three-dimensional space to get a rectangular parallelepiped in three-dimensional space. We then project it back onto the x + y + z = 0 plane to get the hexagons. I will solve this problem algebraically.

First, we rewrite the condition -N ≤ dx ≤ N in a more general form x min ≤ x ≤ x max, and take x min = center.x - N and x max = center.x + N. Let's do the same for y and z, resulting in a general view of the code from the previous section:

Var results = for each xmin ≤ x ≤ xmax: for each max (ymin, -x-zmax) ≤ y ≤ min (ymax, -x-zmin): var z = -xy results.append (Cube (x, y, z))
The intersection of the two ranges a ≤ x ≤ b and c ≤ x ≤ d is max (a, c) ≤ x ≤ min (b, d). Since the area of ​​the hexagons is expressed as ranges over x, y, z, we can individually intersect each of the x, y, z ranges and then use a nested loop to generate a list of hexagons at the intersection. For one area of ​​hexagons, we take x min = H.x - N and x max = H.x + N, similarly for y and z. For the intersection of two regions of hexagons, we take x min = max (H1.x - N, H2.x - N) and x max = min (H1.x + N, H2.x + N), similarly for y and z. The same pattern works for the intersection of three or more regions.

GIF


Obstacles

If there are obstacles, it is easiest to fill with a limited distance (Breadth First Search). In the figure below, we are limited to four moves. In code, fringes [k] is an array of all the hexagons that can be reached in k steps. With each pass through the main loop, we expand level k-1 to level k.

Function cube_reachable (start, movement): var visited = set () add start to visited var fringes = fringes.append () for each 1< k ≤ movement: fringes.append() for each cube in fringes: for each 0 ≤ dir < 6: var neighbor = cube_neighbor(cube, dir) if neighbor not in visited, not blocked: add neighbor to visited fringes[k].append(neighbor) return visited

Turns

For a given hexagon vector (the difference between the two hexagons), we may need to rotate it so that it points to another hexagon. It is easy to do with cubic coordinates, if you stick to a rotation of 1/6 of a circle.

Rotating 60 ° to the right shifts each coordinate one position to the right:

[x, y, z] to [-z, -x, -y]
Rotating 60 ° to the left shifts each coordinate one position to the left:

[x, y, z] to [-y, -z, -x]



"Having played" [in the original article] with the scheme, you will notice that each turn by 60 ° changes signs and physically "rotates" the coordinates. After a 120 ° rotation, the signs are the same again. A 180 ° rotation changes signs, but the coordinates are rotated to their original position.

Here is the complete sequence of rotating the P position around the center C position, resulting in a new R position:

  1. Convert positions P and C to cubic coordinates.
  2. Calculate a vector by subtracting the center: P_from_C = P - C = Cube (P.x - C.x, P.y - C.y, P.z - C.z).
  3. Rotate the P_from_C vector as described above and assign the resulting vector R_from_C.
  4. Convert the vector back to position by adding center: R = R_from_C + C = Cube (R_from_C.x + C.x, R_from_C.y + C.y, R_from_C.z + C.z).
  5. Convert the cubic position R back to the desired coordinate system.
There are several stages of transformation, but each of them is quite simple. It is possible to shorten some of these steps by defining the rotation directly in axial coordinates, but hex vectors do not work with offset coordinates, and I don’t know how to shorten the steps for offset coordinates. See also stackexchange discussion of other ways to calculate rotation.

Rings

Simple ring

To find out if a given hexagon belongs to a ring of a given radius, you need to calculate the distance from this hexagon to the center, and find out if it is equal to radius. To get a list of all such hexagons, take radius steps from the center, and then follow the rotated vectors along the path along the ring.

Function cube_ring (center, radius): var results = # this code doesn't work for radius == 0; do you understand why? var cube = cube_add (center, cube_scale (cube_direction (4), radius)) for each 0 ≤ i< 6: for each 0 ≤ j < radius: results.append(cube) cube = cube_neighbor(cube, i) return results
In this code, the cube starts at the ring shown by a large arrow from the center to the corner of the diagram. I chose angle 4 to start because it matches the path my direction numbers are moving. You may need a different starting angle. At each step of the inner loop, the cube moves one hexagon around the ring. After 6 * radius steps, it ends where it started.


Spiral rings

By traversing the rings in a spiral pattern, we can fill in the inner parts of the rings:

Function cube_spiral (center, radius): var results = for each 1 ≤ k ≤ radius: results = results + cube_ring (center, k) return results



The area of ​​the large hexagon is the sum of all the circles plus 1 for the center. Use this formula to calculate the area.

Traversing hexagons in this way can also be used to calculate the range of motion (see above).

Area of ​​visibility

What is visible from a given position with a given distance, and is not obstructed by obstacles? The simplest way to determine this is to draw a line to each hexagon in a given range. If the line doesn't meet the walls, then you see a hexagon. Move the mouse over the hexagons [in the diagram in the original article] to see the drawing of lines to these hexagons and the walls with which the lines meet.

This algorithm can be slow over large areas, but it is easy to implement, so I recommend starting with it.

GIF



There are many different definitions of visibility. Do you want to see the center of another hexagon from the center of the starting one? Do you want to see any part of the other hexagon from the center of the starting one? Maybe any part of another hexagon from any starting point? Are obstructions smaller than a full hexagon? Scope is a trickier and more varied concept than meets the eye. Let's start with the simplest algorithm, but expect that it will definitely calculate the answer correctly in your project. There are even cases where a simple algorithm gives illogical results.

I want to expand this tutorial further. I have

Is there a pencil near you? Take a look at its section - it is a regular hexagon or, as it is also called, a hexagon. The cross-section of a nut, a field of hexagonal chess, some complex carbon molecules (for example, graphite), a snowflake, a honeycomb and other objects also have this shape. A giant regular hexagon was recently discovered Let's take a closer look.

A regular hexagon is a polygon with six equal sides and equal angles. We know from the school course that it has the following properties:

  • The length of its sides corresponds to the radius of the circumscribed circle. Of all, only a regular hexagon has this property.
  • The angles are equal to each other, and the magnitude of each is 120 °.
  • The perimeter of a hexagon can be found by the formula P = 6 * R, if the radius of the circumscribed circle around it is known, or P = 4 * √ (3) * r, if the circle is inscribed in it. R and r are the radii of the circumcircle and the incircle.
  • The area occupied by a regular hexagon is determined as follows: S = (3 * √ (3) * R 2) / 2. If the radius is unknown, instead of it we substitute the length of one of the sides - as you know, it corresponds to the length of the radius of the circumscribed circle.

The regular hexagon has one interesting feature that made it so widespread in nature - it is able to fill any surface of the plane without overlaps and gaps. There is even the so-called Pal's lemma, according to which a regular hexagon with a side equal to 1 / √ (3) is a universal cover, that is, it can cover any set with a diameter of one unit.

Now let's look at building a regular hexagon. There are several ways, the simplest of which involves using a compass, pencil, and ruler. First, we draw an arbitrary circle with a compass, then in an arbitrary place on this circle we make a point. Without changing the solution of the compass, we put the tip at this point, mark the next notch on the circle, continue this way until we get all 6 points. Now all that remains is to connect them together with straight segments, and the desired figure will be obtained.

In practice, there are times when you need to draw a large hexagon. For example, on a two-level plasterboard ceiling, around the mounting point of the central chandelier, you need to install six small lamps on the lower level. It will be very, very difficult to find a compass of this size. What to do in this case? How do you draw a large circle at all? Very simple. You need to take a strong thread of the required length and tie one of its ends opposite the pencil. Now all that remains is to find an assistant who would press the second end of the thread to the ceiling at the desired point. Of course, in this case, minor errors are possible, but they are unlikely to be noticeable to an outsider at all.

Content:

A regular hexagon, also called a perfect hexagon, has six equal sides and six equal corners. You can draw a hexagon with a tape measure and a protractor, a rough hexagon with a round object and a ruler, or an even rougher hexagon with just a pencil and a little intuition. If you want to know how to draw a hexagon in different ways, just read on.

Steps

1 Draw a perfect hexagon using a compass

  1. 1 Draw a circle using a compass. Insert the pencil into the compass. Extend the compass to the desired width for the radius of your circle. The radius can be from a couple to ten centimeters wide. Next, place a compass with a pencil on the paper and draw a circle.
    • Sometimes it is easier to draw the half of the circle first and then the other half.
  2. 2 Move the compass needle to the edge of the circle. Place it on top of the circle. Do not change the angle and position of the compass.
  3. 3 Make a small pencil mark at the edge of the circle. Make it clear, but not too dark, as you will erase it later. Remember to keep the angle you set for the compass.
  4. 4 Move the compass needle to the mark you just made. Place the needle directly on the mark.
  5. 5 Make another pencil mark at the edge of the circle. Thus, you will make a second mark at a certain distance from the first mark. Keep moving in one direction.
  6. 6 Make four more marks in the same way. You should go back to the original mark. If not, then most likely the angle at which you held the compass and made the marks has changed. Perhaps this happened due to the fact that you squeezed it too tightly or, on the contrary, loosened it a little.
  7. 7 Connect the marks with a ruler. The six places where your marks intersect with the edge of the circle are the six vertices of the hexagon. Using a ruler and pencil, draw straight lines connecting adjacent marks.
  8. 8 Erase both the circle, the marks on the edges of the circle, and any other marks you made. Once you've erased all of your construction lines, your perfect hexagon should be ready.

2 Draw a rough hexagon using a round object and a ruler

  1. 1 Draw a pencil around the rim of the glass. This will draw a circle. It is very important to draw with a pencil, as later you will need to erase all the auxiliary lines. You can also circle an inverted glass, jar, or anything else that has a round base.
  2. 2 Draw horizontal lines across the center of your circle. You can use a ruler, a book, anything with a straight edge. If you do have a ruler, you can mark the middle by calculating the vertical length of the circle and dividing it in half.
  3. 3 Draw an "X" over half of the circle, dividing it into six equal sections. Since you have already drawn a line through the middle of the circle, the X must be wider than it is high so that the parts are equal. Imagine you are dividing a pizza into six pieces.
  4. 4 Make triangles out of each section. To do this, use a ruler to draw a straight line under the curved portion of each section, connecting it to the other two lines to form a triangle. Do this with the remaining five sections. Think of it like making a crust around your pizza slices.
  5. 5 Erase all construction lines. Construction lines include your circle, the three lines that divided your circle into sections, and other marks that you made along the way.

3 Draw a rough hexagon with one pencil

  1. 1 Draw a horizontal line. To draw a straight line without a ruler, simply draw the start and end points of your horizontal line. Then place the pencil at the starting point and extend the line towards the end. The length of this line can be as little as a couple of centimeters.
  2. 2 Draw two diagonal lines from the ends of the horizontal one. The diagonal line on the left should be facing outward in the same way as the diagonal line on the right. You can imagine that these lines form an angle of 120 degrees with respect to the horizontal line.
  3. 3 Draw two more horizontal lines emanating from the first horizontal lines drawn inward. This will create a mirror image of the first two diagonal lines. The lower left line should be a reflection of the upper left line and the lower right line should be a reflection of the upper right line. While the top horizontal lines should look outward, the bottom ones should look inward of the base.
  4. 4 Draw another horizontal line connecting the bottom two diagonal lines. This way you will draw the base for your hexagon. Ideally, this line should be parallel to the upper horizontal line. Now you have completed your hexagon.
  • The pencil and compass should be sharp to minimize errors from too wide marks.
  • If, using the compass method, you connect each mark instead of all six, you will get an equilateral triangle.

Warnings

  • The compass is a pretty sharp object, be very careful with it.

Principle of operation

  • Each method will draw a hexagon formed by six equilateral triangles with a radius equal to the length of all sides. The six drawn radii are the same length and all the lines to create the hexagon are also the same length, since the width of the compass did not change. Due to the fact that six triangles are equilateral, the angles between their vertices are 60 degrees.

What do you need

  • Paper
  • Pencil
  • Ruler
  • Pair of compasses
  • Something you can put under the paper to keep the compass needle from slipping.
  • Eraser

Close