Линейная алгебра является ответом.Здесь есть две системы координат: экранные координаты и изометрические координаты.Преобразование углов выбранной области из экранных координат в изометрические координаты очень поможет вам.
Пусть тета - это угол между осями x и y изометрических координат, измеренный на экране, а единица измерения - длина пикселя.одного шага в изометрических координатах.Тогда
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);
}
}
}