線形代数が答えです。ここでは、画面座標と等角座標の 2 つの座標系に注目します。選択した領域の角を画面座標から等角座標に変換すると、非常に役立ちます。
画面上で測定されたアイソメトリック座標の x 軸と y 軸の間の角度をシータとし、アイソメトリック座標の 1 ステップのピクセル長を単位とします。それで
var c = Math.cos(theta/2);
var s = Math.sin(theta/2);
var origin = [oX, oY]; //the pixel coordinates of (0, 0)
var unit = 20;
var iso2Screen = function(iso) {
var screenX = origin[0] + unit * (iso[0] * c + iso[1] * c);
var screenY = origin[1] + unit * (iso[0] * -s + iso[1] * s);
return [screenX, screenY];
}
この関係を逆にすると、
var screen2Iso = function(screen) {
var isoX = ((screen[0] - origin[0]) / c - (screen[1] - origin[1]) / s) / unit;
var isoY = ((screen[0] - origin[0]) / c + (screen[1] - origin[1]) / s) / unit;
次に、選択ボックスの各コーナーの画面座標を等角座標に変換し、最小と最大の x と y を取得します。
var cornersScreen = ...//4-element array of 2-element arrays
var cornersIso = [];
for(var i = 0; i < 4; i++) {
cornersIso.push(screen2Iso(cornersScreen[i]));
}
var minX, maxX, minY, maxY;
minX = Math.min(cornersIso[0][0], cornersIso[1][0], cornersIso[2][0], cornersIso[3][0]);
maxX = Math.max(cornersIso[0][0], cornersIso[1][0], cornersIso[2][0], cornersIso[3][0]);
minY = Math.min(cornersIso[0][1], cornersIso[1][1], cornersIso[2][1], cornersIso[3][1]);
maxY = Math.max(cornersIso[0][1], cornersIso[1][1], cornersIso[2][1], cornersIso[3][1]);
選択したアイソメトリック ポイントはすべてアイソメトリック ボックス [minX, maxX] x [minY, maxY] 内にありますが、そのボックス内のすべてのポイントが選択範囲内にあるわけではありません。
選択範囲に含まれていないボックス内のポイントを取り除くために、さまざまなことができます。等角座標の x と y の整数値を反復処理し、等角座標を画面座標に変換してから、その画面座標が選択ボックス内にあるかどうかをテストすることをお勧めします。
var sMinX, sMaxX, sMinY, sMaxY;
sMinX = Math.min(cornersScreen[0][0], cornersScreen[1][0], cornersScreen[2][0], cornersScreen[3][0]);
sMaxX = Math.max(cornersScreen[0][0], cornersScreen[1][0], cornersScreen[2][0], cornersScreen[3][0]);
sMinY = Math.min(cornersScreen[0][1], cornersScreen[1][1], cornersScreen[2][1], cornersScreen[3][1]);
sMaxY = Math.max(cornersScreen[0][1], cornersScreen[1][1], cornersScreen[2][1], cornersScreen[3][1]);
var selectedPoints = [];
for(var x = Math.floor(minX); x <= Math.ceil(maxX); x++) {
for(var y = Math.floor(minY); x <= Math.ceil(maxY); y++) {
var iso = [x,y];
var screen = iso2Screen(iso);
if(screen[0] >= sMinX && screen[0] <= sMaxX && screen[1] >= sMinY && screen[1] <= sMaxY) {
selectedPoints.push(iso);
}
}
}