Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как найти отрезок перпендикулярный данной прямой? Подскажите пожалуйста алгоритм? 
:(
    Опции темы
GenkaRu
Дата 4.5.2010, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.4.2010

Репутация: нет
Всего: нет



 Для чего мне это нужно:  На чертеже изображена стена дома в виде прямой, определённой двумя точками, она содержит две стороны (могут принадлежать разным комнатам), содержать разную отделку и т.д. Необходимо реализовать подсветку конкретной стороны по наведению курсора, ну и выбор по клику, ну и подсветку при выборе стороны стены в списке объектов, чтобы пользователь видел какую конкретно сторону стенки он будет модифицировать.

  Для варианта подсветки при выборе стороны в списке объетов я пробовал искать отрезок - перпендикуляр через середину стены, чтобы потом через нужную его конечную точку проводить линию "подсветки", но не получилось его ограничить (скажем 3мя пикселами).
 
 Ещё как вариант можно было бы переделать алгоритм определения принадлежности курсора прямой для определения принадлежности курсора заданному корридору в те же 3 пиксела, но тоже не выходит пока.. Этот алгоритм я скопировал отсюда: 
http://forum.sources.ru/index.php?showtopi...mp;view=showall

он такой:

           
Код

 bool online;
            int sqrl12, hlfl12;
            
            int x = pointerPosition.X, x1 = wallPosition.Point1.X,
                x2 = wallPosition.Point2.X, y = pointerPosition.Y,
                y1 = wallPosition.Point1.Y, y2 = wallPosition.Point2.Y;
            
            sqrl12 = (int)(Math.Pow((x2-x1), 2) + Math.Pow((y2-y1),2));
            hlfl12 = (int)Math.Truncate(Math.Sqrt(sqrl12)/2);

             online = (Math.Abs((y1-y2)*(x-x1)+(x2-x1)*(y-y1)) <= hlfl12) &&

            (Math.Abs((2*x-x1-x2)*(x2-x1)+(2*y-y1-y2)*(y2-y1)) <= sqrl12);
            return online;


 Если кто-то знает хорошие решения или наставит на путь истинный в поисках оных буду очень признателен!
PM MAIL   Вверх
GenkaRu
Дата 4.5.2010, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.4.2010

Репутация: нет
Всего: нет



По идее проблему должна решить следующая последовательность действий: 1) Из уравнения прямой, перпендикулярной данной прямой, получить координаты точки их пересечения 2) Проверить лежит ли точка пересечения на вожделенном отрезке 3) Проверить в какой полуплоскости относительно нашего отрезка был сделан клик, и определить с какой стороны рисовать подсветку. Код получился вот такой, вызывается по MouseMove:

Код

public int WallSideHighlighted(Wall wall, Point pointer)
        {
            double x, y; //Координаты точки пересечения перпендикуляра и отрезка (нашей стены)
            double x1 = wall.Position.Point1.X, x2=wall.Position.Point2.X, y1=wall.Position.Point1.Y, y2=wall.Position.Point2.Y, //координаты      точек отрезка
                x3 = pointer.X, y3 = pointer.Y; //Координаты курсора
            double length = 0;
            int distance = 3; // граница коридора
            bool onSegment;     //лежит ли точка пересечения перпендикуляра на отрезке
            if(x1 == x2)  //случай с вертикальным отрезком
            {
                x = x2;
                y = y3;

                length = Math.Abs(x3 - x2);
                onSegment = (Math.Abs(y2 - y1) == (Math.Abs(y3 - y1) + Math.Abs(y2 - y3)));
            }
            else if(y1 == y2)  //с горизонтальным
            {
                x = x3;
                y = y2;

                length = Math.Abs(y3 - y1);
                onSegment = (Math.Abs(x2 - x1) == Math.Abs(x1 - x3) + Math.Abs(x2 - x3));
            }
            else // общий случай с как попало лежащим отрезком
            {
                x = ((x2 - x1)/(y2 - y1)*x3 + y3 - y1 + ((x1*y2) - (x1*y1))/(x2 - x1))/
                    ((y2 - y1)/(x2 - x1) + (x1 - x2)/(y2 - y1));
                y = x*(y2 - y1)/(x2 - x1) - ((x1*y2) - (x1*y1))/(x2 - x1) + y1;         //координаты точки пересечения прямой, на которой лежит отрезок, и опущенного на неё перпендикуляра

                length = (int)Math.Sqrt(Math.Pow((x3 - x), 2)+Math.Pow((y3-y),2));   //расстояние от точки клика до точки пересечения

                onSegment = (int)Math.Sqrt(Math.Pow((x2 - x1), 2) + Math.Pow((y2 - y1), 2)) ==   //лежит ли точка пересечения на отрезке
                            (int)Math.Sqrt(Math.Pow((x1 - x), 2) + Math.Pow((y1 - y), 2)) +
                            (int)Math.Sqrt(Math.Pow((x2 - x), 2) + Math.Pow((y2 - y), 2));
            }
            if(length<=distance && onSegment)
            {
                MessageBox.Show("Huraa", "The pointer is within the corridor");
            }

            return 0;
        }


Проблема в том, что перпендикуляр строится избирательно, для большинства прямых - неверно, уходит куда-то под уклоном к ним за пределы экрана, но к некоторым строится верно. Баловство со знаками приводило к нужным результатам для одних прямых, и к неприемлемым к другим. Особенно, кажется, проблемны прямые близкие к вертикальным или горизонтальным, но таковыми не являющиеся. Буду пока пересчитывать, либо есть ошибка в вычислениях, либо чего-то не учёл..
PM MAIL   Вверх
GenkaRu
Дата 4.5.2010, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.4.2010

Репутация: нет
Всего: нет



Ураа, координаты надо считать вот так, sweet Mary mother of Jesus оно работает, всем спасибо!))

Код

x = ((x1 - x2) * x3 / (y2 - y1) - (y2 - y1) * x1 / (x2 - x1) + y1 - y3 ) /
                    ((x1 - x2) / (y2 - y1) - (y2 - y1) / (x2 - x1));
                
 y = (x1 - x2)*x/(y2 - y1) - (x1 - x2)*x3/(y2 - y1) + y3;

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0587 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.