Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.07.2013, 15:24   #1
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию Проверка на пересечение отрезков. Оптимизация

Добрый вечер. В моей программе одним из проблемных мест является проверка пересечения отрезков. В Интернете есть описание алгоритмов http://e-maxx.ru/algo/segments_intersection_checking . я использую первый. Только работать приходится с float. Переделал, получилось вот что:
Код:
#include <stdio.h>
#include <iostream>

using namespace std;

struct Point
{
   float x,y;
};

bool InOneLine(float a,float b, float c, float d)
{
     if (a>b) swap(a,b);           // Находятся ли наши отрезки на одной прямой 
     if (c>d) swap(c,d);
     return max(a,c)<=min(b,d);
}


float area(Point a, Point b, Point c)
{
     return ((a.x-c.x)*(b.y-c.y))-((b.x-c.x)*(a.y-c.y)); // поиск знаковой площади
}


bool Cross(Point a,Point b, Point c, Point d)
{
     if (InOneLine(a.x,b.x,c.x,d.x)&&InOneLine(a.y,b.y,c.y,d.y))
     {
         float a1 = area(a,b,c);  // находим площади
         float a2 = area(a,b,d);
         float a3 = area(c,d,a);
         float a4 = area(c,d,b);

         if(  (((int)a1|0x80000000)^((int)a2|0x80000000)==0)&& // Сравниваем float'ы
              (((int)a3|0x80000000)^((int)a4|0x80000000)==0)) 
               return true;     
         else
               return false;

     }
     else
     {
         return false;
     }
}

int main(int argc, char * argv[])
{
    Point a,b,c,d;
    a.x=-5;
    a.y=1;

    b.x=1;
    b.y=5;

    c.x=0;
    c.y=0;

    d.x=3;
    d.y=-6;




    if (Cross(a,b,c,d))
    {
       cout<<"Отрезки пересекаются";
    }
    else 
       cout<<"Отрезки не пересекаются";

    
    return 0;
}
Будет ли он оптимальнее(по скорости) алгоритма по ссылке? Выигрыш в один такт тоже важен(только если ущерб коду не огромен)

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 25.07.2013, 10:59   #2
ultimatet41
Форумчанин
 
Аватар для ultimatet41
 
Регистрация: 08.04.2012
Сообщений: 104
По умолчанию

вот в этом куске кода можно слегка упростить
с:
Код:
bool Cross(Point a,Point b, Point c, Point d)
{
     if (InOneLine(a.x,b.x,c.x,d.x)&&InOneLine(a.y,b.y,c.y,d.y))
     {
         float a1 = area(a,b,c);  // находим площади
         float a2 = area(a,b,d);
         float a3 = area(c,d,a);
         float a4 = area(c,d,b);

         if(  (((int)a1|0x80000000)^((int)a2|0x80000000)==0)&& // Сравниваем float'ы
              (((int)a3|0x80000000)^((int)a4|0x80000000)==0)) 
               return true;     
         else
               return false;

     }
     else
     {
         return false;
     }
}
на:
Код:
bool Cross(Point a, Point b, Point c, Point d)
{
     if (InOneLine(a.x, b.x, c.x, d.x) && InOneLine(a.y, b.y, c.y, d.y))
     {
         float a1 = area(a,b,c);  // находим площади
         float a2 = area(a,b,d);
         float a3 = area(c,d,a);
         float a4 = area(c,d,b);

         if(  (( (int) a1 | 0x80000000) ^ ( (int) a2 | 0x80000000 ) == 0) && // Сравниваем float'ы
              (( (int) a3 | 0x80000000) ^ ( (int) a4 | 0x80000000) == 0)) 
               return true;     
       }
     
     return false;
     
}
ultimatet41 вне форума Ответить с цитированием
Старый 25.07.2013, 12:25   #3
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Спасибо.
Насколько это извращение:
Код:
 if(  (( (int) a1 | 0x80000000) ^ ( (int) a2 | 0x80000000 ) == 0) && // Сравниваем float'ы
              (( (int) a3 | 0x80000000) ^ ( (int) a4 | 0x80000000) == 0))
будет быстрее простого
Код:
if ((a1*a2<=0)&&(a3*a4<=0)
?

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог

Последний раз редактировалось _PROGRAMM_; 25.07.2013 в 12:37.
_PROGRAMM_ вне форума Ответить с цитированием
Старый 25.07.2013, 13:43   #4
Fenex
Форумчанин
 
Аватар для Fenex
 
Регистрация: 15.02.2012
Сообщений: 821
По умолчанию

Вряд ли кто сможет сказать наверняка. Проще написать два теста. Будет видно чётко и ясно.

Но вообще может случиться и так, что это будет правдой только для вашего компьютера.
^-.-^ My GitHub
Fenex вне форума Ответить с цитированием
Старый 25.07.2013, 14:02   #5
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Цитата:
Но вообще может случиться и так, что это будет правдой только для вашего компьютера.
Разве в моем компьютере числа кодируются по другому?

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 25.07.2013, 14:27   #6
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Разве в моем компьютере числа кодируются по другому?
тут речь шла о скорости вычислений. если один из вариантов будет у вас работать быстрее, то не факт, что на других ПК будет так же...
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 25.07.2013, 15:50   #7
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,601
По умолчанию

Ну ведь в первом случае все равно придется использовать сопроцессор.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 25.07.2013, 16:04   #8
DiemonStar
Старожил
 
Регистрация: 08.02.2012
Сообщений: 2,173
По умолчанию

Цитата:
Сообщение от _PROGRAMM_ Посмотреть сообщение
Ну ведь в первом случае все равно придется использовать сопроцессор.
сопроцессор тоже не панацея. битовая логика + сдвиги с учетом конвейера отработают быстрее.
Правильно поставленная задача - три четверти решения.
DiemonStar вне форума Ответить с цитированием
Старый 26.07.2013, 12:11   #9
Fenex
Форумчанин
 
Аватар для Fenex
 
Регистрация: 15.02.2012
Сообщений: 821
По умолчанию

Существуют вообще, казалось бы, парадоксальные вещи. Две команды на одном и том же процессоре в одном порядке могут выполняться быстрее, чем если их поменять местами. Производители процессоров пишут толстые книги, описывающие все тонкости работы с их детящами и возможности оптимизации.
^-.-^ My GitHub

Последний раз редактировалось Fenex; 26.07.2013 в 12:17. Причина: орф.
Fenex вне форума Ответить с цитированием
Старый 26.07.2013, 12:44   #10
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Код:
bool InOneLine(float a,float b, float c, float d)
{
     if (a>b) swap(a,b);           // Находятся ли наши отрезки на одной прямой 
     if (c>d) swap(c,d);
     return max(a,c)<=min(b,d);
}
Че это? - комментарий левый, что делает функция? - что такое "одна прямая" вообще?

Код:
float area(Point a, Point b, Point c)
{
     return ((a.x-c.x)*(b.y-c.y))-((b.x-c.x)*(a.y-c.y)); // поиск знаковой площади
}
каждый раз когда ты вызываешь эту функцию, создаются 2 новых экземпляра Point. Когда функция завершает работу они уничтожаются - на это уходит время, почему бы не передавать константную ссылку?

Цитата:
Насколько это извращение:
Код:
 if(  (( (int) a1 | 0x80000000) ^ ( (int) a2 | 0x80000000 ) == 0) && // Сравниваем float'ы
              (( (int) a3 | 0x80000000) ^ ( (int) a4 | 0x80000000) == 0))
будет быстрее простого
Код:
if ((a1*a2<=0)&&(a3*a4<=0)
Я не думаю что это одно и тоже, поэтому и сравнивать скорости их выполнения вобще никак нельзя (че сравнивать мопед с чайной чашкой?) И работать этот фрагмент быстро не будет, ИМХО, когда ты выполняешь приведение типов у тебя опять же создается временный объект (в твоем случае типа int)
rrrFer вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Пересечение отрезков времени RISagitov Microsoft Office Excel 4 21.05.2012 18:59
Пересечение отрезков BoozZzilla Помощь студентам 3 06.04.2012 13:51
Пересечение отрезков Helen236 Паскаль, Turbo Pascal, PascalABC.NET 9 06.04.2012 12:08
C++ Пересечение отрезков Liza Dalbek Помощь студентам 2 22.12.2010 23:20
Пересечение отрезков Пaвeл Помощь студентам 1 30.04.2010 05:46