В проекте я хотел бы равномерно распределить точки вокруг правильного шестиугольного пути.
Таким образом, я хотел бы рассчитать координаты моих точек от центра шестиугольника и длины стороны.
Например, если я хочу сделать то же самое по кругу, я бы сделал (в JS):
let center = {x: 0, y: 0}
let radius = 10;
let amountOfDots = 48;
for (let i = 0; i < amountOfDots; i++) {
let x = radius * Math.sin(Math.PI * 2 * i / amountOfDots) + center.x;
let y = radius * Math.cos(Math.PI * 2 * i / amountOfDots) + center.y;
// draw my dot in (x, y) or whatever
}
Другими словами, я хотел бы получить координаты всех этих точек в одном цикле.
В этом примере amountOfDots = 24
У меня есть интуиция, реализовать которую будет несложно, но я борюсь с математикой...
Спасибо :)
Если вы думаете о (x, y) как о векторе и думаете о шестиугольнике как о 6 линиях внутри круга, вы можете выполнить простой расчет пересечения линий и получить точки, дайте мне знать, что вы думаете об этом решении
Всегда ли количество точек кратно 6? Вы хотите, чтобы расстояние между точками было одинаковым или угол к центральной точке?
Это в основном то, что я хотел бы, пересечение линий. Дело в том, что, как вы сказали, есть 6 строк, что означает 6 сценариев. А в сценарии с 6 вариантами я могу просто нарисовать 6 линий и разрезать их на amountOfDots / 6
порции.
В алгоритме, который я ищу, количество точек может быть любым, это значение, которое я хочу легко изменить. В конце концов, я бы хотел, чтобы расстояние между точками было одинаковым, но если у меня есть алгоритм с одинаковым углом, это подойдет :)
Несколько наблюдений, когда мы делаем это на единичном круге (радиус = 1):
Размер одного из шести ребер шестиугольника равен 1
Координаты шести точек шестиугольника:
( 1, 0 )
( 0.5, √3/2)
(-0.5, √3/2)
(-1, 0 )
(-0.5, -√3/2)
( 0.5, -√3/2)
Общий размер окружности шестиугольника равен 6.
Расстояние (на этой окружности) между двумя последовательными точками равно 6/количество точек.
Расстояние от точки до начальной точки (на шестиугольнике) можно использовать, чтобы узнать, на каком ребре шестиугольника лежит эта точка (целая часть расстояния) и как далеко на этом ребре (дробная часть расстояния).
Таким образом, с помощью интерполяции мы можем определить координаты такой точки
Вот интерактивный фрагмент JS для расчета и рисования этих точек:
// Main algorithm:
function hexagonDots(center, radius, amountOfDots) {
// Function to map unit coordinates to the given center & radius
const project = (x, y) => ({
x: center.x + radius * x,
y: center.y + radius * y
});
const y = Math.sqrt(3) / 2; // = sin(60°)
const hexaX = [1, 0.5, -0.5, -1, -0.5, 0.5, 1];
const hexaY = [0, y, y, 0, -y, -y, 0];
return Array.from({length: amountOfDots}, (_, i) => {
let offset = 6 * i / amountOfDots;
const edgenum = Math.floor(offset); // On which edge is this dot?
offset %= 1; // Retain fractional part only: offset on that edge
return project(
// Use interpolation to get coordinates of that point on that edge
hexaX[edgenum] + offset * (hexaX[edgenum + 1] - hexaX[edgenum]),
hexaY[edgenum] + offset * (hexaY[edgenum + 1] - hexaY[edgenum])
);
});
}
// I/O management:
function drawHexagon(ctx, dots) {
// Draw
ctx.resetTransform();
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.translate(200, 80);
for (const {x, y} of dots) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x+1, y);
ctx.stroke();
}
}
const ctx = document.querySelector("canvas").getContext("2d");
function refresh() {
const center = {x: 0, y: 0};
const radius = 70;
const amountOfDots = +this.value;
const dots = hexagonDots(center, radius, amountOfDots);
drawHexagon(ctx, dots);
}
const input = document.querySelector("input");
input.addEventListener("input", refresh);
refresh.call(input);
Dots: <input type="number" value="48" size="4"><br>
<canvas></canvas>
О боже спасибо!! Я знал, что речь идет об интерполяции и прочем, но не мог это смоделировать!
Можете ли вы добавить рисунок, чтобы ваш вопрос стал более ясным?