Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Свойство Canvas TImage


Автор: Glorius 22.6.2007, 21:28
Вопрос такой. Допустим на канве нарисован некий объект. Поверх него создан еще один объект, скажем в виде стрелки. Как можно стереть эту стрелку, неповредив нижележащий объект?

Автор: Klin 22.6.2007, 21:30
имхо канва перерисовывает, поэтому нужно создать новый объект (типа канвы) и передвигать ее.

Автор: Alexeis 22.6.2007, 21:41
  Предварительно скопировать квадратик такого размера как стрелка на битмап, а потом, когда нужно восстановить, то нарисовать битмап обратно туда где он был.

Автор: zkv 22.6.2007, 23:13
Цитата(Glorius @  22.6.2007,  21:28 Найти цитируемый пост)
Вопрос такой. Допустим на канве нарисован некий объект. Поверх него создан еще один объект, скажем в виде стрелки. Как можно стереть эту стрелку, неповредив нижележащий объект? 

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

Автор: Glorius 23.6.2007, 10:02
Цитата(Alexeis @ 22.6.2007,  21:41)
Предварительно скопировать квадратик такого размера как стрелка на битмап, а потом, когда нужно восстановить, то нарисовать битмап обратно туда где он был.

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

Добавлено через 1 минуту и 38 секунд
Цитата(zkv @ 22.6.2007,  23:13)
можно сконструировать свое окно, регион ему в виде стрелки установить, потом можно работать как с обычным окном. Не знаю правда как в Билдере реализуется.

Я могу сделать окошко ввиде стрелки...надо подумать, но опять же как-то это через ж..у по-мойму))

Добавлено через 2 минуты и 56 секунд
Цитата(Klin @ 22.6.2007,  21:30)
имхо канва перерисовывает, поэтому нужно создать новый объект (типа канвы) и передвигать ее.

А если у меня 25 таких стрелок, то осздавать 25 холстов? И еще немного не догнал методу создания новой канвы...

Автор: Alexeis 23.6.2007, 14:14
Цитата(Glorius @  23.6.2007,  10:02 Найти цитируемый пост)
А если у меня 25 таких стрелок, то осздавать 25 холстов? И еще немного не догнал методу создания новой канвы... 

  В таких случаях перерисовывают всю картинку целиком это быстрее чем восстанавливать много мелких каритнок.

Автор: zkv 23.6.2007, 16:30
Цитата(Glorius @  23.6.2007,  10:02 Найти цитируемый пост)
Я могу сделать окошко ввиде стрелки...надо подумать, но опять же как-то это через ж..у по-мойму))

через ж.. или нет понятно только тебе, так как ты один знаешь условие задачи. 
Я предложил альтернативу, выбор за тобой. 

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

Кстати, может ты просто не правильно реагируешь на слово "окно", в курсе что все контролы (кнопки, комбо-боксы и пр.) по сути - окна? Возьмем тот же static-text (не знаю как в Билдере правильно называется) - получается для вывода строки текста, мы создаем целое окно! - это тоже через ж.. придумали?

Автор: Glorius 23.6.2007, 16:46
Цитата(zkv @ 23.6.2007,  16:30)
через ж.. или нет понятно только тебе, так как ты один знаешь условие задачи. 
Я предложил альтернативу, выбор за тобой. 

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

Кстати, может ты просто не правильно реагируешь на слово "окно", в курсе что все контролы (кнопки, комбо-боксы и пр.) по сути - окна? Возьмем тот же static-text (не знаю как в Билдере правильно называется) - получается для вывода строки текста, мы создаем целое окно! - это тоже через ж.. придумали?

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

Автор: _hunter 25.6.2007, 10:42
что через ж а что нет определяется очень легко: реализуем самый простой вариант (минимум кода) -- а именно перерисовку всего окна. если при таком варианте нет заметных морганий -- останавливаемся на этом варианте. если есть -- реализуем другой.
кстати. создать ассоциированные битмапы -- не так уж и сложно: создаем постой битмап и кладем его в map'у (с id == id стрелки (стрелка should be классом (хотя можно и ее указатель использовать...))

Автор: Glorius 25.6.2007, 11:46
Цитата(_hunter @ 25.6.2007,  10:42)
что через ж а что нет определяется очень легко: реализуем самый простой вариант (минимум кода) -- а именно перерисовку всего окна. если при таком варианте нет заметных морганий -- останавливаемся на этом варианте. если есть -- реализуем другой.

hunter, похоже это действительно самый правильный вариант, поскольку графической информации должно быть не так уж и много.

Но меня еще интересует и вопрос перемещения графических объектов мышкой (это из другой программы). Как это лучше делать?

Автор: Lazin 25.6.2007, 11:48
Цитата

Допустим на канве нарисован некий объект. Поверх него создан еще один объект, скажем в виде стрелки. Как можно стереть эту стрелку, неповредив нижележащий объект?

Если нужно быстро перерисовать часть изображения, можно использовать Xor. Сначала рисуешь фон, затем устанавливаешь ...->Canvas->Pen->Mode = pmXor и рисуешь стрелку. Когда надо перерисовать, сначала рисуешь стрелку ещё раз (Pen->Mode = pmXor), после этого остаётся только фон, затем рисуешь её в другом месте.
Код

void __fastcall TForm1::Image2MouseMove(TObject *Sender, TShiftState Shift,
      int X, int Y)
{
    static int _x = -20, _y = -20;
    Image2->Canvas->Pen->Mode = pmXor;
    Image2->Canvas->Brush->Style = bsNone;
    Image2->Canvas->Ellipse(_x-10,_y-10,_x+10,_y+10);
    Image2->Canvas->Ellipse(X-10,Y-10,X+10,Y+10);
    _x = X;
    _y = Y;
}

Автор: _hunter 25.6.2007, 12:03
а вот для перемещения уже желательно переходить на классы: тогда (при опускании кнопки) просто пробегаем по вектору стрелок и смотрим лежит ли точка в пределах стрелки (метод класса "стрелка") если лежит -- при перемещении мыши задаем стрелке новые координаты и перерисовываем экран.

Автор: Glorius 25.6.2007, 15:01
Hunter, спасибо. smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)