1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Собственно,есть проэкт в VS 2008 C++,у фрейма есть кнопка и picturebox.По нажатии на кнопку должна отрисоваться сетка из прямоугольников.(100х100 где то) Дело в том что после нажания кнопки происходит отрисовка,но по завершению результат пропадает,приходится нажимать 2 раз,и тогда от нормально и длительно отображается,хотя иногда тоже пропадает.Мне непонятно почему такое может происходить??Еще мне немного не нравится та скорость,с которой происходит отрисовка,можно ли ее как нибудь ускорить?Дело в том,что потом для каждой "клетки" будет задаваться свой собственный цвет.
Krjuger, тип RectangleF как-то больше подходит для заталкивания в него вещественных значений, чем Rectangle. Опять же, не надо перерасчитывать значения X в цикле по J, результаты будут одинаковыми, вынеси вычисления из внутреннего цикла. Но это так, для проформы. На скорость отрисовки влияния не окажет.
С точки зрения алгоритма - все прекрасно, почему сбоит реализация в VS 2008 - непонятно. Проверил на C# - рисует прямоугольнички как положено, ничего не исчезает.
Цитата
Еще мне немного не нравится та скорость, с которой происходит отрисовка,можно ли ее как нибудь ускорить?
Если б ты не написал ниже, что
Цитата
потом для каждой "клетки" будет задаваться свой собственный цвет.
- то ларчик открывался просто: в цикле заполняешь массив RectangleF[], без отрисовки, а потом одним махом g->FillRectangles + g->DrawRectangles. Выигрыш по скорости очень заметен. Но раз для каждой клетки - свой цвет, то можно сэкономить на одной из отрисовок. В цикле делаешь g->FillRectangle, и запоминаешь область. А потом, после циклов - опять же один вызов g->DrawRectangles, и тебе все клеточки обведутся...
Ну просто тут такое дело,что эта задача напрямую связана с той,что была до этого,тобиш расчитать поле температур,но преподавателю оказалось мало полученных результатов,ему еще все в картинках подавай.Суть в том что у меня есть некая фигура заданная в виде массива и в каждой ячейке храниться "температура" в данной точке.Мне надо все отградуировать считая, что минимальная температура, это красный цвет, а максимальная это синий.Граници прямоугольников я потом вообще уберу,потому что преподаватель нам давал код на делфи ,который совершал необходимые действия с словами " портируйте сами".И там было x := ((i-1)*h + h/2) * Xkoef; вместо x= (i)*h * Xkoef;,и выводило явно не то что надо(было небольшое наложение прямоугольников).Поэтому,чтобы исправить, я взял и отрисовывал сетку,чтобы убедиться и исправить,хотя принципи такое наложение возможно поможет для больших прямоугольников,дескать получение промежуточного цвета,хотя я не проверял как себя будет вести это наложение.
Тогда тебе волноваться не о чем. Распахнутое на весь экран окно (при расширении 1920*1080) заполняется разными цветами меньше чем за 2 секунды. Все тормоза - именно из-за отрисовки границ, DrawRectangle работает значительно медленнее, чем FillRectangle...
Чтоб применить нормальный StretchBlt, он для начала должен быть в .Net, да? Это первое. Второе - я не упирался в оптимизацию: на месте создавал кисти, на месте же пересчитывал координаты, просто, чтобы проверить, насколько тормозит отрисовка границ против заливки. Тормозит. Порядка 12 секунд против примерно двух.
А StretchBlt тебе что, очень поможет (даже если его импортировать), если не все цвета одинаковые? И даже не большинство. Ну, будет работать моментально на красных ячейках. Как начнешь рисовать реальную картинку с градациями цветов - получишь еще бОльшие тормоза. Где выигрыш?
То у тебя красно-чёрное дерево быстрее, чем сортировка подсчётом, теперь это.
Это ты о чем, вообще?
Цитата
StrechBlt тормознее, чем куча прямоугольников?!
Блин... Да ты пойми, что ТС пишет-то не на WinAPI!!! Он пишет управляемый код. Пока это все преобразуешь в тот самый управляемый из неуправляемого, коим является вызов API-функции - потеряешь время (нет, не ты... Программа потеряет время). Еще раз: если б знать, что ТС будет использовать только 16 цветов - нет проблем, пусть мучается, пишет импорты ДЛЛ, ради того, чтоб программа выполнялась на секунду быстрее. И она БУДЕТ выполняться быстрее. Но если мне надо заполнить область градиентом (а по ходу это - именно то, что ему надо:
Цитата
Мне надо все отградуировать считая, что минимальная температура, это красный цвет, а максимальная это синий
) - то StretchBlt идет таким лесом - что ему даже не снилось. Откуда копировать-то прямоугольнички? А? Это тебе не нарисовать первый, а потом его отштамповать тысячу раз, это КАЖДЫЙ РАЗ НОВЫЙ ЦВЕТ!!!
> Еще раз: если б знать, что ТС будет использовать только 16 цветов
Какая разница, сколько.
> ради того, чтоб программа выполнялась на секунду быстрее
Вывод картинки в течение двух секунд - это дохрена.
> Откуда копировать-то прямоугольнички? А?
Как откуда. Из другого DC, само собой. А уж попиксельно вывести массив в DC, созданный через CreateDIBSection - это вообще простой цикл, выполняется очень быстро. Только делать это надо не через SetPixel, а через то самое "нельзя, но если очень хочется, то можно", которое ты так стремишься сделать "нельзя". Понимаешь, все запретные концепции хоть и мешают жить большую часть времени, но когда они становятся смертельно нужны, то приходится опускаться и до них. А терпеть 2-секундный вывод чисто ради принципов - это уже фанатизм.
Или ты подумал, что я для каждого прямоугольника отдельно StretchBlt вызываю? Я что, похож на идиота? Нет, я сначала рисую картинку из "прямоугольничков размером 1х1" (при помощи неприятных и грязных, но простых действий), а потом её растягиваю.
Знаешь, что? Свои фантазии оставь при себе. Я не собираюсь тут еще и за чужие слова отчитываться. Я здесь зарегистрировался под ником IUnknown, в статус через 10 секунд после регистрации записал, под каким ником я еще известен в сети. Ни от кого скрываться я и не думал (происхождение ника объяснить, или сам догадаешься? Если имел дело с интерфейсами - можешь и догадаться) Это понятно? Я надеюсь, к этому вопросу мы больше не будем возвращаться...
Цитата
Только делать это надо не через SetPixel, а через то самое "нельзя, но если очень хочется, то можно", которое ты так стремишься сделать "нельзя".
Работа у меня такая, что "нельзя" - это значит "нельзя". А если очень хочется, и делаешь "можно" - то потом это падает. Причем падает так, и тогда, что исправлять это приходится очень большой ценой. И все равно в итоге "нельзя" - оказывается "нельзя".
Цитата
Понимаешь, все запретные концепции хоть и мешают жить большую часть времени, но когда они становятся смертельно нужны, то приходится опускаться и до них.
Без комментариев. Почему - см. ниже.
Цитата
попиксельно вывести массив в DC, созданный через CreateDIBSection - это вообще простой цикл, выполняется очень быстро.
Быстро - когда неуправляемый код вызывается из неуправляемого же. А вызов unmanaged кода из managed - потеря производительности. В разы... Не забыл? Затраты на вызов могут перекрыть прирост производительности, ага. Было смертельно нужно? Ну, и получил тормоза при смешивании кодов... Чья концепция оказалась в выигрыше?
> А если очень хочется, и делаешь "можно" - то потом это падает.
Что же у вас тестирование не работает? А ничего, что в основе любого кода, если глубже ковырнуть, лежить то самое "нельзя". И первый компилятор писался на "нельзя", потому что другого не было. Так то паранойя не имеет смысла, можно много до чего дойти.
> Быстро - когда неуправляемый код вызывается из неуправляемого же. А вызов unmanaged кода из managed - потеря производительности. В разы... Не забыл? Затраты на вызов могут перекрыть прирост производительности, ага. Было смертельно нужно? Ну, и получил тормоза при смешивании кодов... Чья концепция оказалась в выигрыше?
Неужели в точканете всё так плохо? Наверняка там есть готовый класс для копирования массива в память БМП, который там хоть через unsafe{} работает, главное, что он есть и отлажен. Просто надо побольше использовать стандартных алгоритмов для всяких вещей типа растягивания картинки итд, иначе либо руками вычислять все адреса всех пикселей (для игр иногда балуюсь этим), либо тормозить с прямоугольниками.
В конце концов, специально для тех, кому страшно, можно для сравнения нарисовать маленькую картинку (с прямоугольниками 1х1) через тупой SetPixel, и растянуть её
Цитата((с))
готовым отлаженным средством, а не изобретать велосипед.
Я благодарен за такой интерес к этой теме,но после 4 или 5 поста я перестал понимать вообще что либо.
Цитата
Еще раз: если б знать, что ТС будет использовать только 16 цветов - нет проблем
Цвета будет всего 2 красный и синий,а все промежуточные цвета будут вычисляться. Если заглянуть в то,что давал преподаватель на делфи,то там это выглядело так.
Цитата
// коэффициент интенсивности текущего выводимого значения // Ckoef = 0 соответствует минимальному значению и красному цвету // Ckoef = 1 соответствует максимальному значению и синему цвету Ckoef := (U(i,j) - minU) / (maxU - minU); // Определение цвета // Первое слагаемое дает вклад оттенка красного (1 байт цвета) // второе слагаемое - оттенка синего (3 байт цвета) // 2 байт цвета (оттенки зеленого) при этом всегда остается нулевым col := Round($FF * (1-Ckoef)) + Round($FF * Ckoef)*$10000;
Собственно вопрос.Хоть я и не знаю делфи,но с данными коментариями я вполне понимаю, как это интерпретируется,но как это реализовать на с++ не совсем представляю,т.к. с графикой встречался весьма редко и не настолько "глубоко".
Цитата
Неужели в точканете всё так плохо?
Там может быть все и хорошо,но я к счастью, или к несчастью, не на нем пишу.
Чуешь, да, куда я клоню? Ширину и высоту 3 и 4 параметром. А не конечную точку. То есть, у тебя отрисовывалось не много маленьких прямоугольников, а много больших, причем постоянно увеличивающихся в размере. Итого, вот такой код:
float y = 0; for(int j = 0; j <= N; j++) { float x = h * Xkoef; for(int i = 1; i <= N; i++) { if ((i + j) % 2 == 1) { g.FillRectangle( hBrush, x, y, h * Xkoef, h * Ykoef); } else { g.FillRectangle( hBrush2, x, y, h * Xkoef, h * Ykoef); } x += h * Xkoef; } y += h * Ykoef; } }
работает на порядок быстрее...
Цитата
я к счастью, или к несчастью, не на нем пишу.
А на чем же ты пишешь? Graphics^, SolidBrush^, System::Object^, System::EventArgs^ - это что, по-твоему? WinAPI?
Да я сам чето тормознул,повелся на то,что преподаватель давал......
Цитата
А на чем же ты пишешь? Graphics^, SolidBrush^, System::Object^, System::EventArgs^ - это что, по-твоему? WinAPI?
Да я чуш сморозил,у меня почему то проассоциировалось с C#.net,сам незнаю почему.
Вопрос о том, как создать оттенок зная пропорции синего и красного, в силе. Я немного покопавшись нарыл такую вещицу ,как Color::FromArgb(R,G,B); при помощи которого в цикле создавать нужный мне цвет и закрашивать его. Что то в духе.
Спасибо за совет,сам бы врятли додумался Новую тему создавать не стал,так как немного мелочным посчитал проблему. У меня есть файл в котором лежит число(размерность матрицы),затем исходная матрица и преобразованная матрица(размерность одинаковая).Можно ли как то считать быстро ненужную мне исходную матрицу ,чтобы быстро приступить к нужной,или можно сразу как нибуть переместиться на нужную позицию,но как тогда вычислить где именно необходимая мне позиция.
Так же меня немного смутил такой момент,когда я записывал в файл,то делалось это достаточно просто.
Есть ли возможность как то через cin это провернуть. Ну или можно создать диалог с открытием файла и пойти через StreamReader. System::IO::StreamReader ^ myStream = gcnew System::IO::StreamReader(openFileDialog1->FileName); В общем незнаю что сделать....
void btnReadMatrixClick(object sender, EventArgs e) { openFileDialog1.ShowDialog(); TextReader sr = new System.IO.StreamReader(openFileDialog1.FileName); int Len = Convert.ToInt32(sr.ReadLine());
string s = sr.ReadToEnd(); string[] sArr = s.Split('\n');
int[,] iArr = new int [Len, Len];
// Вот, собственно, пропускаем первую часть, от 0 до Len - 1... for(int i = Len; i < sArr.Length; i++) { int j = 0; foreach(string st in sArr[i].Split(' ')) { iArr[i - Len, j++] = Convert.ToInt32(st); } } }
(VS у меня нету, так что код - на C#). Тестировал на небольших матрицах (элементы в строке разделены пробелами, но в принципе, Split принимает любой разделитель...) - все прекрасно работает.
Да и твой код я так в полной мере не понял. что значит "," в строчке int[,] iArr = new int [Len, Len]; Я пытался все исправить руководствуясь тем,что от меня требовал компилятор и с 15 ошибок сократил до 5,но все 5 выдаются как раз на этой строчке. Получилось так.
int Len = Convert::ToInt32(myStream->ReadLine()); String^ s = myStream->ReadToEnd(); array<String^>^ sArr = s->Split('\n');
int[,] iArr = new int [Len, Len];
// Вот, собственно, пропускаем первую часть, от 0 до Len - 1... for(int i = Len; i < sArr->Length; i++) { int j = 0; for each(String^ st in sArr[i]->Split(' ')) { iArr[i - Len, j++] = Convert::ToInt32(st); } }
Пришлось после всех String-оф понаставить "^",потому что компилятор писал.
Цитата
error C3149: 'System::String' : cannot use this type here without a top-level '^'
Как это будет работать я даже не знаю,потому,что оно даже не компилируется пока что. Ошибки на строке int[,] iArr = new int [Len, Len]; следующие
Цитата
error C2143: syntax error : missing ';' before '[' error C3409: empty attribute block is not allowed error C2143: syntax error : missing ']' before ',' error C2143: syntax error : missing ';' before ',' error C2065: 'iArr' : undeclared identifier
И наконец,для чего вообще нужен массив iArr,в него закидывается то что мне нужно,как я понял.