我正在創建一個尋路應用程式,我想將每個 hexgon(H) 連接到其相鄰的六邊形。網格是一個矩形,但填充了六邊形。問題是現在連接這些六邊形的代碼很長而且非常挑剔。我想要實作的一個例子是:

問題是一個六邊形與其鄰居之間的連接(范圍為 2-6,具體取決于它們在網格中的位置)無法正常作業。我現在使用的將六邊形與 6 個鄰居連接的代碼示例是:
currentState.graph().addEdge(i, i 1, 1);
currentState.graph().addEdge(i, i - HexBoard.rows 1, 1);
currentState.graph().addEdge(i, i - HexBoard.rows, 1);
currentState.graph().addEdge(i, i HexBoard.rows 1, 1);
currentState.graph().addEdge(i, i HexBoard.rows , 1);
該圖本質上是網格,addEdge 按順序添加從 src ->dest 和 cost(c) 的連接。有什么演算法或方法可以讓我的代碼不那么笨重嗎?(現在它被 if-else 子句污染了)?啟發我的網站:https ://clementmihailescu.github.io/Pathfinding-Visualizer/#
編輯:問題不在于繪制六邊形(它們已經是 SVG),而在于為它們分配邊緣和連接。
uj5u.com熱心網友回復:
有趣的問題...為了打下堅實的基礎,這里有一個既不冗長也不挑剔的六邊形網格類,它基于線性陣列的簡單資料結構。一些筆記...
- 構造
HexagonGrid函式接受六邊形網格尺寸,即六邊形寬度 (hexWidth) 與六邊形高度 (hexHeight) 的數量。 hexHeight每隔一列交替增加一個六邊形,以獲得更令人愉悅的外觀。因此,奇數的hexWidth書擋六邊形網格在第一列和最后一列中具有相同數量的六邊形。- 該
length屬性表示網格中六邊形的總數。 - 每個六邊形都由從 0 開始的線性索引參考
length。 - 采用 (x,y) 坐標的
hexagonIndex方法回傳基于最近六邊形近似值的線性索引。因此,當靠近六邊形的邊緣時,回傳的索引可能是近鄰。 - 我對類結構并不完全滿意,但足以展示線性索引六邊形網格中涉及的關鍵演算法。
為了幫助可視化線性索引方案,代碼片段以六邊形顯示線性索引值。這種索引方案提供了具有相同長度的并行陣列的機會,該陣列通過索引表示每個特定六邊形的特征。
還舉例說明了通過單擊任何六邊形將滑鼠坐標轉換為六邊形索引的能力,這將重新繪制具有較粗邊框的六邊形。
const canvas = document.getElementById( 'canvas' );
const ctx = canvas.getContext( '2d' );
class HexagonGrid {
constructor( hexWidth, hexHeight, edgeLength ) {
this.hexWidth = hexWidth;
this.hexHeight = hexHeight;
this.edgeLength = edgeLength;
this.cellWidthPair = this.hexHeight * 2 1;
this.length = this.cellWidthPair * ( hexWidth / 2 |0 ) hexHeight * ( hexWidth % 2 );
this.dx = edgeLength * Math.sin( Math.PI / 6 );
this.dy = edgeLength * Math.cos( Math.PI / 6 );
}
centerOfHexagon( i ) {
let xPairNo = i % this.cellWidthPair;
return {
x: this.dx this.edgeLength / 2 ( i / this.cellWidthPair |0 ) * ( this.dx this.edgeLength ) * 2 ( this.hexHeight <= i % this.cellWidthPair ) * ( this.dx this.edgeLength ),
y: xPairNo < this.hexHeight ? ( xPairNo 1 ) * this.dy * 2 : this.dy ( xPairNo - this.hexHeight ) * this.dy * 2
};
}
hexagonIndex( point ) {
let col = ( point.x - this.dx / 2 ) / ( this.dx this.edgeLength ) |0;
let row = ( point.y - ( col % 2 === 0 ) * this.dy ) / ( this.dy * 2 ) |0;
let hexIndex = ( col / 2 |0 ) * this.cellWidthPair ( col % 2 ) * this.hexHeight row;
//console.log( `(${point.x},${point.y}): col=${col} row=${row} hexIndex=${hexIndex}` );
return ( 0 <= hexIndex && hexIndex < this.length ? hexIndex : null );
}
edge( i ) {
let topCheck = i % ( this.hexHeight 0.5 );
return (
i < this.hexHeight
|| ( i 1 ) % ( this.hexHeight 0.5 ) === this.hexHeight
|| i % ( this.hexHeight 0.5 ) === this.hexHeight
|| ( i 1 ) % ( this.hexHeight 0.5 ) === 0
|| i % ( this.hexHeight 0.5 ) === 0
|| this.length - this.hexHeight < i
);
}
drawHexagon( ctx, center, lineWidth ) {
let halfEdge = this.edgeLength / 2;
ctx.lineWidth = lineWidth || 1;
ctx.beginPath();
ctx.moveTo( center.x - halfEdge, center.y - this.dy );
ctx.lineTo( center.x halfEdge, center.y - this.dy );
ctx.lineTo( center.x halfEdge this.dx, center.y );
ctx.lineTo( center.x halfEdge, center.y this.dy );
ctx.lineTo( center.x - halfEdge, center.y this.dy );
ctx.lineTo( center.x - halfEdge - this.dx, center.y );
ctx.lineTo( center.x - halfEdge, center.y - this.dy );
ctx.stroke();
}
drawGrid( ctx, topLeft ) {
ctx.font = '10px Arial';
for ( let i = 0; i < this.length; i ) {
let center = this.centerOfHexagon( i );
this.drawHexagon( ctx, { x: topLeft.x center.x, y: topLeft.y center.y } );
ctx.fillStyle = this.edge( i ) ? 'red' : 'black';
ctx.fillText( i, topLeft.x center.x - 5, topLeft.y center.y 5 );
}
}
}
let myHexGrid = new HexagonGrid( 11, 5, 20 );
let gridLeftTop = { x: 20, y: 20 };
myHexGrid.drawGrid( ctx, gridLeftTop );
canvas.addEventListener( 'mousedown', function( event ) {
let i = myHexGrid.hexagonIndex( { x: event.offsetX - gridLeftTop.x, y: event.offsetY - gridLeftTop.y } );
if ( i !== null ) {
let center = myHexGrid.centerOfHexagon( i );
myHexGrid.drawHexagon( ctx, { x: gridLeftTop.x center.x, y: gridLeftTop.y center.y }, 3 );
}
} );
<canvas id=canvas width=1000 height=1000 />
線性索引的一大好處是它使路徑搜索更容易,因為每個內部六邊形都被相對索引為 -1、-6、-5、 1、 6、 5 的六邊形包圍。例如,將相對索引應用于六邊形 18 會導致周圍六邊形的串列為 17、12、13、19、24、23。
作為獎勵,該edge方法指示六邊形是否在網格邊緣。(在代碼片段中,邊緣單元由紅色文本標識。)強烈建議邊緣單元不要成為路徑的一部分(即它們不可到達),因為這樣可以簡化任何路徑搜索。否則路徑邏輯變得非常復雜,就像現在在邊緣單元格上,指示周圍六邊形的相對索引不再完全適用......
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/464886.html
標籤:javascript 数学 几何学
上一篇:如何檢查范圍內的角度?
