2013-12-17 8 views
1

Я пытаюсь выяснить, находится ли точка (щелчок мыши) в пределах рамки, основанной на верхнем левом x/y и нижнем правом углу x/y. Позиция может быть положительной или отрицательной. Когда вы двигаетесь вверх, значение y увеличивается, при движении вниз, y уменьшается. Когда вы двигаетесь вправо, значение x увеличивается, когда вы двигаетесь влево, x уменьшается.Лучший способ найти, находится ли точка в пределах другого Vector2?

Позиции Vector2 могут быть отрицательными или положительными в зависимости от того, где щелкнули.

Я думал, что это будет просто работать, но это не похоже на отрицательные числа. Какие-либо предложения? Мой мозг жарится сегодня вечером после выполнения векторной арифметики всю ночь на других вещах. Хотелось бы, чтобы я был одним из вас, кто, похоже, понимает это без проблем. ;)

if(point.x >= topLeft.x && point.y <= topLeft.y && 
    point.x <= bottomRight.x && point.y >= bottomRight.y) 
{ 
// is within box 
} 

Редактировать Вот как верхний левый и нижний правый вычисляются. Как оказалось, проблема не в том, что было выше, но я забыл добавить position.y в верхний левый расчет ниже.

Vector2 topLeft = new Vector2(transform.position.x - (transform.localScale.x/2), 
         transform.position.y + (transform.localScale.y/2)); 

Vector2 bottomRight = new Vector2(transform.position.x + (transform.localScale.x/2), 
          transform.position.y - (transform.localScale.y/2)); 

Для всех, кто попадает по этой теме, вышеуказанная проверка верна.

Пример 1:

Bounding Box

Пример 2:

Bounding Box 2

+0

Можете ли вы показать, как назначаются «topLeft» и «bottomRight»? – elnigno

+0

Форме присваивается местоположение, основанное на его центральном положении. Центром прямоугольника являются его мировые координаты. topLeftX рассчитывается, принимая половину размера квадрата и вычитая его из своего положения в мире. topleftY рассчитывается, принимая свое мировое положение и добавляя половину его высоты. BottomRightX рассчитывается, принимая половину ширины и добавляя к мировому положению X объекта. BottomRightY рассчитывается, принимая мировое положение и вычитая половину высоты. Получение половины высоты и ширины производится только путем получения общей ширины или высоты и деления на два. – Euthyphro

+1

Думаю, я должен принять ваше слово. :) Вы подтвердили, что значения координат - это то, что вы ожидаете от них во время инструкции 'if'? – elnigno

ответ

0

Почему бы не использовать Rectangle, а затем проверить, содержит ли он пункт?

var rectangle = new Rectangle(-100,0,100,-100); 
if(rectangle.Contains(-25,-25)) 
{ 
    // is within box 
} 

Для остальных, кажется, ваш код должен работать. Тогда может возникнуть проблема с присвоением значений point, topLeft и bottomRight.

+0

Мы не используем формы окон с этим приложением. Точно так же мне нужно, чтобы это было эффективно, поскольку оно будет использоваться десятки, если не сотни раз в секунду. – Euthyphro

+1

Я сомневаюсь, что это будет неэффективно, если вы повторно используете объект Rectangle. Но, конечно, если вы не можете использовать фигуры, этот метод не является жизнеспособным :) – elnigno

0

проблема с отрицательными числами, что ваш левый верхний не ваш верхний левый

если вы говорите

topY = max(corner1y, corner2y, corner3y) 
bottomY = min (corner1y, corner2y, corner3y) 

после этого ваш чек снова будет работать.

1

Я думаю, что вы ошибочно перевернули булевское выражение. Легче проверять все случаи, когда клик находится вне поля. семантически, определенная точка находится за пределами прямоугольника, если он:

  • Выше, чем самая высокая точка прямоугольника
  • ниже, чем lowestpoint прямоугольника
  • левее левой стороне прямоугольник
  • больше прав, чем правая сторона прямоугольника

Если один из них, правда, это нестандартно.

if( 
    clickPosition.x < topLeft.x 
     || 
    clickPosition.x > bottomRight.x 
     || 
    clickPosition.y < bottomRight.y 
     || 
    clickPosition.y > topLeft.y 
    ) 
{ 
    //Now you're sure the click was outside the box. 
} 
+0

Это точно такое же количество проверок для проверки внутри (с использованием '&&') или снаружи (с использованием '||'). – Rotem

+0

Да. Уже исправлял это. Хорошо подмечено. – Flater

+0

@ Ротем: да, это такое же количество проверок. Но, вообще говоря, люди лучше понимают оценку, где главная операция - это || в отличие от &&. У меня нет доказательств для этого, это просто то, что я заметил много на работе. – Flater

0

Я считаю, что вы используете неправильные знаки на проверках Y. Если это 50, 100 верхнее-левое и правый нижний является 100, 50, то 80 (у) по-прежнему должны быть между 50 и 100, это не имеет значения, в каком направлении ваш Y движется по отношению к экрану, до тех пор, пока вы также инвертируя ваше определение top left.

if(point.x >= topLeft.x && point.y >= topLeft.y && //flipped sign in the second condition 
    point.x <= bottomRight.x && point.y <= bottomRight.y) //flipped sign in the second condition 
{ 
// is within box 
} 

Если вы не переворачивая ваше определение top left, ваш исходный код является правильным, даже для отрицательных чисел.

+0

В соответствии с вопросом значение Y увеличивается, когда точка перемещается вверх. Но вторым элементом вашего блока if является 'point.y> = topLeft.y'. Если это истинное утверждение, это означает, что щелчок был НЕ в поле. – Flater

+0

@Flater В соответствии с значениями угла, опубликованным OP, это не имеет значения. Все пространство «перевернуто» ... ну, только инвертированное, если вы привыкли к окну координат экрана Windows, но все же все зависит от того, как OP определяет их углы. – Rotem

+0

Да, но нет, если вы назовете свои очки 'topLeft'. Потому что, если ось Y меняет направление, важно проверить, больше ли или больше значение Y-вала.Если ось Y идет вверх, topLeft является наивысшим допустимым значением Y для этой точки. Если ось Y опускается, это минимальное значение Y. – Flater

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