• Почему не работает GetPixel?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    GetPixel принимает сначала x, потом y. У вас там Height и Width не в том порядке переданы.

    Это будет ошибкой, если одна из сторон более чем в 2 раза больше другой. Это может быть, если у вас широкоформатный монитор.

    У вас там битмап сохраняется в sceen2.png - оно там что-то сохранило вообще? Иначе проблема может быть не GetPixel, а с самим хБитмапом.

    Edit:

    Еще проблема может быть с масштабированием. В результате GetSystemMetrics(SM_CYSCREEN) возвращает не то, что вам надо и BitBlt не срабатывает из-за слишком большого размера.

    Попробуйте вызвать SetProcessDPIAware.

    Еще может быть проблема, что вы SelectObject делаете 2 раза с одним и тем же membit. Надо во второй раз что-то другое подставлять, чтобы HBitmap освободить. Иначе оно, похоже, так и остается привязано к DC.

    Вот мой рабочий код:
    HBITMAP GameManager::GetScreenshot(HWND window) {
    	HDC hScreenDC = GetDC(window);
    	HDC hMemoryDC = CreateCompatibleDC(hScreenDC);
    	RECT window_rect;
    	GetClientRect(window, &window_rect);
    	int width = window_rect.right - window_rect.left;
    	int height = window_rect.bottom - window_rect.top; 
    	int result_width = width;
    	int result_height = height;
    	
    	HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, result_width, result_height);
    	HBITMAP hOldBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hBitmap));
    	StretchBlt(hMemoryDC, 0, 0, result_width, result_height, hScreenDC, 0, 0, width, height, SRCCOPY);
    	hBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hOldBitmap));
    	DeleteDC(hMemoryDC);
    	DeleteDC(hScreenDC);
    	return hBitmap;
    }
    Ответ написан
    1 комментарий
  • Как растягивать прямоугольники до полного замощения области?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    Не знаю, насколько оптимальное решение это будет давать, но раздувайте прямоугольники по чуть-чуть.

    Пусть у прямоугольников будут степени свободы - верх,лево,низ,право. Изначально все прямоугольники раздуваются во все 4 стороны.

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

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

    Найдите минимальное время для всех пар. "Отмотайте" это время вперед - раздуйте все прямоугольники на это количество пикселей по всем активным степеням свободы. У двух пересекающихся отберите свободу раздуваться в направлениях, где они коснулись. Если они коснулись по углу, то у вас это будет событие: или они встретились по горизонтали, или по вертикали. Именно эти степени свободы и отбираете.

    Повторяйте пока есть хоть одна степень свободы где-то.

    Ну и еще надо учитывать пересечения с гарницей поля - точно так же. Считаете время до столкновения.

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

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

    Еще прикол, если прямоугольники пересекутся через пол тика - между ними всего один пиксель. Тут надо будет двигать только один из двух, скажем, с тот у кого номер меньше.

    В примере с картинки вы через 0 тиков зафиксируете, допустим, вертикальные границы и потом найдете. что через какое-то время один из прямоугольников упрется в стену. Раздуете оба прямоугольника, зафиксируете упершийся. Дальше, если все симметрично, то второй прямоугольник через 0 тиков тоже упрется в стену.

    Правда у этого метода есть проблема Например, вот такая картинка:
    AA.B
    ...B
    C...
    C.DD


    Тут прямоугольники можно чуть чуть раздуть до упирания, но при определенных пропорциях в центре останется пустое место, при чем все 4 окна будут сцеплены между собой. Не уменьшая изначальные окна его никак не убрать.
    Ответ написан
    Комментировать
  • Реализация лабиринта по алгоритму Уилсона. Как сделать это в C# WinForms?

    wataru
    @wataru Куратор тега Алгоритмы
    Разработчик на С++, экс-олимпиадник.
    В чем проблема перевести с lua на C#?

    Там в алгоритме ничего сверх сложного и какой-то встроенной библиотеки не используется. Понятно, что MazeGrid - это двумерный массив? Aux - это класс с методами createGrid (возвращает двумерный массив класса с полями visited, right_wall, bottom_wall), wilson (реализация алгоритма) и всякие вспомогателные hashKey/deHashKey. Еще есть поля width/height/sx/sy.

    Сам алгоритм в wilson() использует циклы while и for, if, elseif - все это переводится на C# не задействуя мозг вообще. Чисто механически. Ну, разве что о типах переменных чуть чуть подумать придется. Но, ясно же, что dir - это строка, isMoved - bool.

    Потом, когда вы это все переведете, можно начинать улучшать код. Типа вместо строк для направлений использовать enum.
    Ответ написан
    Комментировать
  • Вычислить исходные величины на основе измерений с погрешностью - как называется и решается такая задача?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Это называется кластеризация.

    Восстановить точное значение вы никогда не сможете, но можно взять среднее в каждом кластере. Такими измерениями занимается статистика
    Ответ написан
    Комментировать
  • Можно так сделать с interface?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    По уму, вам надо продумать ваш интерфейс. И тогда подобных извращений не понадобится. Дабавьте туда какой-нибудь способ для итерации по структуре данных для вывода. Или вообще сделайте метод ToString, который бы возвращал строковое представление внутренней структуры для вывода. Это все, естественно, виртуальные публичные методы, переопределенные в двух реализациях.

    То же и со вводом. Если надо как-то во внутренности очереди залезать и обычными push это не сделать, то, например, передавайте в метод CreateFromData() вектор введенных пользователем значений.
    Ответ написан
    Комментировать
  • Почему скалярное произведение не нормализованных и коллинеарных векторов разное при изменении их точек?

    wataru
    @wataru Куратор тега Математика
    Разработчик на С++, экс-олимпиадник.
    Ну, скалярное произведение вектора самого на себя - даст квадрат его длины по определению (|a|*|a|*cos(0)). Если менять точки - меняется длина вектора - меняется скалярное произведение.
    Ответ написан
    Комментировать
  • Как сделать какую-нибудь многозадачность на ардуино?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно поменять логику. Включили мотор и постоянно меряете расстояние. Как домеряли до 35см - остановились.

    Можно перед циклом один раз померять - решить, а надо ли вообще мотор включать. Внутри, чтоб электричество зря не жечь, можно даже между вычислениями расстояния сколько-то спать. Смотрите там из расстояния - если оно сильно больше 35 - спите подольше.
    Ответ написан
    2 комментария
  • Почему автодополнение не предлагает мне поля структуры?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы хотите вернуть T. У Node - это член Data. Вот и возвращайте _node->data, или какой там у вас смысл у _node. Пока странно, вы наследуетесь от Array, но никак его не используете. По идее надо возвращать первый элемент в массиве.

    Да, еще, по английски правильно capaCity, а не capaSity.
    Ответ написан
  • Импликация (следование) в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Нету в C++ отдельных операторов для этих логических функций. Потому что их все можно составить из И, ИЛИ и НЕ.

    Так, импликация - это !a || b. Эквивалентность - можно просто сравнить 2 переменные: a == b.
    Ответ написан
    1 комментарий
  • Как можно перебирать слова в C++?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Раз у вас во вводе коды каждого символа разделены пробелами, то все просто. Заведите в программе map<wstring, wchar> и где-то в начале напишите 33 строчки вида:
    dict[L"•−"] = L'А';

    Потом входную строку разбейте на части по проблелам. Руками, циклом. Указатель-индекс будет указывать на первый необработанный символ. Найдите первый пробел или конец строки начиная с этой позиции. Кусок между двумя позициями - это текущий код. Его с помощью map'а выше переводите в символ. Сдвигайте индекс первого необработанного символа на позицию после пробела. Ну и аккуратно смотрите, если первый необработанный - пробел, то это пробел между словами - его как есть и выводите, сдвигая индекс необработанного символа на 1.
    Ответ написан
  • Почему не вызывается конструктор копирования при инициализации переменной другим объектом?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Тут сработало copy elision.

    operator& не создает никакого временного Query, а работает сразу с Query в месте его вызова. Поэтому конструктор в пункте 8 создает уже результат.
    Ответ написан
    Комментировать
  • Что делать с этой проблемой?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Исходник в кодировке utf. 'А' действительно занимает 2 байта. Что видит компилятор? Видит 2 байта между кавычками и ругается.

    setlocale() - эта функция во время исполнения программы настроит, в какой кодировке у вас будет просиходить ввод/вывод с консоли. На кодировку исходника оно никак не влияет.

    Тут 2 варианта решения: Или поменяйте кодировку исходника и настройки локали, чтобы 'А' занимало один байт, или работайте с wstring.

    Чтобы не путаться с кодировками, напишите программу, которая выводит численное значение байт прочитанной строки. Запустите ее, введите туда 'А', смотрите, что оно выводит. Поэксперементируйте с разными настройками setlocale(). Если выводит 2 байта - вот эти два байта надо писать в case и использовать wstring. Если выводит один байт, вот его в case и вставляйте.
    Ответ написан
  • Почему выдает ошибку при наследовании?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Для решения этой проблемы по уму надо написать вот это в определении производного класса:
    using Array<T>::_size;
    using Array<T>::_capasity;
    using Array<T>::_data;


    Ответ на вопрос "почему" в С++ всегда один: "потому что стандарт":
    Non-dependent names are looked up and bound at the point of template definition. This binding holds even if at the point of template instantiation there is a better match:


    Проблема в том, что Array зависит от T, а вот его член _size от T не зависит. Ну вот не ищет компилятор независимые имена в зависимых местах. Независимые имена разрешаются в месте определения шаблона, когда еще неясно даже, с каким оно типом будет работать-то. Поэтому он никак до Array достучатся не может, ведь никакого T конкретного у него еще нет.

    Надо как-то компилятору указать, где искать вот эти ваши _size и т.д.
    Например, через this-> или через using или через Array<T>::.

    Вообще от этих правил lookup-а в C++ волосы дыбом встают и куча приколов вылезает. Их надо только запомнить. Оно неинтуитивно, но таково оно есть.
    Ответ написан
    Комментировать
  • Почему внутри шаблона можно иметь доступ к приватному члену внутреннего класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    С чего вы взяли, что внутри шаблона это работет? Вы его инстанциировать пробовали (объявить переменную класса Outer<int>, например)?

    Вылезает точно такая же ошибка.

    Если шаблон просто написать, но не использовать его, то он компилироваться и не будет и ошибки в нем не обнаружатся.
    Ответ написан
    1 комментарий
  • Как решить ошибку Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Переведите текст ошибки на русский. У вас выход за границу массива. Запустите код в отладчике - он остановится в том месте, где это происходит.

    Возможно файл map.txt лежит не там, программа его не находит и не может его прочитать. Получается пустой массив file, но в функции GetMaxLengthOfLine идет обращение к 0-вому элементу, а его нет.

    Или строки в файле разной длины, тогда при присваивании map[x, y] = file[y][x]; идет выход за границу массива file[y] в не самой длинной строке. Ведь x проходится до длины самой длинной строки.
    Ответ написан
    1 комментарий
  • Как проверить эфективность линейного и бинарного поиска в простом методе сортировки?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Эффективность поиска заключается в количестве срав-
    нений, произведенных определённым методом.


    Ну так подсчитайте количество сравнений. Напишите эти два поиска, заведите счетчики. Во всех местах, где у вас сравнение элементов происходит, увеличивайте счетчик. Выведите их в конце.
    Ответ написан
    Комментировать
  • Почему типы из заголовка cstdint доступны без его включения?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам повезло. Какой-то из включаемых вами других хедеров уже включает cstdint. Поскольку система инклудов в C++ идет еще из C и это дикое и неудобное легаси (текст хедера тупо вставляется в файл вместо include препроцессором), то такое рекурсивное включение работает.

    Но это плохая практика - стоит включать все, что вы используете всегда. Потому что потом вы что-то поменяете, исключив какой-то уже не нужный вам хедер отсюда, или из другого хедера, и у вас вылезет ошибка о неопределенных типах из cstdint.
    Ответ написан
    Комментировать
  • Какую роль играют float и double в скобках?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Такая запись имени типа в скобках в выражении - это явное приведение типа. Тут вы указываете компилятору, что выражение надо преобразовать вот к такому вот типу (флоат, в данном случае).

    float нужен вам в начале, потому что вещественные константы имеют тип double. Поэтому у eps/2.0 и 1.0 в первом цикле имеют тип double, все вычесляется в double. Преобразовав одно из выражений в float вы получаете то, что вам надо. Без этого все вычисления идут в double и ответ находится не тот. На самом деле там float при сравнении все-равно расширяется до double но на результат сравнения это не влияет в данном случае.

    Еще, вместо явного приведения типов, можно поставить f после вещественных констант, чтобы указать компилятору, что это float:
    while (1 + eps/2.0f != 1.0f){

    Тогда вычисления будут во float и ответ будет правильный.

    Во втором цикле double вам не нужен. Ведь вычисления итак идут в этом типе. Да и написано у вас там с опечаткой, вы к типу double приводите все выражение со сравнением. т.е. вы булево значение преобразуете в дабл. Потом оно назад в булево преобразуется при проверке условия циклом. В итоге это бесполезное действие.
    Ответ написан
    Комментировать
  • Крестики-нолики.Проблемы с ходом Х?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас там бесконечный цикл, который читает ход Х. Без единого break внутри - поэтому нет даже теоретической возможности, что вы из него выйдите.

    Упростите код: эти 9 if else условий заменяются на такой код:
    if (us.length() != 2) {
      cout << "?????" << endl;
      continue;
    }
    int row = us[0]-'A';
    int col = us[1]-'0';
    if (row < 0 || row > 2 || col < 0 || col > 2) {
      cout << "????" << endl;
      continue;
    }
    if (pole[row][col] != '_') {
      cout  << "занято" << endl;
      continue;
    }
    pole[row][col] = 'X';
    break;
    Ответ написан
    Комментировать
  • Как эффективно составить гистограмму слов (big data)?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если реализовывать самостоятельно, то самый эффективный вариант - использовать структуру бор. Правда, тут надо чтобы все файлы влезли в память.

    Десятки гигабайт - это не тот объем где стоит использовать распределенную ферму. Вы копируя файлы туда-сюда больше времени потратите, чем на обработку на одной машине.

    Если памяти на компьютере не 64-128гб, и писать что-то не хочется, то можно файл отсортировать и потом подсчитать там повторения за один проход. Это будет чуть медленнее теоретически оптимального решения. rPman уже привел линуксовую команду, которая это делает. Только разбивать на части просто так нельзя, надо чтобы одинаковые строки остались вместе, иначе собирать ответ с нескольких кусков надо будет хитро. Но это и не надо в вашей задаче.

    Если же вы что-то распределенное все-таки хотите использовать, то ваша задача - это фактически обучающий пример для всяких map-reduce фреймворков типа hadoop. Но там придется повозиться с установкой и настройкой этого добра и код с примера скопировать.
    Ответ написан
    8 комментариев