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

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

ru
Offline Offline
Пол: Женский

« : 12-02-2016 11:13 » 

Помогите, подайте идею.

1. Пишу на visual studio c++ 2010.

2. Вывожу график функции с помощью GDI:
    MoveTo(...);
    PolylineTo(...);

3. Надо при щелчке кнопкой мыши по кривой графика выдавать значения х и у.

4. Координаты любой точки я могу определить, они передаются при обработке события с помощью OnLButtonDown(UINT nFlags, CPoint point)

5. Могу выбросить координаты, которые не относятся к области вывода графика на экран с помощью PtInRect(point).


Вопрос такой : как мне выдавать значения только точек графика, а не любой точки клиентской области?

Первое, что приходит в голову эти точки отличаются цветом, тогда вопрос мб такой как вытащить цвет точки?

Записан
RXL
Технический
Администратор

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

WWW
« Ответ #1 : 12-02-2016 11:53 » 

Проверяй на попадание в точку с некоторым радиусом. Если точек нашлось несколько, вычисли расстояние до точки и выбери ближайшую. Фактически, нужно обработать все точки.

Для плотных графиков с большим количеством точек можно использовать только "x" координату мыши.

PS: чего-то я тормознул: для любых графиков из одной функции достаточно "x". Улыбаюсь
« Последнее редактирование: 12-02-2016 13:37 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #2 : 12-02-2016 12:09 » 

Спасибо, попытаюсь реализовать.
Записан
Джон
просто
Администратор

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

« Ответ #3 : 12-02-2016 22:30 » 

Ром, а расстояние от точки до... чего вычислять?

Ф-я, я так понимаю, дискретная кусочно-линейная в силу PolylineTo(...);

Таким образом, данных для абсолютно всех точек графика нет.

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

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

зызы Параметры кусков можно вычислить один раз и занести в отдельный массив
« Последнее редактирование: 12-02-2016 22:40 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #4 : 13-02-2016 06:24 » 

ann_nef, при распечатке графика нужно запомнить координаты каждой точки (относительно окна)

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

Записан

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

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

« Ответ #5 : 13-02-2016 21:35 » 

Лёш, во-первых, координаты точек запоминать не надо, они уже даны, по ним строится график.
А во-вторых...



и шо?

* ss1.gif (7.81 Кб - загружено 1444 раз.)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #6 : 14-02-2016 07:40 » 

Координаты каждой точки запомнены и на графике они обозначены кружочками, примерно,как у Джона на рисунке  Xn,Yn.
Щёлкать будут только по по этим кружочкам.
Линии, которые их соединяют нужны только для наглядности,между точками нет конкретного значения амплитуды и поэтому эти точки никого не интересуют.
Уже по этим графикам увидели недочёты в аппаратуре.

Спасибо всем. Идею поняла, буду действовать.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #7 : 14-02-2016 08:25 » 

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

Поэтому не понимаю вопроса , что "и шо" ? ))  
Записан

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

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

« Ответ #8 : 14-02-2016 11:22 » 

ann_nef, как это можно заставить пользователя кликать ТОЛЬКО по точкам?
Раз уж ты делаешь интерполяцию между двумя точками, то надо обеспечить и отображение для любого участка графика. Тем более, что сделать это очень просто. Принадлежность точки к прямой  (y=ax+b) вычислить гораздо проще, чем расчитывать минимальное расстояние между двумя точками.

Лёшик, при чём тут обратный пересчёт или нет? Экранные координаты каждой точки данных уже известны (а как же они ещё отрисовываются?).

А "и шо?" было к ситуации на рисунке. Пользователь кликает точно на линии соединяющей две точки, координаты чего ты собираешься показывать? Усложним задачу: он кликает строго по середине между двумя точками. И шо? Ага
« Последнее редактирование: 14-02-2016 11:26 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #9 : 15-02-2016 04:24 » 

Джон, что именно показать - зависит от задачи. Любую ближайшую точку, либо точку на соединяющей линии. Если точки вааапще на одинаковом расстоянии - выбирается любая
Записан

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

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

« Ответ #10 : 15-02-2016 09:37 » 

Джон, что именно показать - зависит от задачи.

И что непонятного в задаче?

3. Надо при щелчке кнопкой мыши по кривой графика выдавать значения х и у.


Любую ближайшую точку, либо точку на соединяющей линии. Если точки вааапще на одинаковом расстоянии - выбирается любая

Как это "любая"?  Быть такого не может

Т.е. "шаг влево" вижу одно, "шаг вправо" совершенно другое? Даже если этот "шаг" равен одному экранному пикселю? Кто быстрей сойдёт с ума в этом случае?

Как пользователь, я ожидаю увидеть значение ф-ции в точке "клика". Анализ этих значений - это моя проблема. Если данных на этом участке нет, то я понимаю, что имеет место быть некая интерполяция, или же что эти данные полная чушь.
Но программа должна отрабатывать адекватно, иначе я буду думать, что у неё развился свой собственный разум, со всеми вытекающими последствиями. Ага
« Последнее редактирование: 15-02-2016 09:40 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #11 : 16-02-2016 04:30 » 

