C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Рисование на форме, оптимальный путь
Лена
Отправлено: 26.07.2006, 17:24


Мастер участка

Группа: Участник
Сообщений: 501



Мне нужно написать программу, которая бы рисовала линии на форме. Щелкаю на кнопку и перехожу в режим рисования. Далее щелкаю мышью по форме — ставиться тока, щелкаю в другом месте — ставиться другая точка и эти точки соединяются линией. После двойного щелчка рисование произвольной ломанной линии прекращается. Рисовать надо именно на форме, а не Image-e или PainBox-e. При перекрывании формы с линиями другой формой рисунок должен сохраняться, а не затираться.
Вопрос, какой оптимальный путь выбрать для решения этой задачи? Использовать стандартные ф-ции LineTo, и т.д. или есть готовый сторонний компонент для облегчения задачи?
Спасибо.
Shagg
Отправлено: 27.07.2006, 06:27


Дежурный стрелочник

Группа: Участник
Сообщений: 69



wink.gif хммм если задача сводится только к рисованию ломаной на форме,можно пожалуй хранить в массиве координаты точек и каждый раз перерисовывать
Valdemar
Отправлено: 27.07.2006, 08:21


Мастер участка

Группа: Участник
Сообщений: 433



Чтобы форма атоматически перерисовывалась, необходимо написать обработчик события OnPaint.
Лена
Отправлено: 27.07.2006, 10:08


Мастер участка

Группа: Участник
Сообщений: 501



QUOTE (Shagg @ 27/07/2006, 06:27)
wink.gif хммм если задача сводится только к рисованию ломаной на форме,можно пожалуй хранить в массиве координаты точек и каждый раз перерисовывать


А как добавить следующее в программу:
нарисовала несколько многоугольников на форме, потом захотела стереть один из них?
При новом старте программы все нарисованные в прошлом сеансе многоугольники должны отображаться на форме. Как проще это реализовать?


Отредактировано Лена — 27/07/2006, 10:14
Guest
Отправлено: 27.07.2006, 11:34


Не зарегистрирован







1. Так сохраняете у себя все координаты точек и перерисовываете.

2. Сохранять эти точки в файле.
При новом старте — читать файл и рисовать.
Удобно пользоваться или ini-файлом или сохранять в реестре.
Shagg
Отправлено: 27.07.2006, 11:52


Дежурный стрелочник

Группа: Участник
Сообщений: 69



Лучше всего сделать так:
описать класс — фигура (у которого одним из полей будет указатель на массив координат вершин) и его наследников — треугольник, квадрат, многоугольник и т.д.
описать метод Print — вывод на форму
и перегрузить операторы>> и << для записи и чтения из файла
после чего обьявить массив объектов и работать с ними по своему усмотрению
Лена
Отправлено: 27.07.2006, 12:33


Мастер участка

Группа: Участник
Сообщений: 501



Да, придется потрудиться… smile.gif
Подскажите, а нет ли стороннего компонента для рисования, чтобы существенно облегчить задачу, и уменьшит написание кода?

Shagg
Отправлено: 27.07.2006, 14:35


Дежурный стрелочник

Группа: Участник
Сообщений: 69



К сожалению не встречал.
Видел только GLPanel, но это для рисования в OpenGL, а там дебри еще по-хлеще.
Konstantine
Отправлено: 27.07.2006, 16:54


Мастер участка

Группа: Модератор
Сообщений: 545



QUOTE (Shagg @ 27/07/2006, 11:52)
Лучше всего сделать так:
описать класс — фигура .... и его наследников — треугольник, квадрат, многоугольник и т.д....

а зачем?
один класс многоугольник на очереди или динам. массиве.
и помимо свойств рисования, добавления, удаления — сделать булево — замкнут или нет (т.е. есть ли линия с послед. точки в первую). также сохранить и считать — с файла, или (лучше) потока... — т.е. формат сохранения

если с каждой точки могут выходить неск. линий — то делать граф. если надо — я писал его (также с рисованием на форме) — могу принести.

Отредактировано Konstantine — 27/07/2006, 16:57
Лена
Отправлено: 27.07.2006, 17:40


Мастер участка

Группа: Участник
Сообщений: 501



Мне наконец сформулировали окончательно задачу и она существенно усложнилась. На форме, на всей ее поверхности будет таки лежать Image. В Image будет загружен рисунок. На рисунке будут разные объекты (квадраты, многоугольники и пр. (см.рисунок). Пользователь должен иметь возможность задавать области вокруг этих объектов на рисунке во время выполнения приложения. Все заданные им области должны уметь подсвечиваться при наведении мыши. Вот рисунок прилагаю. Пользователь задал область вокруг рисунка динамика и плюс эта область умеет подсвечиваться при наведении мыши.
Пользователь также может отменять ранее сделанные им области подсветки.
Подскажите по шагам реализацию такой программы.


Отредактировано Лена — 27/07/2006, 17:47

Присоединить изображение

Присоединить изображение

Grigoriy
Отправлено: 27.07.2006, 21:04


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE (Лена @ 27/07/2006, 17:40)
Пользователь должен иметь возможность задавать области вокруг этих объектов на рисунке во время выполнения приложения.

Немного недопонимаю, или просто пустяк какой-то.
Если объект задан в виде множества Q пикселов, которое имеет единственную границу в виде подмножества A пикселов, и существует некоторое подмножество B пикселов, для каждого Bn пиксела которого существует пиксел An из A такой, что расстояние
R=Sqrt((Anx-Bnx)^2 + (Any-Bny)^2)
до него минимально из всех расстояний до других пикселов A, причем это расстояние постоянно — R=const
То область, которая является множеством C пикселов, и включает множества A и B так, что граница C состоит из множеств A и B -
определяется однозначно.

Или определение области вокруг объектов задается в виде задания расстояния R ?

В общем, а можно рассказать, если не секрет — какова потребность в этой задаче ? wink.gif
Shagg
Отправлено: 28.07.2006, 06:33


Дежурный стрелочник

Группа: Участник
Сообщений: 69



2Konstantine:
QUOTE
один класс многоугольник на очереди или динам. массиве.

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

2Лена:
мда задача ваша действительно усложнилась, тем более что пользователь может выбрать пересекающиеся области, но все не так глобально и страшно. smile.gif
вам нужно просто зная координаты точки (в вашем случае это координаты курсора мыши) определить в пределах каких многоугольников она находится , высветить эти многоугольники а остальные сделать неактивными.

PS: да еще советую хранить указатель на выделенные фигуры, чтобы потом для их "отключения" не приходилось перебирать все объекты.
AVC
Отправлено: 28.07.2006, 08:41


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

Мне наконец сформулировали окончательно задачу и она существенно усложнилась ...

А ваше руководство не пыталось использовать специализированное по для построения схем / чертежей ... Среди программ есть и хорошие, и бесплатные, но вот одновременно ли? smile.gif

Правда если вам нужно не создавать/редактировать а только подсвечивать...
Думаю не от рисунка надо отталкиваться. Нужно иметь его модель (описание) типа как в Corel. По модели можно и рисунок генерить, и контуры подсвечивать, и находить объекты, попавшие в область выделения.

В простом случае моделью может служить что-то типа map html (замкнутая ломаная контура). Это если объекты не пересекаются.
Лена
Отправлено: 28.07.2006, 10:04


Мастер участка

Группа: Участник
Сообщений: 501



>Немного недопонимаю, или просто пустяк какой-то.

На форме Image в Image загружен рисунок. На рисунке, например изображение квартала домов. Пользователь должен уметь делать некоторые дома (которые ему нужны) интерактивными при наведении мыши. Пользователь каким-то образом должен задать область выделения вокруг понравившегося ему дома на рисунке. При наведении мыши область вокруг дома должна подсвечивается рамкой, а размер и форму рамки вокруг дома на рисунке, определяется пользователем щелчками мыши. Необходимо учесть, что домов может быть очень много.

>В общем, а можно рассказать, если не секрет — какова потребность в этой задаче ?


Получаем интерактивную карту. Областям вокруг объектов в дальнейшем нужно будет задавать всплывающие подсказки и назначать события. Посмотрите на рисунок. Это фрагмент стороннего приложения без исходного кода. Я хочу сделать такое же в своем проекте, но чтобы область выделения можно было задавать не только прямоугольниками, а произвольными щелчками мыши вокруг дома на рисунке (например, ромб, параллелограмм, что угодно…).

>А ваше руководство не пыталось использовать специализированное по для построения схем / чертежей ... Среди программ есть и хорошие, и бесплатные, но вот одновременно ли?

Руководство увидело программу фрагмент, которой приведен на рисунке и хочет иметь такое же. smile.gif Достоверно известно, что это создано в Builder, но там области выделения только квадраты и прямоугольники.

>Думаю не от рисунка надо отталкиваться.

Рисунки дает заказчик. Мы должны отдавать программу, где на формах будут лежать рисунки заказчика и заказчик должен уметь возможность назначать свои области подсветки на своих рисунках.

Если нет простого решения этого вопроса, то может воспользоваться картографическим компонентом MapX, который я не плохо знаю? Хочется все-таки обойтись без него, как говориться малой кровью.
Есть простое решение? Опишите please. smile.gif


Присоединить изображение

Присоединить изображение

avc*
Отправлено: 28.07.2006, 12:09


Не зарегистрирован







QUOTE

Рисунки дает заказчик. Мы должны отдавать программу, где на формах будут лежать рисунки заказчика и заказчик должен уметь возможность назначать свои области подсветки на своих рисунках.

Значит ваша фирма должна посадить человека (или програму-робота), который преобразует рисунки в набор связных объектов.

QUOTE

Если нет простого решения этого вопроса, то может воспользоваться картографическим компонентом MapX

Вам и "карты" в руки как знатоку MapX smile.gif
Лена
Отправлено: 28.07.2006, 13:33


Мастер участка

Группа: Участник
Сообщений: 501



>Вам и "карты" в руки как знатоку MapX

Я не хотела использовать MapX по двум причинам: я не очень представляю как создать инсталляционную программу, которая будет еще и устанавливать ActiveX MapX на компьютер пользователя. MapX имеет свой большой инсталлятор (плюс крек надо проинсталировать). Во вторых мне придется все рисунки преобразовывать в формат MapX в программе MapInfo.
А как же, интересно, реализована программа рисунки, из которой я приводила? Там точно нет MapX. Кнопкой включается режим задания областей на форме. Пользователь задает области (квадраты или прямоугольники). Потом выходит из режима задания областей (просто кнопку отжимает соответствующую). Эти области подсвечиваются и сохраняются между стартами программы. Наверное, в той программе внутри километры кода. smile.gif

Отредактировано Лена — 28/07/2006, 13:34
AVC
Отправлено: 28.07.2006, 13:46


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

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

Т.е. вам нужен редактор прямоугольных рамок? Я правильно понял? А потом этот набор прямоугольничков где то сохряняется с привязкой к файлу, и когда пользователь грузит файл этот набор активизируется. Так?
Это далеко не километры кода.
Guest
Отправлено: 28.07.2006, 14:13


Не зарегистрирован







Рассмотрите вариант работы/преобразования Вашего рисунка
в .png-файл и работы с ним.

Это графический формат, в ктором есть объекты, которые можно
удалять/редактировать/добавлять и пр.
Лена
Отправлено: 28.07.2006, 14:32


Мастер участка

Группа: Участник
Сообщений: 501



>Т.е. вам нужен редактор прямоугольных рамок?

В том то и дело, что руководство хочет, чтобы рамки могли задаваться пользователем любые. Например чтобы пользователь мог задать такой фрагмент (см.рисунок).
Таких разных интерактивных областей пользователь может наделать сколько угодно по всему Image, на его усмотрение. Не пойму с чего начать и в каком направлении правильнее действовать. ohmy.gif

Отредактировано Лена — 28/07/2006, 14:33

Присоединить изображение

Присоединить изображение

avc*
Отправлено: 28.07.2006, 15:17


Не зарегистрирован







QUOTE

Не пойму с чего начать и в каком направлении правильнее действовать

В первом приближении (очень грубо) я вижу так:
класс многоугольник
список узловых точек
+ свойства: описание объекта ...
+ методы: подсветить / убрать подсветку / ...

класс описание какртинки
+ свойства: изображение, текстовое описание изображения, вектор или другой список экземпляров класса многоугольник
+ методы: перемещения многоугольника по рабочему пространству,
изменения z order (нужен будет при перекрытии многоугольников)
активировать многоугольник
сохранения / восстановление экземпляра класса описания на диске

Алгоритм
- Выбрать сохраненный или создать новый экземпляр описания (при новом привязать к неме картинку)
- По умолчанию находимся в режиме подсвети объектов
- По команде пользователя — переход к режиму создания / редактированиия многоугольников
- В редакторе при "новый"
-- выбрать фигуру (прямоугольник, многоугольник ...)
-- мышкой "проклацать" узловые точки
-- сохранить / отменить
-- при сохранить добавить новый элемент в класс описание
- В редакторе при "изменить"
-- переташить на новое место / поправить узловый точки / поменять z order ...
-- сохранить / отменить
- В режиме подсвети объектов
-- по координатам мыша найти верхний из объектов, которому принадлежат эти координаты (самая сложная расчетная часть) и подсветить его или показать другую информацию.
Лена
Отправлено: 28.07.2006, 16:18


Мастер участка

Группа: Участник
Сообщений: 501



Спасибо, так мне понятнее!

P.S. Без километра кода не обойтись smile.gif


Отредактировано Лена — 28/07/2006, 16:36
Doga
Отправлено: 29.07.2006, 03:39


Мастер участка

Группа: Участник
Сообщений: 575



Привет!

Позвольте мне, уважаемые коллеги, предложить свой вариант. Ну, может не совсем свой, а скорее сосем не свой cool.gif . Не знаю, насколько он будет удобен для пользователя, приемлем для заказчика, прост для разработчика. Как говорится — наше дело предложить… smile.gif

Буду рад, если тот самый километр удастся сократить хотя бы на метр cool.gif

1. Способ выделения объектов с помощью серии кликов мыши мне кажется крайне неудобным для пользователя. Представьте, если для выделения объекта потребуется 20-30 щелчков, а то и больше. А если таких объектов несколько (или вообще много)? А как быть, если картинка очень большая, с множеством мелких, при текущем масштабе, объектов? Надо быть снайпером, что бы попасть в необходимую точку мышью, не задев при этом какой либо из соседних объектов! Максимум через полчаса работы пользователь поймёт, что с такой программой работать нельзя.

Способ выделения объектов должен быть максимально простым и удобным, например, тот же самый стандартный растягиваемый прямоугольник или окружность. Окружность мне кажется даже более предпочтительной, т.к. при выделении может не изменять своего центра относительно объекта. Но это уже дело вкуса, и реализация обоих способов позволит уменьшить количество недовольных по этому поводу пользователей. Если за один раз не возможно выделить необходимую часть объекта (весь, или даже несколько объектов), удобно будет применить короткую серию последовательных выделений с удерживанием спец. клавиши (Ctrl, Shift, Alt — не важно). Даже в этом случае такая серия выделений будет гораздо более удобной, чем кропотливое щёлканье мышью вокруг объектов. При этом, не имеет смысла производить выделение (рисовать рамки) в не имеющих объектов областях.

2. Поскольку предполагается вывод на экран расширенной информации о расположенных на картинке объектах, значит заказчик имеет о них всю информацию (в частности контуры или границы объектов и их привязка к картинке). Без этих данных будет просто невозможно корректно вывести на экран эту, связанную с объектами, информацию. Отсюда вывод — данные об объектах существуют, и это сильно облегчает реализацию программы.

3. Собственно об объектах. В принципе, данные о них могут быть в любом удобоваримом виде и, понятно, что чем они будут проще, тем лучше. Мне, например, видится такой вариант. Предполагаю, что на одну картинку всё не влезет, поэтому их будет несколько. Я бы даже посоветовал бы так и сделать, для более подробной детализации. Итак, каждая область карты будет состоять из трёх файлов:
1. Собственно, сама картинка местности, возможно в формате JPEG, которую пользователь будет видеть на экране. Красивая, сочная, с плавными переходами тонов, с градиентами, с лужами на тротуарах, бликующими всё ещё тёплыми лучами сентябрьского солнца, с усыпавшими всё вокруг опавшими листьями, и недовольными, по этому случаю, дворниками.
2. Дополнительная картинка, которую пользователь не видит. Содержит сами объекты и (или) их контуры вокруг них, двух- или трёхцветная. Желательно, что бы расположенные здесь объекты, хотя бы приблизительно вписывались в изображение на первой картинке. Их (картинок) размеры (ширина и высота) должны быть, как минимум, пропорциональны (лучше равны). Это позволит упростить контроль расположения объектов при их создании с помощью простого наложения картинок друг на друга. Контуры объектов можно (и нужно) использовать в качестве рамок объектов при их выделении пользователем на первой картинке, возможно даже с помощью простого копирования прозрачного битмапа со второй картинки на первую. Для этой картинки я бы посоветовал бы формат WMF — будет проще разбирать объекты. Но можно и тот же JPEG. В этом случае, возможно, придётся применять немного более сложные методы распознавания, хотя, как уже сказал Grigoriy, тоже не смертельно. Под разбором и распознаванием, здесь имеется в виду метод поиска рамки объекта на второй картинке, соответствующей изображению этого самого объекта на первой картинке. Наличие уже готовых рамок позволит практически без усилий реализовать автоматическое подсвечивание объектов при наведении на них мыши. А также их автоматическое выделение, например, при двойном щелчке на каком либо из них.
3. И на последок какой-нибудь текстовый файл, с той самой расширенной информацией об объектах.

4. Немного подробнее о рамках объектов. Вообще то, тут уже и так всё ясно. Осталось рассказать о случае, когда выделяется только часть объекта. Но и здесь все просто. Вышеуказанным способом рисуем ту часть рамки, которая попала в область выделения, а остальное дорисовываем линиями границ самой области выделения, теми их отрезками, которые, пересекаются с самим объектом, тем же цветом и толщиной что и оригинальная рамка.


Таким образом, всё получается и просто и красиво. По крайней мере, мне так кажется smile.gif

Отредактировано Doga — 29/07/2006, 04:17
Grigoriy
Отправлено: 29.07.2006, 06:53


Мастер участка

Группа: Участник
Сообщений: 381



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

Ну и если в эту область попадут какие-нибудь объекты — то они будут зафиксированы.
Grigoriy
Отправлено: 29.07.2006, 06:56


Мастер участка

Группа: Участник
Сообщений: 381



QUOTE
Собственно, сама картинка местности, возможно в формате JPEG, которую пользователь будет видеть на экране. Красивая, сочная, с плавными переходами тонов, с градиентами, с лужами на тротуарах, бликующими всё ещё тёплыми лучами сентябрьского солнца, с усыпавшими всё вокруг опавшими листьями, и недовольными, по этому случаю, дворниками.

cool.gif Ну это вы усложняете задачу biggrin.gif biggrin.gif biggrin.gif biggrin.gif
Grigoriy
Отправлено: 29.07.2006, 16:25


Мастер участка

Группа: Участник
Сообщений: 381



А вообще задание интересное...
Лена
Отправлено: 31.07.2006, 09:42


Мастер участка

Группа: Участник
Сообщений: 501



Cпасибо всем за советы! Будет над чем подумать для реализации.

>объекта потребуется 20-30 щелчков, а то и больше

В основном процентов на 90 области будут четырехугольники и параллелограммы (выделение домов). В редких случаях более изощренные как на моем последнем рисунке.

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

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

>Дополнительная картинка, которую пользователь не видит. Содержит сами объекты и (или) их контуры вокруг них, двух- или трёхцветная.

Интересная мысль, надо мне подумать. Пока в голове каша, да и от мысли использовать MapX еще не отказалась. smile.gif


P.S.
Кто не слышал:
MapX компонент для картографии (масштабирование, выделение, поиск объектов, замер расстояний, печать областей, раскраска и прочее на поверхности рисунка-карты). http://extranet.mapinfo.com/products/Overv...uctcategoryid=1
Лена
Отправлено: 11.08.2006, 19:37


Мастер участка

Группа: Участник
Сообщений: 501



Все решил MapX и кода получилось с гулькин нос! smile.gif

Вернуться в Вопросы программирования в C++Builder