Hexagon
(16진법의 경우 Hexadecimal 항목 참조)
기하학에서 육각형은 변이 여섯 개인 도형이다.
정육각형의 한 각의 크기는 120°이므로 테셀레이션이 가능하다. 정육각형의 내각의 합은 720°이다.
Sample design
Black-hexagon-border-emblems-set-white-background-styled-borders-91979160.png
코드로 정육각형 그리는 방법
하나의 원이 있다고 가정하고, 원을 여섯 개의 호(Arc)로 정확히 나누면 각 내각은 60도 이다.
Hexagon-01.jpg
12시방향의 첫 번째 점은 (0, r)
로 가정한다. 시계 방향으로 점을 찍을 때, 두 번째 점의 좌표는 \((\frac{\sqrt{3}}{2}r, 0.5r)\) 이다.
Hexagon-02.jpg
계산 방식은 다음과 같다:
- 60도 이동한 위치는 xy 평면 상의 위치로 이동시켜서, 삼각 함수 (Trigonometric functions) 계산을 편히 하기 위해
직각(90º) - 60º = 30º
로, 사용할 수 있다. - x축 으로 \(cos(30^{\circ}) = \frac{\sqrt{3}}{2}\)이므로 \(\frac{x}{r} = \frac{\sqrt{3}}{2}\), \(x = \frac{\sqrt{3}}{2}r\)
- y축 으로 \(sin(30^{\circ}) = \frac{1}{2}\) 이므로 \(\frac{y}{r} = \frac{1}{2}\), \(y = \frac{1}{2}r\)
X축과 Y축으로 Flip 하면 전체 꼭지점이 도출된다.
Godot
using Godot;
using System;
using System.Collections.Generic;
[Tool]
public class HexagonTile : Node2D
{
private static float COS30 = (float)Math.Sqrt(3f) / 2f;
private static float SIN30 = 0.5f;
private float _radius = 48f;
[Export]
public float radius {
get => _radius;
set
{
this._radius = value;
this.UpdatePoints();
this.Update();
}
}
private Vector2 _offset = new Vector2(0, 0);
[Export]
private Vector2 offset
{
get => _offset;
set
{
this._offset = value;
this.UpdatePoints();
this.Update();
}
}
private Color _lineColor = new Color(1f, 1f, 1f, 1f);
[Export]
private Color lineColor
{
get => _lineColor;
set
{
this._lineColor = value;
this.Update();
}
}
private Color _fillColor = new Color(0f, 0f, 0f, 0f);
[Export]
private Color fillColor
{
get => _fillColor;
set
{
this._fillColor = value;
this.Update();
}
}
private float _lineWidth = 1f;
[Export]
private float lineWidth
{
get => _lineWidth;
set
{
this._lineWidth = value;
this.UpdatePoints();
this.Update();
}
}
private bool _antialiased = true;
[Export]
private bool antialiased
{
get => _antialiased;
set
{
this._antialiased = value;
this.Update();
}
}
private List<Vector2> _points = new List<Vector2>();
static public List<Vector2> MakeHexagonPoints(Vector2 center, float radius)
{
var r = radius;
var x = COS30 * radius;
var y = SIN30 * radius;
var cx = center.x;
var cy = center.y;
var points = new List<Vector2>();
points.Clear();
points.Add(new Vector2(cx + x, cy));
points.Add(new Vector2(cx + x, cy + y));
points.Add(new Vector2(cx + 0, cy + r));
points.Add(new Vector2(cx - x, cy + y));
points.Add(new Vector2(cx - x, cy - y));
points.Add(new Vector2(cx + 0, cy - r));
points.Add(new Vector2(cx + x, cy - y));
points.Add(new Vector2(cx + x, cy));
return points;
}
public void UpdatePoints()
{
this._points = MakeHexagonPoints(this._offset, this._radius);
}
public override void _Draw()
{
if (this._points.Count == 0) {
this.UpdatePoints();
}
var fillColors = new Color[] { this._fillColor };
DrawPolygon(this._points.ToArray(), fillColors);
if (this._lineWidth > 0) {
DrawPolyline(
this._points.ToArray(),
this._lineColor,
this._lineWidth,
this._antialiased);
}
}
}
DrawPolyline
함수의 꼭지점 연결 부분이 부자연스럽다면 Godot:CanvasItem#draw_polyline 항목의 "Line Connection 이슈" 항목을 참조.
pygame
def draw_ngon(Surface, color, n, radius, position):
pi2 = 2 * 3.14
for i in range(0, n):
pygame.draw.line(Surface, color, position, (cos(i / n * pi2) * radius + position[0], sin(i / n * pi2) * radius + position[1]))
return pygame.draw.lines(Surface,
color,
True,
[(cos(i / n * pi2) * radius + position[0], sin(i / n * pi2) * radius + position[1]) for i in range(0, n)])