Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 06:23
Оценка:
Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360). Требуется определить, пересечет ли он третий луч, угол которого также задан.

Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?
Re: Попадание луча между двумя другими лучами
От: Dorofey Россия  
Дата: 19.12.13 06:28
Оценка:
Здравствуйте, 777777w, Вы писали:

7>Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360). Требуется определить, пересечет ли он третий луч, угол которого также задан.


Третий? А где второй?

7>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?


Бррр, какие кучу if-ов? Ты хочешь написать 360 if-ов? Вау, индиан стайл солюшн
Re[2]: Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 06:38
Оценка:
Здравствуйте, Dorofey, Вы писали:

7>>Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360). Требуется определить, пересечет ли он третий луч, угол которого также задан.


D>Третий? А где второй?


Второй это положение первого после поворота.

7>>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?


D>Бррр, какие кучу if-ов? Ты хочешь написать 360 if-ов? Вау, индиан стайл солюшн


Чтобы было понятно — конкретный пример. Первый луч +10 градусов, поворачивается на -340 градусов. Пересечет ли он луч -20 градусов? +170? +20? Напиши выражение возвращающее bool.
Re: Попадание луча между двумя другими лучами
От: Cyberax Марс  
Дата: 19.12.13 06:41
Оценка:
Здравствуйте, 777777w, Вы писали:

7>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?

Строим уравнения прямых, на которых лежат лучи. Ищем точку пересечения и проверяем, что она лежит в границах луча.

Если луч 1 повёрнут на угол alpha радиан, то уравнение его прямой будет:
-x*sin(alpha) + y*cos(alpha) = 0

Уравнение второго луча считается как обычно.
Sapienti sat!
Re[2]: Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 06:45
Оценка:
Здравствуйте, Cyberax, Вы писали:

7>>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?

C>Строим уравнения прямых, на которых лежат лучи. Ищем точку пересечения и проверяем, что она лежит в границах луча.

Точка пересечения лучей всегда будет в начале координат независимо от углов.
Re[3]: Попадание луча между двумя другими лучами
От: Dorofey Россия  
Дата: 19.12.13 07:01
Оценка:
Здравствуйте, 777777w, Вы писали:

7>Чтобы было понятно — конкретный пример. Первый луч +10 градусов, поворачивается на -340 градусов. Пересечет ли он луч -20 градусов? +170? +20? Напиши выражение возвращающее bool.


if (testAngle > startAngle &&
testAngle < (startAngle+rotateAngle))

не?
Re[3]: Попадание луча между двумя другими лучами
От: Cyberax Марс  
Дата: 19.12.13 07:09
Оценка:
Здравствуйте, 777777w, Вы писали:

7>>>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?

C>>Строим уравнения прямых, на которых лежат лучи. Ищем точку пересечения и проверяем, что она лежит в границах луча.
7>Точка пересечения лучей всегда будет в начале координат независимо от углов.
Можно детально задачу с рисунком?
Sapienti sat!
Re[4]: Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 07:29
Оценка:
Здравствуйте, Dorofey, Вы писали:

D>Здравствуйте, 777777w, Вы писали:


7>>Чтобы было понятно — конкретный пример. Первый луч +10 градусов, поворачивается на -340 градусов. Пересечет ли он луч -20 градусов? +170? +20? Напиши выражение возвращающее bool.


D>if (testAngle > startAngle &&

D> testAngle < (startAngle+rotateAngle))

D>не?


Не. Вышеприведенный пример не прокатывает если testAngle = -170

В том-то и проблема, что это углы, а не расстояния. С углами всегда проблемы.
Re[4]: Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 07:38
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Можно детально задачу с рисунком?




Известен угол луча 1 и угол, на который он поворачивается рисуя дугу. (В данном случае — примерно 10 градусов и поворот на -340 градусов.)

Требуется узнать, попадают ли в эту дугу лучи 2 и 3, углы которых также известны.
Re: Попадание луча между двумя другими лучами
От: MBo  
Дата: 19.12.13 07:48
Оценка: 1 (1)
Здравствуйте, 777777w, Вы писали:

7>Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360). Требуется определить, пересечет ли он третий луч, угол которого также задан.


7>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?


Луч заметает некий интервал углов на окружности. Приводим этот интервал к полностью неотрицательному, добавляя при необходимости 2Pi или 4Pi так, чтобы левая точка интервала (неважно, начало это, или конец) стала неотрицательной, и лежала в диапазоне [0, 2Pi). Потом третью точку тоже делаем неотрицательной, и проверяем, что или она (X) или (X+2Pi) лежит внутри интервала
Re[2]: Попадание луча между двумя другими лучами
От: Stanislav V. Zudin Россия  
Дата: 19.12.13 08:08
Оценка:
Здравствуйте, MBo, Вы писали:

MBo>Луч заметает некий интервал углов на окружности. Приводим этот интервал к полностью неотрицательному, добавляя при необходимости 2Pi или 4Pi так, чтобы левая точка интервала (неважно, начало это, или конец) стала неотрицательной, и лежала в диапазоне [0, 2Pi). Потом третью точку тоже делаем неотрицательной, и проверяем, что или она (X) или (X+2Pi) лежит внутри интервала


Добавлю, стоит еще разворачивать дугу, чтобы направление всегда было CW или CCW (смотря что выбрано за положительное направление).
Тогда пасьянс сходится.
_____________________
С уважением,
Stanislav V. Zudin
Re[3]: Попадание луча между двумя другими лучами
От: MBo  
Дата: 19.12.13 08:13
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Добавлю, стоит еще разворачивать дугу, чтобы направление всегда было CW или CCW (смотря что выбрано за положительное направление).


Собственно, интервал (отрезок) ненаправленный, поэтому ориентация уже волновать не будет.
Re[4]: Попадание луча между двумя другими лучами
От: Stanislav V. Zudin Россия  
Дата: 19.12.13 08:35
Оценка:
Здравствуйте, MBo, Вы писали:

MBo>Здравствуйте, Stanislav V. Zudin, Вы писали:


SVZ>>Добавлю, стоит еще разворачивать дугу, чтобы направление всегда было CW или CCW (смотря что выбрано за положительное направление).


MBo>Собственно, интервал (отрезок) ненаправленный, поэтому ориентация уже волновать не будет.


Нашел контрпример, когда алгоритм не сработает.

Поискал у себя в закромах.
В общем достаточно посчитать векторное произведение векторов SD и SE.
D — точка пересечения луча и окружности,
S — начало дуги, E — конец дуги.



Знак произведения показывает, попадает луч в дугу или нет.
В этом случае направление дуги не важно.
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: Попадание луча между двумя другими лучами
От: 777777w Россия  
Дата: 19.12.13 10:38
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

SVZ>Нашел контрпример, когда алгоритм не сработает.


А я пока не нашел...

SVZ>Поискал у себя в закромах.

SVZ>В общем достаточно посчитать векторное произведение векторов SD и SE.
SVZ>
SVZ>Знак произведения показывает, попадает луч в дугу или нет.
SVZ>В этом случае направление дуги не важно.

То есть как не важно? А если дуга рисуется от S к E против часовой стрелки? Тогда произведение останется прежним, но точка D попадает на дугу!
Re[5]: Попадание луча между двумя другими лучами
От: Кодт Россия  
Дата: 19.12.13 11:08
Оценка: +1
Здравствуйте, 777777w, Вы писали:

7>


Одна картинка стоит тысячи слов.

Задача выглядит так: попадает ли угловая координата НаправлениеЛуча2 в интервал [НачалоЛуча1, НачалоЛуча1 + ПоворотЛуча1].

Поскольку у нас есть зацикливание, то
— либо придётся распознать, что интервал вышел за область значений [-180,+180] — и тогда рассмотреть уже два интервала [-180,конец] и [начало,+180]
— либо размножить проверяемую точку — и проверить вхождение луч2, луч2-360, луч2+360 в интервал [начало,конец]
— либо размножить интервал — и проверить вхождение луч2 в [начало,конец], [начало-360,конец-360], [начало+360,конец+360]
Понятно, что проверять надо не три, а только два варианта — в зависимости от того, куда сместился оригинальный интервал.

Ну а если коротко, то
bool belongs(int a, int b, int c) // a <- [b,b+c]
{
  assert(a >= -180 && a <= 180);
  assert(b >= -180 && b <= 180);
  assert(c >= -360 && c <= 360);

  // быстрые проверки
  if(c == 0) return a==b;
  if(c == -360 || c == 360) return true;

  int x, y; // [b,b+c] = [x,y]
  if(c < 0) { x=b+c; y=b; } else { x=b; y=b+c; } // упорядочиваем границы интервала

  if(a < x) a += 360; // даём шанс - перемещаем точку вправо на полный цикл
  return a>=x && a<=y;
}
Перекуём баги на фичи!
Re: Попадание луча между двумя другими лучами
От: watchmaker  
Дата: 19.12.13 14:06
Оценка: 9 (2)
Здравствуйте, 777777w, Вы писали:

7>Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360).

7>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?

Если тебе важно не писать много условий, то можно обойтись одним:
угол t находится внутри сектора [s; s + a] только если cos(s – t + a/2) ≥ cos(a/2).
Очевидно, все случаи с периодичностью тут уже учтены внутри косинуса. Разумеется двукратное вычисление косинуса и является главным недостатком такого решения.
Re: Попадание луча между двумя другими лучами
От: AleksandrN Россия  
Дата: 19.12.13 14:14
Оценка:
Здравствуйте, 777777w, Вы писали:

7>Дан угол, под которым луч выходит из начала координат (от -180 до 180) и угол на который он поворачивается (от -360 до 360). Требуется определить, пересечет ли он третий луч, угол которого также задан.


7>Есть ли какой-то простой алгоритм? Или нужно писать кучу if-ов учитывая пересечение первым лучом нуля, 180 или -180 градусов?


Вычислить угол между 1-м и 3-м лучём в направлении вращения 1-го луча.
Сравнить вычисленный угол с углом поворота.
Re[3]: Попадание луча между двумя другими лучами
От: Pzz Россия https://github.com/alexpevzner
Дата: 19.12.13 14:35
Оценка:
Здравствуйте, 777777w, Вы писали:

7>Чтобы было понятно — конкретный пример. Первый луч +10 градусов, поворачивается на -340 градусов. Пересечет ли он луч -20 градусов? +170? +20? Напиши выражение возвращающее bool.


Что значит пересечет? Если все лучи исходят из начала координат, казалось бы, все они в начале координат и пересекаются между собой. Поэтому выражение будет состоять из одного слова, true
Re[5]: Попадание луча между двумя другими лучами
От: Pzz Россия https://github.com/alexpevzner
Дата: 19.12.13 14:36
Оценка:
Здравствуйте, 777777w, Вы писали:

7>В том-то и проблема, что это углы, а не расстояния. С углами всегда проблемы.


Приведите их все к диапазону 0...360, если в градусах.
Re[2]: Попадание луча между двумя другими лучами
От: watchmaker  
Дата: 19.12.13 15:09
Оценка:
W>угол t находится внутри сектора [s; s + a] только если cos(s – t + a/2) ≥ cos(a/2).
W>Разумеется двукратное вычисление косинуса и является главным недостатком такого решения.
Впрочем, от косинуса требуется лишь сравнение на больше–меньше, а не точное значение. Так что можно его заменить на похожую функцию, скажем на модуль и остаток от деления:
|180° – (|s – t + a/2| mod 360°)| ≥ 180° – |a/2|
Не то чтобы запись получилась короче, но зато никакой тригонометрии.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.