【发布时间】:2015-06-14 17:49:55
【问题描述】:
我用 JavaScript 编写了一个循环,它将围绕 HTML 画布上的中心六边形渲染同心六边形环。
我从最里面的环开始,在 3 点钟位置画出六角形,然后继续绕一圈,直到所有的六角形都被渲染出来。然后我转到下一个环并重复。
当您以这种方式绘制六边形时(而不是仅使用 x 和 y 偏移平铺它们),任何不能被 60 整除的六边形到中心六边形的距离与可被 60 整除的六边形的距离不同(因为这些六边形包括较大的十六进制的平边,而不是顶点)。
我遇到的问题是这些六边形(不能被 60 度整除的)渲染在稍微偏离的位置。我不确定这是一个浮点数学问题,我的算法问题,我生锈的三角函数的问题,或者只是愚蠢的问题。我赌 4 分中的 3 分。要切入正题,请查看下面代码中的 if (alpha % 60 !== 0) 行。
作为一个信息点,我决定以这种方式绘制网格,因为我需要一种简单的方法将每个十六进制的坐标映射到一个数据结构中,每个十六进制由它的环 # 和该环内的 ID# 标识.如果有更好的方法,我会全力以赴,但是,我仍然想知道为什么我的渲染关闭了。
这是我非常业余的代码,请耐心等待。
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasApp(){
var xOrigin;
var yOrigin;
var scaleFactor = 30;
var theCanvas = document.getElementById("canvas");
var context;
if (canvas.getContext) {
context = theCanvas.getContext("2d");
window.addEventListener('resize', resizeCanvas, false);
window.addEventListener('orientationchange', resizeCanvas, false);
resizeCanvas();
}
drawScreen();
function resizeCanvas() {
var imgData = context.getImageData(0,0, theCanvas.width, theCanvas.height);
theCanvas.width = window.innerWidth;
theCanvas.height = window.innerHeight;
context.putImageData(imgData,0,0);
xOrigin = theCanvas.width / 2;
yOrigin = theCanvas.height / 2;
}
function drawScreen() {
var rings = 3;
var alpha = 0;
var modifier = 1;
context.clearRect(0, 0, theCanvas.width, theCanvas.height);
drawHex(0,0);
for (var i = 1; i<=rings; i++) {
for (var j = 1; j<=i*6; j++) {
if (alpha % 60 !== 0) {
var h = modifier * scaleFactor / Math.cos(dtr(360 / (6 * i)));
drawHex(h * (Math.cos(dtr(alpha))), h * Math.sin(dtr(alpha)));
}
else {
drawHex(2 * scaleFactor * i * Math.cos(dtr(alpha)), 2 * scaleFactor * i * Math.sin(dtr(alpha)));
}
alpha += 360 / (i*6);
}
modifier+=2;
}
}
function drawHex(xOff, yOff) {
context.fillStyle = '#aaaaaa';
context.strokeStyle = 'black';
context.lineWidth = 2;
context.lineCap = 'square';
context.beginPath();
context.moveTo(xOrigin+xOff-scaleFactor,yOrigin+yOff-Math.tan(dtr(30))*scaleFactor);
context.lineTo(xOrigin+xOff,yOrigin+yOff-scaleFactor/Math.cos(dtr(30)));
context.lineTo(xOrigin+xOff+scaleFactor,yOrigin+yOff-Math.tan(dtr(30))*scaleFactor);
context.lineTo(xOrigin+xOff+scaleFactor,yOrigin+yOff+Math.tan(dtr(30))*scaleFactor);
context.lineTo(xOrigin+xOff,yOrigin+yOff+scaleFactor/Math.cos(dtr(30)));
context.lineTo(xOrigin+xOff-scaleFactor,yOrigin+yOff+Math.tan(dtr(30))*scaleFactor);
context.closePath();
context.stroke();
}
function dtr(ang) {
return ang * Math.PI / 180;
}
function rtd(ang) {
return ang * 180 / Math.PI;
}
}
</script>
【问题讨论】:
-
这是hexagonal grids上的一个很好的资源
-
我要指出我已经阅读了该资源,但它并没有解决我的具体问题。我在编写算法后阅读了这篇文章,它确实提供了一些关于我可以解决这个问题的另一种方法的见解。我很固执,我想弄清楚为什么我的计算会有轻微的扰动。谢谢!
标签: javascript html5-canvas trigonometry 2d-games