Джон, я не знаю, как ты собрался поместить курсор мыши между пикселями экрана Отлично
Записан

zubr
Гость
« Ответ #12 : 16-02-2016 05:47 » 

А если клик попал вообще не на прямую X,Y X1,Y1, к примеру, а на несолько пикселей левее или правее?
Имхо, проще графическое решение:
1. Делаем, к примеру, черный график на белом фоне.
2. По координате клика определяем цвет пиксела, если не черный, проходим влево-вправо по оси X на несколько пикселей (допускаемое отклонение). Если черный пиксел встретился - это координата X графика, иначе клик вне графика.
3. Аналогично для Y.
Записан
Джон
просто
Администратор

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

« Ответ #13 : 16-02-2016 10:00 » 

Джон, я не знаю, как ты собрался поместить курсор мыши между пикселями экрана Отлично

Лёш, это уже отмазки. Где это я собирался поместить курсор между пикселями?

 - растояние между точками А и Б равно 13 пикселям
Координаты какой точки (А или Б) будут отображены, если пользователь кликает на 7-ом пикселе?

 - растояние между точками Б и В равно 24 пикселям
Координаты какой точки (Б или В) будут отображены в след. случаях:
   а)  пользователь кликает на 11-ом пикселе
   б)  пользователь кликает на 12-ом пикселе

Попробуй теперь выкрутиться Ага

А если клик попал вообще не на прямую X,Y X1,Y1, к примеру, а на несолько пикселей левее или правее?

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

Само определение "на несколько пикселей" настолько расплывчато, что не поддаётся алгоритмизации. Как только ты скажешь "скажем... 4", тут же возникает вопрос: а почему не 3 или 5?

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

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #14 : 16-02-2016 13:07 » 

У меня, как всегда, вопрос элементарный, но я запуталась, читая всё подряд в инете.

Кликаем левой кнопкой мыши по клиентской области,где график выведен, получаем с помощью OnLButtonDown(UINT nFlags, CPoint point) координаты точки, относительно левого, верхнего угла окна.

А как перейти к координатам этой точки относительно клиентской области? (Как применить LPtoDP не поняла, извиняюсь за бестолковость.)
И определить цвет точки?

Джон, они будут кликать только по точкам.
Между ними нет амплитуд(не записаны,тк не было этого события),поэтому промежуточные точки никого не интересуют. Линии, соединяющие точки, нужны только для наглядности.
Но, это в моей конкретной  задаче. Другим мб они нужны будут.
Записан
Джон
просто
Администратор

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

« Ответ #15 : 16-02-2016 14:57 » 

ann_nef, нууу во-первых вопрос остаётся

ann_nef, как это можно заставить пользователя кликать ТОЛЬКО по точкам?

они будут кликать везде!

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

А как перейти к координатам этой точки относительно клиентской области?

Тут всё зависит от реализации canvas="холста" (той области где непосредственно отрисовывается график). Я в подобных случаях не рисую где попало на основном окне, а просто делаю собственное окно (CWnd) и ловлю события мыши в нём (ты же всё-равно в OnPaint вызываешь GetClientRect). И никаких преобразований не требуется - 0,0 окна соответствует 0,0 мыши. Это же одновременно решает и проблему учёта прокрутки.

Если же ты используешь DC основного окна, то тебе надо учитывать смещение холста оносительно него. Но это ненужные заморочки. ИМХО разумеется.

Добавлено через 42 минуты и 8 секунд:
Ладно, не хотите, как хотите. Если нужно только по точкам, то всё-равно без этих "цветочных поисков".

Если быстро, но маленько грязно, то... Для каждой точки делаешь концентричный квадрат с длиной стороны равной диаметру области попадания, а потом используешь ф-ю PtInRect. Если хочешь сделать "чисто", то вместо квадрата создаёшь элиптический регион и, соответственно, используешь ф-ю PtInRegion.
« Последнее редактирование: 16-02-2016 15:44 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #16 : 17-02-2016 04:25 » 

Джон, даже не собираюсь выкручиваться и выпутываться, я и не запутывался )) Если расстояние до точек одинаковое - выбираю ЛЮБУЮ из них. Первую по индексу. Да хоть по рандому. Нету такой проблемы то
Записан

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

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

« Ответ #17 : 17-02-2016 10:13 » 

Вот и я говорю, кликаешь на пиксель 11 получаешь одну точку, смещаешься на 12-ый и... уже совсем другую. Классная логика. Пользователи будут в восторге! Ага

ps У нас за такие "логики" опускают ниже плинтуса. А за "рандом" могут и уволить.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #18 : 18-02-2016 06:12 » 

Джон, Ответ #7 - если ты кликаешь в 11, то никакого смещения нет . Фантазируешь чегойта ))
Записан

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

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

« Ответ #19 : 18-02-2016 08:57 » new

Лёшик, ладно, я есть рюсски плёхо понимайт. Ага

При расстоянии между точками в 24 пикселя (чётное количество) 11-ый пиксель находится ближе к одной точке данных (назовём её А), а 12-ый к другой (Б). Т.е. по твоей логике, при клике на 11-ый пиксель будут показаны координаты точки А, а при клике на 12-ый - Б. "Вот тебе и пожалуйста" (с) Сместился на один пиксель, и получил другие данные.

Так понятно?

Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #20 : 18-02-2016 09:12 » 

А если графика будет два или больше в одной системе координат, то только цвет поможет?
Записан
Джон
просто
Администратор

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

« Ответ #21 : 18-02-2016 11:28 » 

А если два (или больше) графика будут одинакового цвета... Ага

А если дисплей будет монохромный... А если разрешение поменяется...

Или вот ещё проблемка... Толщина линии. Сорри, я хотел сказать точки. Допустим диаметр точки, с данными в координатах холста (100,100), равен 11 и, допустим, что проблема с antialias тоже каким-то образом решена (мы можем получать и однозначно различать цвет каждой точки холста).
Пользователь кликает в точку с координатой (97,97). Ессно попадает на "нужный" цвет. Какие значения будут выданы? 97,97? Но у нас нет таких данных!
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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


« Ответ #22 : 18-02-2016 11:45 » 

Джон, дело ясное, что дело тёмное!
Записан

zubr
Гость
« Ответ #23 : 18-02-2016 12:13 » 

Джон, а если график не полилайн, а полибейзер - твой алгоритм уже не работает. Касаемо цветов - та хоть серо-буро-малиновый, главное что бы он был везде одинаков для фона и отличающийся от фона но везде одинаковый для графика. Если графиков несколько - рисуем их разным цветом, да хотя бы отличающимся на 1 - визуально они будут одного цвета, если так надо. А вот попасть в линию графика курсором, да еще чтобы координата соответствовала уравнению линии - тот еще гиморрой для пользователя (ну не юзабелити это), хотя... это идея для компьютерной игры в попадалки Улыбаюсь
Записан
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #24 : 18-02-2016 12:28 » 

И ещё вопрос: как этот злополучный график запомнить в файле?
Записан
Джон
просто
Администратор

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

« Ответ #25 : 18-02-2016 13:07 » 

Джон, а если график не полилайн, а полибейзер - твой алгоритм уже не работает.

С каких это пор математика не работает?

Ессно что в этом случае будет не y=ax+b, но другая ф-я y=f(x).

зы Что ж вы так математику не любите?

Ладно, надоело мне кого-то в чём-то убеждать. Делайте с цветом.

А вот попасть в линию графика курсором, да еще чтобы координата соответствовала уравнению линии - тот еще гиморрой для пользователя (ну не юзабелити это),

голословно, доказать сможешь? Я проблемы с цветопопадаловом озвучил. А что значит "попасть в линию графика" гемморно? Да сотни тысяч всяких там дизайнеров делают это по сто раз на дню, и ничего не жужжат. Или всякие там фотошопы по цвету точки находят? Ну-ну...
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #26 : 18-02-2016 13:34 » 

Дык, сделала я с помощью подсказки Джона.

Пожалуйста, ответьте на вопрос:

как этот  график запомнить в файле?

Добавлено через 44 секунды:
как этот  график запомнить в файле?
« Последнее редактирование: 18-02-2016 13:35 от ann_nef » Записан
Джон
просто
Администратор

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

« Ответ #27 : 18-02-2016 19:54 » 

Ты хочешь сохранить его как картинку или как набор данных? Если как данные, то... можно выбрать что угодно: XML, просто текстовый файл, бинарный файл... В общем всё зависит от дальнейших целей.

Если как картинку, то DC, в который ты отрисовываешь, можно скопировать (с помощью ф-ции BitBlt) в обыкновенный битмап. А его можно сохранить в файл, преобразовав предварительно в массив байтов. Для это нужно: 1. CreateCompatibleBitmap 2. BitBlt и 3. GetDIBits

Посмотри любые примеры сохранения скрина экрана в файл. В этом примере посмотри ф-ю CaptureAnImage. Там всё, что тебе нужно.

зы Встречный вопрос, а почему GDI, а не GDI+? Там подобные "проблемы" решаются парой строчек кода, да и в принципе им пользоваться гораздо удобней. Или есть какие-то ограничения?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #28 : 25-02-2016 07:40 » 

Просто про GDI+ ничего не знаю.

График запомнила в файле BMP.

Ещё один вопрос: как график распечатать из программы?

В какую сторону смотреть?
Записан
ann_nef
Помогающий

ru
Offline Offline
Пол: Женский

« Ответ #29 : 25-02-2016 07:42 » 

Помогите ещё раз.
Джон, если подскажете про GDI+, то буду благодарна. На всякий случай напоминаю, что использую MS Visual c++ 2010/
Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines