Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: элементарная графика на форме  (Прочитано 20161 раз)
0 Пользователей и 5 Гостей смотрят эту тему.
tipabot
Интересующийся

by
Offline Offline

« : 12-12-2010 17:38 » 

Всем привет.
Хотелось бы узнать если способы ускорения отрисовки на форме. У меня такая ситуация если нажата левая клавиша мышки и мышка движется то происходит отрисовка точки (с помощью FillEllipse). Но обработка не поспевает и получается отрывистая линия.
Вот скрин



А вот обработчик здесь ни чего лишнего
Код:
private void gbGraph_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button.Equals(MouseButtons.Left))
            {
                graphicsObj.FillEllipse(Brushes.Black, e.X, e.Y, 5, 5);
                Points.Add(new Point(e.X, e.Y));
            }
        }

Заранее спасибо

* 0c72397e76be.jpg (18.89 Кб - загружено 1741 раз.)
« Последнее редактирование: 12-12-2010 17:53 от RXL » Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 12-12-2010 17:51 » 

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

Добавлено через 1 минуту и 4 секунды:
События движения мыши возникают не так часто, как хотелось бы...
« Последнее редактирование: 12-12-2010 17:54 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 12-12-2010 18:30 » 

Типичная ошибка - вызов графических ф-ций (отрисовки) в событиях для этого неподходящих.
Отрисовка должна производиться ТОЛЬКО в ф-ции перерисовки - OnPaint. В событии мыши надо только изменять данные и вызывать апдейт экрана (Invalidate).
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 12-12-2010 18:49 » 

tipabot, а точки соединяются линиями. И рисуются не эллипсом, а установкой стиля пера Улыбаюсь
Записан

tipabot
Интересующийся

by
Offline Offline

« Ответ #4 : 13-12-2010 08:34 » 

RXL
Цитата
События движения мыши возникают не так часто, как хотелось бы...
Меня одолевают смутные сомнения

Джон
Цитата
Типичная ошибка - вызов графических ф-ций (отрисовки) в событиях для этого неподходящих.
Отрисовка должна производиться ТОЛЬКО в ф-ции перерисовки - OnPaint. В событии мыши надо только изменять данные и вызывать апдейт экрана (Invalidate).
может вы и правы, но это наоборот усугубляет положение т.к. все точки (пиксели по которым прошел указатель мыши)надо перерисовывать каждый раз заново поэтому к прерывистой линии добавляется мерцание.

p.s. Мне надо получить и отрисовать все точки (координаты) по которым прошелся указатель мышки на форме в real-time (ну как в Paint карандаш, paint мне делать не надо это как пример  Отлично)

Алексей1153++
Цитата
tipabot, а точки соединяются линиями. И рисуются не эллипсом, а установкой стиля пера
да дело не в красоте линий, мне надо получить ВСЕ координаты движения мышки, ну а если у меня будут все координаты то я и линии получу без прерываний. Внимание! Говорит и показывает...



Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 13-12-2010 08:47 » 

но это наоборот усугубляет положение т.к. все точки (пиксели по которым прошел указатель мыши)надо перерисовывать каждый раз заново поэтому к прерывистой линии добавляется мерцание.
так сохранять точки нужно на битмапе, который прикреплен к контексту, созданному в памяти . Это даже быстрее будет работать. А когда нужно отрисовать окно - разом копируешь с контекста в озу на контекст  окна. Тут ещё один плюс: в WM_PAINT можно рисовать промежуточную вспомогательную графику поверх рисунка. Причём, основном рисунке эта графикане сохранится Улыбаюсь

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

если задача поставленно именно так (в чём, однако, сомневаюсь), то:
http://msdn.microsoft.com/ru-ru/library/ms646265.aspx



Добавлено через 2 минуты и 44 секунды:
блин, опять я не обратил внимание, что это у тебя дотнет ))
« Последнее редактирование: 13-12-2010 08:50 от Алексей1153 » Записан

yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #6 : 13-12-2010 09:40 » 

Нужно рисовать не точки, а линии между последней и предпоследней точкой. Именно так поступает Paint - поводи быстро мышкой - там будут прямые линии длиной в 2-3 пикселя.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 13-12-2010 09:43 » 

yudjin, у меня линии и по ~100 пикселов по модулю получаются Улыбаюсь
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #8 : 13-12-2010 09:47 » 

может вы и правы

Можно на "ТЫ".

Бессмысленность отрисовки по событию MouseMove станет очевидной после, например сворачивания/разворачивания окна. Да даже достаточно поместить любое другое окно поверх формы, а потом опять вернуться к ней. Результат будет одинаков: вся кривулька исчезнет. Так что тут без вариантов. А мерцание - стандартное явление, подавляется включением двойного буфера, смысл которого описал Лёшка.

Леш, в С# это уже встроено. Нужно только установить стиль контролла OptimizedDoubleBuffer.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 13-12-2010 12:14 » 

Цитата: Джон
А мерцание - стандартное явление, подавляется включением двойного буфера, смысл которого описал Лёшка.

Леш, в С# это уже встроено. Нужно только установить стиль контролла OptimizedDoubleBuffer.
Не, двойная буферизация здесь не поможет именно потому, что при сворачивании окна или загораживании другим окном теряется старая траектория движения. Чтобы она не терялась, её надо где-то запоминать - например, в Bitmap, хранящемся в памяти, и не зависящем от фактического состояния окна.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #10 : 13-12-2010 12:18 » 

Говоря об элементарной графике рановато вспоминать двойной буфер, Compatible контексты и проч. тонкости. я, например, пока не прочувствовал все тяготы рисования, не понимал, зачем это нужно (причем "понимал" как раз с чистыми WinAPI).
А чтобы рисовать неприрывную прямую в событии OnMouseMove, нужно рисовать линии между последней и предпоследней точкой.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 13-12-2010 12:45 » 

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

Это ("её надо где-то запоминать") уже принимается как факт и обсуждению не подлежит.

В событии мыши надо только изменять данные

Что, собственно говоря, УЖЕ делается в оригинальном коде: Points.Add(new Point(e.X, e.Y));

Говоря об элементарной графике рановато вспоминать двойной буфер

Его придётся не только вспоминать, но и использовать, независимо от степени сложности графики, если хочется избежать мерцания. Даже, если графика будет тривиальной, но требующей отрисовки нескольких объектов "одновременно" за событие.
« Последнее редактирование: 13-12-2010 12:47 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #12 : 13-12-2010 13:24 » 

Код:
    public partial class Form1 : Form
    {
        Point oldp;
        Point newP;
        Graphics canva;
        bool isDrawing;

        public Form1()
        {
            InitializeComponent();
            canva = this.CreateGraphics();
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!isDrawing)
                return;
            newP = new Point(e.X, e.Y);
            canva.DrawLine(new Pen(new SolidBrush(Color.Red)), oldp, newP);
            oldp = newP;
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            isDrawing = true;
            oldp = new Point(e.X, e.Y);
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            isDrawing = false;
        }
    }


Ничего не мерцает, не блымает... Да, само себя не отрисовывает. Но топикстартеру это и не нужно было. Иначе можно было бы долго рассказывать про Graphics.FromImage(), Graphics.FromHdc(), долго воевать изменениями размера рабочей области и т.д. и т.п. Но никто же не собирается писать гарфический движок? Вопрос был предельно прост

* paint.png (5.41 Кб - загружено 1562 раз.)
« Последнее редактирование: 13-12-2010 13:28 от yudjin » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 13-12-2010 14:57 » 

Да, само себя не отрисовывает. Но топикстартеру это и не нужно было.

ДА? А это тогда зачем?

Код:
Points.Add(new Point(e.X, e.Y));

А вот, что ему действительно не нужно, так это красота с соединяющими линиями, которую вы с Лёшкой ему так навязываете. Читайте внимательно:

да дело не в красоте линий, мне надо получить ВСЕ координаты движения мышки, ну а если у меня будут все координаты то я и линии получу без прерываний. Внимание! Говорит и показывает...

Вот всё, что ему требуется (с сохранением оригинального кода автора):

Код:
public partial class Form1 : Form
{
private List<Point> Points { get; set; }

public Form1()
{
Points = new List<Point>();
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
 ControlStyles.OptimizedDoubleBuffer |
 ControlStyles.ResizeRedraw, true);
InitializeComponent();
}

protected override void OnPaint(PaintEventArgs e)
{
Points.ForEach(p => e.Graphics.FillEllipse(Brushes.Black, p.X, p.Y, 5, 5));
}

private void Form1_MouseMove_1(object sender, MouseEventArgs e)
{
if (e.Button.Equals(MouseButtons.Left))
{
Points.Add(new Point(e.X, e.Y));
this.Invalidate();
}
}
}

И не надо никаких сложностей и мудростей. Ничего не моргает, всё остаётся, куча точек, плавная линия (каждая точка отрисовывается), resize и прочие прелести. Ну ессно надо учитывать, что Рома сразу сказал:

События движения мыши возникают не так часто, как хотелось бы...



* ss1.gif (9.09 Кб - загружено 1591 раз.)
« Последнее редактирование: 13-12-2010 14:59 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
yudjin
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #14 : 13-12-2010 15:25 » new

Читайте внимательно:

да дело не в красоте линий, мне надо получить ВСЕ координаты движения мышки, ну а если у меня будут все координаты то я и линии получу без прерываний. Внимание! Говорит и показывает...
Вот это ключевое слово я и не приметил
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 13-12-2010 15:53 » 

Джон, я ничего не навязывал )
Записан

tipabot
Интересующийся

by
Offline Offline

« Ответ #16 : 15-12-2010 11:02 » 

Всем спасибо за ответы
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines