2014-11-20 4 views
0

У меня есть бриллиант, нарисованный на панели, и я пытаюсь вычислить, находится ли положение мыши в пределах его границ. Проблема заключается в попытке алмаза, для создания фигуры необходимы четыре координаты, составляющие четыре строки. diamondРасчет, если положение мыши находится в границах алмазного полигона

Проще всего создать или разместить квадрат в пределах алмаза, но я хочу учитывать оставшиеся треугольные области снаружи. Сначала мне казалось, что я пытаюсь вычислить наклон между двумя точками и выяснить, пересекаются ли линии x и y мыши с линией, добавив наклон в уравнение, но оказалось, что это намного сложнее, когда дело доходит до линий которые составляют TOP-> RIGHT, RIGHT-> BOTTOM и BOTTOM-> LEFT, учитывая, что центр алмаза не равен нулю.

Есть ли более простая реализация, чтобы проверить, находится ли мышь x, y в границах алмаза?

+0

Проверьте эту тему: http://stackoverflow.com/questions/10716378/pixel-coordinates-on-diamond – brlaranjeira

+0

Если ширина и высота алмаз равны, это тривиально. Просто воспользуйтесь отличием от центра бриллиантов и вашей точки. Если нет, попробуйте обработать алмаз как 2 треугольника и вместо этого выполнить тест на треугольник. –

ответ

2

В псевдокоде (более читаемым):

Point org = new Point(64, 32); // Center. 
Point radii = new Point(32, 16); // Half the size. 

Point mousePos = ... 

mousePos -= org; // Relative to the center. 
boolean inside = Math.abs(mousePos.x) * radii.y + Math.abs(mousePos.y) * radii.x 
       <= radii.x * radii.y; 

Из математики известно (0, radii.y) и (radii.x, 0) определяют линию границы в положительном квадранте. Это сводится к приведенной выше формуле.

static boolean isInsideDiamond(int x, int y, int[] xs, int[] ys) { 
    int minX = xs[0]; 
    int maxX = minX; 
    int minY = ys[0]; 
    int maxY = minY; 
    for (int i = 1; i < 4; ++i) { 
     minX = Math.min(minX, xs[i]); 
     maxX = Math.max(maxX, xs[i]); 
     minY = Math.min(minY, ys[i]); 
     maxY = Math.max(maxY, ys[i]); 
    } 

    int orgX = (minX + maxX)/2; 
    int orgY = (minY + maxY)/2; 
    int radX = (maxX - minX)/2; 
    int radY = (maxY - minY)/2; 

    return isInsideDiamond(x, y, orgX, orgY, radX, radY); 
} 

static boolean isInsideDiamond(int x, int y, int orgX, int orgY, int radX, 
     int radY) { 
    x -= orgX; 
    x = Math.abs(x); 
    y -= orgY; 
    y = Math.abs(y); 
    return x * radY + y * radX <= radX * radY; 
} 

Кстати:

Polygon diamond = new Polygon(xs, ys, 4); 
boolean inside = diamond.contains(x, y); 
+0

Мне нравится, как он избегает деления и плавающих точек, а также сходство с тестом «находится в круге». – weston

+0

Я отделил код, который только что нашел центр и размеры алмаза от реального кода вычисления. Надеюсь, вы не против. – weston

+0

Я рад, что вы взяли код. Это всегда приятно. –

 Смежные вопросы

  • Нет связанных вопросов^_^