座標計算クラスソース
// 座標計算クラス
var clsCalcPoints = function()
{
};
// 図形の1辺の直線と中心点と検査点を結ぶ線分が内側にあるかを調べる
clsCalcPoints.prototype.InnerPont = function(px1, py1, px2, py2, cx, cy, gx, gy)
{
var tc = (px1 - px2) * (cy - py1) + (py1 - py2) * (px1 - cx);
var td = (px1 - px2) * (gy - py1) + (py1 - py2) * (px1 - gx);
return ((tc * td) > 0);
}
// クライアント座標をHEX座標に変換
clsCalcPoints.prototype.GetHexPoint = function(gx, gy, gw, gh, cx, cy)
{
// 格子の半分の量
var wHalf = (gw / 2);
var hHalf = (gh / 2);
// 行列開始指標(六角形の高さの半分を1行と、幅の半分を1列とする)
var row = Math.floor(gy / hHalf);
var col = Math.floor(gx / wHalf);
// 探索中心点配列
var ary = null;
// 行偶数フラグ
var RowEven = ((row % 2) == 0);
// 探索中心点設定分岐
if ((col % 3) == 1) {
ary = new Array({ x:col * wHalf + wHalf / 2, y:(row * hHalf + (RowEven ? hHalf : 0)) });
}
else if ((col % 3) == 2) {
ary = (
RowEven
? new Array({ x:col * wHalf - wHalf / 2, y:row * hHalf + hHalf }, { x:col * wHalf + wHalf, y:row * hHalf })
: new Array({ x:col * wHalf - wHalf / 2, y:row * hHalf }, { x:col * wHalf + wHalf, y:row * hHalf + hHalf })
);
}
else {
ary = (
RowEven
? new Array({ x:col * wHalf, y:row * hHalf }, { x:col * wHalf + wHalf * 1.5, y:row * hHalf + hHalf })
: new Array({ x:col * wHalf, y:row * hHalf + hHalf }, { x:col * wHalf + wHalf * 1.5, y:row * hHalf })
);
}
// 探索ループ
if (ary) {
for (var idx = 0; idx < ary.length; idx++) {
// 座標を整数に変換
var px = Math.floor(ary[idx].x);
var py = Math.floor(ary[idx].y);
// 点配列を生成
var hex = this.GetHexPolygon(px, py, gw, gh);
// 包含点なら中心座標を返す
if (this.InnerHex(gx, gy, hex)) {
return new Array(px, py, row, col);
}
}
}
// 探索不可を返す
return null;
}
// 中心点から六角形座標を得る
clsCalcPoints.prototype.GetHexPolygon = function(x, y, gw, gh)
{
// 格子の半分の量
var wHalf = (gw / 2);
var hHalf = (gh / 2);
// 点配列を生成
var hex = new Array(
x + (wHalf / 2), y - hHalf // 右上の点
, x + wHalf, y // 右端の点
, x + (wHalf / 2), y + hHalf // 右下の点
, x - (wHalf / 2), y + hHalf // 左下の点
, x - wHalf, y // 左端の点
, x - (wHalf / 2), y - hHalf // 左上の点
);
// 結果を返す
return hex;
}
// 座標が六角形の内にあるかを判定
clsCalcPoints.prototype.InnerHex = function(gx, gy, hex)
{
// 左端と右端から中心Xを求める
var x = hex[8] + ((hex[2] - hex[8]) / 2);
// 右上と右下中心Yを求める
var y = hex[1] + ((hex[5] - hex[1]) / 2);
// 右上と右端
if (!this.InnerPont(
hex[0], hex[1] // 右上の点
, hex[2], hex[3] // 右端の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 右端と右下
if (!this.InnerPont(
hex[2], hex[3] // 右端の点
, hex[4], hex[5] // 右下の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 右下と左下
if (!this.InnerPont(
hex[4], hex[5] // 右下の点
, hex[6], hex[7] // 左下の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 左下と左端
if (!this.InnerPont(
hex[6], hex[7] // 左下の点
, hex[8], hex[9] // 左端の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 左端と左下
if (!this.InnerPont(
hex[8], hex[9] // 左端の点
, hex[10], hex[11] // 左上の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 左上と右上
if (!this.InnerPont(
hex[10], hex[11] // 左上の点
, hex[0], hex[1] // 右上の点
, x, y, gx, gy // 中心点と検査する点
)) return false;
// 点がHEX内部にある事を返す
return true;
}
// サイズ内の座標に変換
clsCalcPoints.prototype.GetPtMapping = function(p, s)
{
return Math.abs(Math.floor(p < 0 ? (s + p) % s : p % s));
}
clsCalcPoints.prototype.DrawRect = function(id, row, col, gw, gh, cx, cy)
{
var canvas = document.getElementById(id);
var ctx = canvas.getContext('2d');
// 格子の半分の量
var wHalf = (gw / 2);
var hHalf = (gh / 2);
// 消去
ctx.clearRect(0, 0, cx, cy);
// キャンバス属性を退避
ctx.save();
// 描画属性を設定
ctx.lineWidth = 2;
ctx.strokeStyle = "red";
// パスを開始
ctx.beginPath();
// 四角形描画
ctx.rect(col * wHalf, row * hHalf, wHalf, hHalf);
// パスを描く
ctx.stroke();
// キャンバス属性を戻す
ctx.restore();
}