Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];

Вниз

Стратегический вопрос   Найти похожие ветки 

 
Мыш   (2003-11-16 22:42) [0]

Сделал компонент (блок-схема), единственное чего очень не хватает - события на перемещение указателя через связь-стрелку. Подскажите люди добрые, как это сделать лучше, ведь единственное, что приходит в голову - на каждое движение мыши по родителю перебирать весь массив ссылок и высчитывать принадлежность точки к каждой прямой. А если объектов - 100, а у каждого по 10-20 связей? Наверняка получится, что при движении мыши по компоненту будет чудовищная загрузка процессора.
Родитель:Tscrollbox, объекты - компоненты-дети его, связи - массивы TList , рисуются прямо по канве скроллбокса вручную

Может быть я принципиально неправильно подешел к созданию подобного компонента?


 
Иван Шихалев   (2003-11-16 22:51) [1]

Предлагаю игнорировать все точки стрелок, кроме крайних и центральных. Т.е. проверять не на принадлежность прямой, а на попадание в окрестности трех (для каждой стрелки) конкретных точек, чьи координаты хранить, а не вычислять. Если нужны сложноизогнутые стрелки, то ввести понятие узловой точки - которых для прямой может быть и более трех, но все-таки конечное число.


 
ti2001   (2003-11-16 23:02) [2]

Есть ли необходимость проверять наличие связи под мышкой постоянно? Если это нужно для перемещения связи, то можно только в момент нажатия кнопки мыши. По крайней мере, не будет постоянного пересчета.


 
мыш   (2003-11-16 23:06) [3]

Так не пойдет, если я правильно понял, то окрестности - это некий порог максимальной длины от заданной точки. Тогда если имеем много пересечений линий, то окрестности неминуемо будут пересекатся, значит придется увеличивать количество точек для уменьшения окрестностей, причем для оптимизации задавать не пропорционалные деления отрезков, а варьируемые, в зависимости от текущего числа пересечений, изменять все эти данные при каждом перемещении блока, что в итоге приведет к слишком большому их числу и неоправданно усложнит код.


 
мыш   (2003-11-16 23:08) [4]

2ti2000 - есть, связь должна интерактивно показать возможность манипулирования с ней (моргуть, подмигнуть :) етц.) Как в Access.


 
Иван Шихалев   (2003-11-16 23:14) [5]

А что окрестности линий пересекаются реже, чем окрестности точек? Введи понятие уровня линии, где выделенная (активная) выше всех, т.е. - приоритетна по пересечениям окрестностей. Для выделения можно кликать по конечным точкам, окрестности которых сделать непересекающимися... Хотя... Фигня все это - расчет принадлежности к прямой много времени не займет, а для кривых без точек привязки все равно не обойтись, да и тоже не должно уж слишком-то сильно тормозить, если формулы расчета достаточно просты.


 
Ломброзо   (2003-11-16 23:39) [6]

Я делал вот что: создавал некий класс-контейнер TLayout, по мере создания каждого элемента блок-схемы добавлял указатель на этот объект в этот контейнер. Все классы-элементы блок-схемы наследовались от TGraphicObject, у которого был виртуальный метод OnMouseMove(X, Y). При движении мыши над контролом перемещение курсора диспетчеризовалось в этот самый TLayout, а он его диспетчеризовал всем элементам блок-схемы в списке, вызывая у них виртуальный OnMouseMove, а те уже полиморфно реагировали на него, сперва проверяя, находится ли точка X, Y в пределах моих границ и реагируя соответственно - элемент-заметка подсвечивался, элемент-точка устанавливал курсор перемещения и т.п.

А насчет принадлежности точки ко множеству -

или введи понятие z-index

или введи указатель на активный элемент - например, тот, на котором щелкнули последним. В этом случае на линии сперва надо будет щелкнуть, чтобы она начала реагировать на перемещение курсора над ней.


 
мыш   (2003-11-16 23:47) [7]

Так для того, чтобы ее выделить, как раз и нужно определять принадлежность точки клика к ней. :)
>А что окрестности линий пересекаются реже, чем окрестности точек? Так если речь идет о точном определении принадлежности точки, то нет необходимости вводить окрестности линий. А пересечение 2 линий будет только в 1 точке. Тогда как если ввести окрестности, то нужно расширить радиусы окрестностей так, чтобы они соприкасались, иначе не каждый клик по линии вызовет реакцию. Расширенные же до соприкосновения хотя бы 3 окрестности (центр и края) дадут в плане этакого снеговика, куда ни кликни-все попал. Только неизвестно, в какую линию, если есть пересечения.

Кстати, дело не в том, что я ресурсы экономлю, я же для себя делаю. Просто часто при использовании того или иного метода берут сомнения - а насколько это не через ж...


 
Ломброзо   (2003-11-16 23:58) [8]

Вот смотри: пересекаются две прямые, и тебе нужно разрешить неоднозначность. Так пускай активным становится тот, кто находится последним в коллекции. Впрочем, сможешь ли ты это реализовать, зависит от того, как ты спроектировал классы. У меня экземпляр класса TGraphicObject имел проперти Active, который автоматически снимал флаг активности с остальных объектов лэйаута.


 
мыш   (2003-11-17 00:00) [9]

Дай посмотреть?


 
Ломброзо   (2003-11-17 00:30) [10]

Во-первых, там кода много и на Builder, во-вторых... лень
выгребать ))

class TCMSLayout
{
private:
TGraphicControl *FControl;
TGraphicObjectsContainer FObjects;
public:
TCMSLayout(TGraphicControl *pControl)
{
FControl = pControl;
Canvas()->Brush->Color = clWhite;
}
TGraphicObjectsContainer *Objects() { return &FObjects; }
TCanvas * Canvas() { return (static_cast<TCMSGraphicControl *>(FControl))->Canvas; }
};

class TCMSGraphicObject
{
private:
bool FActive;
virtual void __fastcall SetActive(const bool Value);
public:
TCMSLayout *FLayout;
public:
virtual bool __fastcall PointInBounds(POINT &pt) = 0;
virtual void __fastcall MouseMove(long X, long Y, TShiftState Shift) = 0;
virtual void __fastcall MouseDown(long X, long Y, TShiftState Shift) = 0;
virtual void __fastcall MouseUp (long X, long Y, TShiftState Shift) = 0;
virtual void __fastcall QueryCursor(int X, int Y, TShiftState Shift) = 0;
virtual void __fastcall Paint() = 0;
__property bool Active = {read=FActive, write=SetActive};
};

typedef std::list< TCMSPoint > TCMSPointList;
class TCMSBrokenLine: public TCMSGraphicObject ...

и т.п.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2003.11.27;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.008 c
3-89769
Chaked
2003-11-07 11:53
2003.11.27
Как убрать пробелы


1-89868
BlackSun
2003-11-16 01:41
2003.11.27
Создание обработчика у невизуального компонента


14-90083
ZeroDivide
2003-11-03 08:48
2003.11.27
---|Ветка была без названия|---


1-89921
radiosoft
2003-11-18 09:59
2003.11.27
Как убрать прокрутку в MDI окне?


7-90154
Kremen
2003-09-17 15:04
2003.11.27
Подключение к устройству





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский