Помощь - Поиск - Пользователи - Календарь
Полная версия: Builder 6.0
Форум «Всё о Паскале» > Современный Паскаль и другие языки > Ада и другие языки
Fanat
Требуеться создать примитивный расширяемый графический редактор.
Основные функции:
размещение двух типов обьектов- прямоугольник и треугольник.
обьекты можно создавать и двигать по окну при помощи мыши.
групповое создание обектов.
сохранение и загрузка.

Не знаю с чего начать.
Как создать окно где будут прорисовываться обьекты?
Для описания,например,прямоугольников, лучше всего, создать тип, который хранит в себе 4 координаты по Ох и Оу?
Как реализовать прорисовку линий между этими координатами?
Почему ColorDialog не растягиваеться?
мисс_граффити
1. Как создать окно где будут прорисовываться обьекты?
PaintBox кинуть на форму?
2. Для описания,например,прямоугольников, лучше всего, создать тип, который хранит в себе 4 координаты по Ох и Оу?
А зачем 4? Двух, имхо, более чем достаточно (по диагонали).
Но отрисовка прямоугольников, если мне память не изменяет, уже реализована.
Хочется изобрести велосипед?
3. Как реализовать прорисовку линий между этими координатами?
См. п.2
4.Почему ColorDialog не растягиваеться?
Так реализован... А зачем это нужно???
При желании, можно свой компонент сваять
Fanat
Цитата(мисс_граффити @ 3.09.2007 21:34) *

1. Как создать окно где будут прорисовываться обьекты?
PaintBox кинуть на форму?
2. Для описания,например,прямоугольников, лучше всего, создать тип, который хранит в себе 4 координаты по Ох и Оу?
А зачем 4? Двух, имхо, более чем достаточно (по диагонали).
Но отрисовка прямоугольников, если мне память не изменяет, уже реализована.
Хочется изобрести велосипед?
3. Как реализовать прорисовку линий между этими координатами?
См. п.2
4.Почему ColorDialog не растягиваеться?
Так реализован... А зачем это нужно???
При желании, можно свой компонент сваять


1)Кинул Image...Это подойдёт думаю...?
2)Насчёт 4х это я погорячился. А можно ли будет подвинуть стандартно прорисованный обьект? И как?
3)Ок
4)Для красоты... smile.gif

Сложность в следуюшем: если мышь находиться на Image и клик мышкой, то создать прямоугольник. То есть создать по какому либо правилу например мышь находиться в левом нижнем углу.

"Сохранение и загрузка",мне кажеться имееться ввиду не изображение а какой либо другой способ хранения объектов, иначе как в загружённом файлу распознать обьект и подфинуть?..
мисс_граффити
1. Ну, дело твоё. Я высказала свое мнение. Прислушиваться к нему или нет - сам решай.
2. Закрасил цветом фона, нарисовал на новом месте
Цитата
То есть создать по какому либо правилу например мышь находиться в левом нижнем углу.

ну например. и размеры сторон заданы.
или надо ловить 2 щелчка. или нажатие и отпускание кнопки (то есть тянуть).
Цитата
"Сохранение и загрузка",мне кажеться имееться ввиду не изображение а какой либо другой способ хранения объектов, иначе как в загружённом файлу распознать обьект и подфинуть?..

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

Добавлено через 3 мин.
я делала подобную вещь в рамках другого задания...
там надо было размещать на форме прямоугольнички и кружочки (все одного размера), а потом соединять их линиями (это я сеть Петри строила smile.gif)
Fanat
Не могла бы ты подсказать каук тогда узнать осуществлен клик на Image и где находиться курсор?..
Закрасить фоном и нарисовать новый ето хорошо, но если нарисовано сразу несколько обьектов то ето не сработает или будет слишком долго по времени...как быть в таком случае?
И как для передвижения "взяься"за обьект?..
мисс_граффити
Цитата
Не могла бы ты подсказать каук тогда узнать осуществлен клик на Image и где находиться курсор?..

у меня только делфи под рукой, но, вроде, отличий нет: обрабатывай событие OnMouseDown
кстати, собственно рисовать лучше в OnPaint
только у Image его нет
Цитата
Закрасить фоном и нарисовать новый ето хорошо, но если нарисовано сразу несколько обьектов то ето не сработает или будет слишком долго по времени...как быть в таком случае?

можно подойти к этому вопросу так: при попытке перемещения вызывать OnPaint
а в нем: закрашиваем все и рисуем все имеющиеся фигуры (их хранить в списке или массиве).
это не очень долго, если у тебя не тысячи фигур.
если не пойдет - я подумаю над вопросом оптимизации. ведь, по сути, надо перерисовывать небольшой кусочек (и, возможно, попавшие в него другие фигуры). но проверять на пересечения будет не намного быстрее - все равно полный перебор.
Цитата
И как для передвижения "взяься"за обьект?..

щелкнуть по нему... проанализировать, в какой из объектов попали...
проблема вот в чем: если мы щелкнули в пересечение двух фигур, какая потащится?
volvo
Цитата
проблема вот в чем: если мы щелкнули в пересечение двух фигур, какая потащится?
Та, которая в списке ближе к "вершине" (то есть, глубина которой в Z-буфере была бы меньше), то есть проверяем от "верхней" фигуры, и тянем первую найденную фигуру, которая содержит "в себе" координаты мыши во время щелчка... Можно, соответственно, переместить перетягиваемую фигуру на "вершину".
мисс_граффити
ну это как вариант...
а можно, например, ту, центр которой ближе (то есть как будто это не картонные прямоугольнички, накиданные на стол... а нечто абстрактное, для чего понятие выше-ниже не определено. все лежит на одном уровне)
Fanat
Спасибо за помошь, думаю всё примерно ясно. Осталось пару вопросов
Какая функция вернёт координаты курсора?
И на чем все-таки лучше рисовать? PaintBox не нашёл. Что такое OnPaint?
мисс_граффити
Цитата
Какая функция вернёт координаты курсора?

обработчик события OnMouseDown получает эти координаты
посмотри внимательнее
Цитата
И на чем все-таки лучше рисовать?

ты хочешь, чтобы я повторила? или устроим голосование?
Цитата
PaintBox не нашёл.

ищи лучше
закладка System
Цитата
Что такое OnPaint?

событие... грубо говоря, перерисовка (например, если ты свернул окно, а потом развернул... или перекрыл другим окном, а потом его убрал)
Fanat
А как проверить нажата ли кнопка1 или кнопка2? Мне надо, например, если нажата кнопка1 рисовать прямоугольник и если 2ая то треугольник.

Сделал, что по клику мышки появляеться прямоугольник,нижний левый угол которого находиться на месте курсора,информация о прямоугольниках храниться в векторе. Далее перебирая элементы вектора можно найти последний созданнй прямоугольник в который попал курсор, если требуеться передвинуть. Но, как получать координаты курсора при его передвижении,чтобы синхронно с этим прорисовывать заново прямоугольник?
мисс_граффити
пользуйся компонентами, для этого предназначенными.
RadioButton, например
Fanat
Сделал, что по клику мышки появляеться прямоугольник,нижний левый угол которого находиться на месте курсора,информация о прямоугольниках храниться в векторе. Далее перебирая элементы вектора можно найти последний созданный прямоугольник, в который попал курсор, если требуеться передвинуть. Но, как получать координаты курсора при его передвижении,чтобы синхронно с этим прорисовывать заново прямоугольник?
klem4
OnMouseMove
Fanat
Цитата(klem4 @ 4.09.2007 19:58) *

OnMouseMove


То есть обрабатывать событие OnMouseMove. Но откуда к нему обращаться?
volvo
Что значит "откуда"? Обработчик события будет вызываться, когда ты будешь двигать мышь... Не надо ниоткуда ничего вызывать самому...
Fanat
Цитата(volvo @ 4.09.2007 20:37) *

Что значит "откуда"? Обработчик события будет вызываться, когда ты будешь двигать мышь... Не надо ниоткуда ничего вызывать самому...


Это событие будет срабатывать когда мышь передвигаеться по окну PaintBox. Но мышь я буду передввигать и в том случае если хочу создать новый прямоугольник. Как быть?
volvo
Сорри, но в том случае, если ты захочешь создать новый прямоугольник, ты должен будешь отпустить кнопку мыши, и потом снова ее нажать, так? Вот именно на OnMouseUp/OnMouseDown и должна быть возложена функция определения, рисуешь ты тот прямоугольник, что когда-то начал, или это уже новая фигура...

Кстати, я бы еще очень внимательно посмотрел на метод MouseCapture, чтобы при случайном (или не очень) выходе мыши из PaintBox-а не произошло неожиданностей yes2.gif
Fanat
Цитата(volvo @ 4.09.2007 20:57) *

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


У меня немного не так. Есть окно. В котором если нажать на мышь, то будет нарисован автоматически прямоугольник. Который уже потом можно будет двигать,а в дальнейшем надеюсь и изменять размеры.
Так что думаю, чтобы двигать прямоугольники можно создать RadoiButton и если она активна то тогда уже не думать о создании. Но в этом случае незнаю как узнать координаты перемещения.

Цитата

Кстати, я бы еще очень внимательно посмотрел на метод MouseCapture, чтобы при случайном (или не очень) выходе мыши из PaintBox-а не произошло неожиданностей


Не знаю что такое MouseCapture blink.gif .
мисс_граффити
И MouseMove, и MouseUp, и MouseDown получают координаты курсора
Может, не самый красивый вариант, но я бы сделала так: ввела глобальную логическую переменную и в OnMouseMove смотерела, что мы делаем: перемещаем фигуру (тогда надо рисовать) или просто так двигаем мышкой.
Fanat
Цитата(мисс_граффити @ 4.09.2007 22:12) *

И MouseMove, и MouseUp, и MouseDown получают координаты курсора
Может, не самый красивый вариант, но я бы сделала так: ввела глобальную логическую переменную и в OnMouseMove смотерела, что мы делаем: перемещаем фигуру (тогда надо рисовать) или просто так двигаем мышкой.



Получилось так: нашли нужный прямоугольник и глобальной переменной flag приравняли 1.
Начинает работать OnMouseMove. И должен передвигаться прямоугольник.


void __fastcall TForm1::PaintBox1MouseMove(TObject *Sender,
TShiftState Shift, int X, int Y)
{
if (flag==1)
{
int x1=rects.back().x1;
int y1=rects.back().y1;
Form1->PaintBox1->Canvas->Rectangle(x1+X,y1+Y,x1+X-30,y1+Y-30);
}
}



Но через несколько секунд выходит ошибка: Project1 raised exception class std::bad_alloc with message 'Exepption Object Address:0x28011005E'.
После чего можно продолжить Run и тогда прямоугольник двигаеться.
Что не так?

Какое событие даст понять что кнопка мышки отпушена? (Там необходимо flag=0).
мисс_граффити
что такое rects? извини, по этому куску кода сложно что-то сказать.
Fanat
Цитата(мисс_граффити @ 4.09.2007 23:40) *

что такое rects? извини, по этому куску кода сложно что-то сказать.


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

мисс_граффити
#include "rectangle.h"  
#include "triangle.h"

это что за звери?
ты хочешь, чтобы помогли? или хочешь скрыть максимальную часть проекта?
volvo
Fanat, можно вопрос? Вот ты пишешь программу на С++, да? Почему не написать ее с использованием наследования? Ну, скажем, набросок:

class
figure {
... // нечто общее для прямоугольника и треугольника
protected:
virtual bool isInside(TPoint &mouse) = 0;
...
};

class
triangle: public figure {
... // здесь - признаки, характерные для треугольника

virtual bool isInside(TPoint &mouse) {
... // проверяешь попадание mouse в треугольник
}
...
};

class
rectangle: public figure {
... // здесь - признаки, характерные для прямоугольника

virtual bool isInside(TPoint &mouse) {
... // проверяешь попадание mouse в прямоугольник
}
...
};

// Ну, а потом:

vector<figure> figures; // работаешь с любыми типами фигур


причем проверка, куда попала мышь, сокращается до одной строки: вызов метода isInside(TPoint(X, Y))... Во-первых, это более расширяемо, во вторых - гораздо проще (не надо работать с несколькими векторами, достаточно одного), ну и наконец, такой код будет больше соответствовать философии С++...

Я, к сожалению, пока не могу помочь тебе ничем, кроме теоретических замечаний, в связи со сгоревшей материнкой я поменял компьютер, и пока у меня установлена только Дельфи 6, в ближайшее время поставлю Builder 2006, тогда советы будут более детальными smile.gif
Fanat
Мисс_граффити, извини забыл, там вот что:

struct rectangle
{
int x1,x2,y1,y2;
};


и 6 координат для треугольника.

volvo, потому, что не умею, но ты прав, постараюсь сегодня разобраться и сделать что-то похожее.
Fanat
привет volvo, сделал так как ты сказал.Немного разобрался с наследованием. Теперь в векторе figures содержаться и треугольники и прямоугольники. Но не знаю как обратиться к треугольнику или прямоугольнику,то есть к координатам его вершин, если мы достаём последний элемент из вектора. Даже если описать функции которые выдают true при попадании в фигуру, то все равно необходимо узнать её координаты. Как это сделать?. virtual не особо понял.
volvo
Цитата
Даже если описать функции которые выдают true при попадании в фигуру, то все равно необходимо узнать её координаты. Как это сделать?

Фигура вообще-то сама хранит свои координаты... То есть, смотри:

// Это - абстрактный базовый класс, ты не можешь создавать экземпляры этого класса
class
figure {
protected:
virtual bool isInside(TPoint &mouse) = 0;
};

class
triangle: public figure {
// здесь - признаки, характерные для треугольника
// Собственно, тут и храним 3 точки, образующие треугольник:
TPoint a, b, c;

virtual bool isInside(TPoint &mouse) {
... // проверяем попадание mouse в треугольник (именно образованный точками a, b, c)
}
...
};

class
rectangle: public figure {
// здесь - признаки, характерные для прямоугольника
// Прямоугольник определяется двумя точками: верхний левый и правый нижний угол:
TPoint leftUp, rightDown;

virtual bool isInside(TPoint &mouse) {
... // проверяешь попадание mouse в прямоугольник (определяемый полями leftUp и rightDown)
}
...
};
Больше ничего пока сказать не могу, не видя, как именно ты реализовал работу с фигурами... Если хочешь - присоедини свой проект (можно в приват)...
Fanat
Всем большое спасибо, обьекты двигаються,
Как бы теперь научиться сохранять элементы в файл и загружать из него?
volvo
Проходом по вектору, и вызовом для каждого его элемента метода, который записывает данные о себе в файл...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.