六边形路径上的点坐标
Coordinates of dot on an hexagon path
在一个项目中,我想在正六边形路径周围均匀分布点。
因此,我想计算我的点从六角形中心的坐标和边的长度。
例如,如果我想围绕一个圆做同样的事情,我会做(在 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
我的直觉不会太难实现,但我在数学上苦苦挣扎...
谢谢:)
我们在单位圆(半径 = 1)上执行此操作时的一些观察结果:
六个六角边之一的大小为1
六边形的六个点坐标为:
( 1, 0 )
( 0.5, √3/2)
(-0.5, √3/2)
(-1, 0 )
(-0.5, -√3/2)
( 0.5, -√3/2)
六边形外接球的总大小为6
两个连续点之间的距离(在那个圆周上)是 6 / amountOfDots
一个点到起点(在六边形上)的距离可以知道这个点在哪条六边形边上(距离的整数部分),以及在那条边上有多远edge(距离的小数部分)
使用插值我们可以确定这样一个点的坐标
这是一个交互式 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>
在一个项目中,我想在正六边形路径周围均匀分布点。
因此,我想计算我的点从六角形中心的坐标和边的长度。
例如,如果我想围绕一个圆做同样的事情,我会做(在 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
我的直觉不会太难实现,但我在数学上苦苦挣扎...
谢谢:)
我们在单位圆(半径 = 1)上执行此操作时的一些观察结果:
六个六角边之一的大小为1
六边形的六个点坐标为:
( 1, 0 ) ( 0.5, √3/2) (-0.5, √3/2) (-1, 0 ) (-0.5, -√3/2) ( 0.5, -√3/2)
六边形外接球的总大小为6
两个连续点之间的距离(在那个圆周上)是 6 / amountOfDots
一个点到起点(在六边形上)的距离可以知道这个点在哪条六边形边上(距离的整数部分),以及在那条边上有多远edge(距离的小数部分)
使用插值我们可以确定这样一个点的坐标
这是一个交互式 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>