Найти точку, в зависимости от расположения курсора мыши

Добрый вечер, коллеги. Проблема следующая: есть 3Д модель, которую нужно вращать лицевой частью в зависимости от расположения мыши: вперёд, назад, влево, вправо. Чтобы вращать модель, функция возвращает точку, к которой будет повернута лицевая часть модели. На изображении показаны 4 зоны, при наведении мыши которых будет задано направление. Требуется написать функцию, которая будет определять две точки x и z, в зависимости от расположения курсора мыши в какой-либо зоне, т.е. если мышь расположена в верхней зоне, она должна вернуть точку с координатами x = 0, z = 1. Снизу мой рабочий кусок кода, но чувствую, что его можно сократить чуть ли не до одной строчки, но так как я не силён в математике, обращаюсь к вам. (Ответ принимаю на любом ЯП)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
protected getStrictPointerPosition(pointerPosition: Vector3): Vector3 { let directionX: number = 0; let directionZ: number = 0; let relPointerPositionX: number = pointerPosition.x - this.root.position.x; let relPointerPositionZ: number = pointerPosition.z - this.root.position.z; let absPointerPositionX: number = Math.abs(relPointerPositionX); let absPointerPositionZ: number = Math.abs(relPointerPositionZ); if (relPointerPositionX > 0 && relPointerPositionZ > 0) { if (absPointerPositionX >= absPointerPositionZ) { directionX = 1; } else { directionZ = 1; } } else if (relPointerPositionX 0 && relPointerPositionZ > 0) { if (absPointerPositionX >= absPointerPositionZ) { directionX = -1; } else { directionZ = 1; } } else if (relPointerPositionX 0 && relPointerPositionZ 0) { if (absPointerPositionX >= absPointerPositionZ) { directionX = -1; } else { directionZ = -1; } } else { if (absPointerPositionX >= absPointerPositionZ) { directionX = 1; } else { directionZ = -1; } } return new Vector3(this.root.position.x + directionX, this.root.position.y, this.root.position.z + directionZ); }
Python, корреляция и регрессия: часть 4
В заключении, мы подходим к одному из наиболее важных применений линейной регрессии: предсказанию. Мы натренировали модель способную предсказывать вес олимпийских пловцов при наличии данных об их росте, половой принадлежности и годе рождения.
9-кратный олимпийский чемпион по плаванию Марк Шпитц завоевал 7 золотых медалей на Олимпийских играх 1972 г. Он родился в 1950 г. и, согласно веб-страницы Википедии, имеет рост 183 см. и вес 73 кг. Посмотрим, что наша модель предсказывает в отношении его веса.
Наша множественная регрессионная модель требует предоставить эти значения в матричной форме. Каждый параметр нужно передать в том порядке, в котором модель усвоила признаки, чтобы применить правильный коэффициент. После смещения вектор признаков должен содержать рост, пол и год рождения в тех же единицах измерения, в которых модель была натренирована:

Матрица β содержит коэффициенты для каждого из этих признаков:

Предсказанием модели будет сумма произведений коэффициентов β и признаков x в каждой строке:

Поскольку матричное умножение производит каждый элемент в результате соответствующего сложения произведений строк и столбцов каждой матрицы, получение результата попросту сводится к перемножению транспонированной матрицы β с вектором xspitz.
Напомним, что размерность итоговой матрицы будет числом строк из первой матрицы и числом столбцов из второй матрицы:

Здесь β T x — это произведение матрицы размера 1 × n и матрицы размера n × 1. Результатом является матрица размера 1 × 1:

Исходный код вычислений очень прост:
def predict(coefs, x): '''функция предсказания''' return np.matmul(coefs, x.values)
def ex_3_29(): '''Вычисление ожидаемого веса спортсмена''' df = swimmer_data() df['бин_Пол'] = df['Пол'].map().astype(int) df['Год рождения'] = df['Дата рождения'].map(str_to_year) X = df[['Рост, см', 'бин_Пол', 'Год рождения']] X.insert(0, 'константа', 1.0) y = df['Вес'].apply(np.log) beta = linear_model(X, y) xspitz = pd.Series([1.0, 183, 1, 1950]) # параметры Марка Шпитца return np.exp( predict(beta, xspitz) )
84.20713139038605
Этот пример вернет число 84.21, которое соответствует ожидаемому весу 84.21 кг. Это намного тяжелее зарегистрированного веса Марка Шпитца 73 кг. Наша модель, похоже, не сработала как надо.
Интервал уверенности для конкретного предсказания
Ранее мы рассчитали интервалы уверенности для параметров популяции. Мы можем также построить интервал уверенности для отдельно взятого предсказания, именуемый интервалом предсказания, или интервалом изменений предсказанной величины. Интервал предсказания количественно определяет размер неопределенности в предсказании, предлагая минимальное и максимальное значение, между которыми истинное значение ожидаемо попадает с определенной вероятностью. Интервал предсказания для ŷ шире интервала уверенности для параметра популяции, такого как например, среднее значение μ. Это объясняется тем, что в интервале уверенности учитывается только неопределенность при оценке среднего значения, в то время как интервал предсказания также должен принимать в расчет дисперсию в y от среднего значения.
Линии интервала предсказания находятся дальше от оптимально подогнанной линии, чем линии интервала уверенности, и тем дальше, чем больше имеется точек данных. 95%-ый интервал предсказания – это площадь, в которую ожидаемо попадают 95% всех точек данных. В отличие от него, 95%-й интервал уверенности – это площадь, которая с 95%-й вероятностью содержит истинную линию регрессии.

Приведенный выше график показывает связь между внешним интервалом предсказания и внутренним интервалом уверенности. Мы можем вычислить интервал предсказания, используя следующую ниже формулу:

Здесь ŷp — это предсказание, плюс или минус интервал. Мы пользуемся t-распределением, где степень свободы равна n — p, т.е. размер выборки минус число параметров. Это та же самая формула, которая ранее применялась при вычислении F-тестов. Хотя указанная формула, возможно, пугает своей сложностью, она относительно прямолинейно транслируется в исходный код, показанный в следующем ниже примере, который вычисляет 95%-ый интервал предсказания.
def prediction_interval(x, y, xp): '''Вычисление интервала предсказания''' xtx = np.matmul(x.T, np.asarray(x)) xtxi = np.linalg.inv(xtx) xty = np.matmul(x.T, np.asarray(y)) coefs = linear_model(x, y) fitted = np.matmul(x, coefs) resid = y - fitted rss = resid.dot(resid) n = y.shape[0] # строки p = x.shape[1] # столбцы dfe = n - p mse = rss / dfe se_y = np.matmul(np.matmul(xp.T, xtxi), xp) t_stat = np.sqrt(mse * (1 + se_y)) # t-статистика intl = stats.t.ppf(0.975, dfe) * t_stat yp = np.matmul(coefs.T, xp) return np.array([yp - intl, yp + intl])
Поскольку t-статистика параметризуется степенью свободы ошибки, она принимает в расчет присутствующую в модели неопределенность.
Если вместо интервала предсказания потребуется рассчитать интервал уверенности для среднего значения, мы попросту можем опустить прибавление единицы к se_y при вычислении t-статистики t_stat .
Приведенный выше исходный код можно использовать для генерирования следующего ниже графика, который показывает, как интервал предсказания изменяется вместе со значением независимой переменной:

В приведенном выше графике модель тренируется на выборке из 5 элементов и показывает, как 95%-й интервал предсказания увеличивается по мере нашего движения дальше от среднего роста. Применив приведенную выше формулу к Марку Шпитцу, в результате получим следующее:
def ex_3_30(): '''Интервал предсказания применительно к данным о Марке Шпитце''' df = swimmer_data() df['бин_Пол'] = df['Пол'].map().astype(int) df['Год рождения'] = df['Дата рождения'].map(str_to_year) X = df[['Рост, см', 'бин_Пол', 'Год рождения']] X.insert(0, 'константа', 1.0) y = df['Вес'].apply(np.log) xspitz = pd.Series([1.0, 183, 1, 1950]) # данные М.Шпитца return np.exp( prediction_interval(X, y, xspitz) )
array([72.74964444, 97.46908087])
Этот пример возвращает диапазон между 72.7 и 97.4 кг., который как раз включает в себя вес Марка 73 кг., поэтому наше предсказание находится в пределах 95%-ого интервала предсказания. Правда оно лежит неудобно близко к границам диапазона.
Границы действия модели
Марк Шпитц родился в 1950 г., за несколько десятилетий до рождения самых возрастных пловцов на Олимпийских играх 2012 г. Пытаясь предсказать вес Марка, используя его год рождения, мы виноваты в том, что пытаемся экстраполировать слишком далеко за пределы наших тренировочных данных. Мы превысили границы действия нашей модели.
Есть и вторая причина, по которой этот результат сопряжен с проблемами. Наши данные полностью основаны на пловцах, которые соревнуются в наши дни на уровне международных стандартов, тогда как Марк не участвовал в соревнованиях уже много лет. Другими словами, Марк теперь не является частью популяции, на которой мы натренировали нашу модель. В целях исправления обеих этих проблем нам нужно поискать подробную информацию о Марке в 1979 г., когда он еще участвовал в соревнованиях по плаванию.
Согласно данным, в 1972 г. 22-летний Марк Шпитц имел рост 185 см. и весил 79 кг.
Отбор верных признаков — это одна из самых важных предпосылок для получения хороших результатов от любого алгоритма предсказания.
Следует отбирать признаки не только, опираясь на их предсказательную силу, но и на их актуальность для моделируемой области.
Окончательная модель
Хотя наша модель имеет чуть более низкий R 2 , давайте натренируем ее повторно, взяв в качестве признака возраст вместо года рождения. Это позволит нам легко предсказывать веса для прошлых и будущих ранее не встречавшихся данных, т.к. она ближе моделирует переменную, которая, как мы полагаем, имеет причинно-следственную связь с весом.
Модель произведет β приблизительно с такими значениями:

Наши признаки для Марка на играх 1972 г. таковы:

Эти признаки можно использовать для предсказания его соревновательного веса при помощи приведенного ниже примера:
def ex_3_32(): '''Окончательная модель для предсказания соревновательного веса''' df = swimmer_data() df['бин_Пол'] = df['Пол'].map().astype(int) X = df[['Рост, см', 'бин_Пол', 'Возраст']] X.insert(0, 'константа', 1.0) y = df['Вес'].apply(np.log) beta = linear_model(X, y) # предсказать вес Марка Шпитца xspitz = pd.Series([1.0, 185, 1, 22]) return np.exp( predict(beta, xspitz) )
78.46882772630318
Пример возвращает число 78.47, т.е. предсказывает вес 78.47 кг. Теперь результат находится очень близко к истинному соревновательному весу Марка, равному 79 кг.
Примеры исходного кода для этого поста находятся в моем репо на Github. Все исходные данные взяты в репозитории автора книги.
Резюме
В этой серии постов мы узнали о том, как определять наличие общей линейной связи между двумя и более переменными. Мы увидели, как выражать силу их корреляции при помощи корреляции Пирсона r и насколько хорошо линейная модель объясняет вариацию при помощи коэффициентов детерминации R 2 и R̅ 2 . Мы также выполнили проверку статистических гипотез и рассчитали интервалы уверенности, чтобы вывести диапазон истинного популяционного параметра ρ для корреляции.
Определив корреляцию между переменными, мы смогли построить предсказательную модель с использованием регрессии методом обычных наименьших квадратов и простых функций Python. Затем мы обобщили наш подход, воспользовавшись для этого матричной функциональностью библиотек pandas и numpy и нормальным уравнением. Эта простая модель продемонстрировала принципы машинного усвоения закономерностей путем определения модельных параметров β, извлеченных из выборочных данных, которые могут использоваться для выполнения предсказаний. Наша модель смогла предсказать ожидаемый вес нового атлета, который полностью попадал в пределы интервала предсказания для истинного значения.
- python
- программирование
- data science
- учебный процесс
- статистический анализ
- предсказание
- Python
- Программирование
- Data Mining
- Учебный процесс в IT
- Статистика в IT
Создаем 2D игру на Python с библиотекой Arcade
Мы продолжаем делится с вами интересными найденными вещами про питончик. Сегодня вот решили разобраться с 2D играми. Это, конечно, немного попроще, чем то, что проходят у нас на курсе «Разработчик Python», но не менее интересно это уж точно.
Python — выдающийся язык для начинающих изучать программирование. Он также идеально подходит тем, кто хочет “просто взять и сделать”, а не тратить кучу времени на шаблонный код. Arcade — библиотека Python для создания 2D игр, с низким порогом вхождения, но очень функциональная в опытных руках. В этом статье я объясню, как начать использовать Python и Arcade для программирования игр.
Я начал разрабатывать на Arcade после преподавания азов библиотеки PyGame студентам. Я очно преподавал PyGames в течение почти 10 лет, а также разработал ProgramArcadeGames.com для обучения онлайн. PyGames отличная, но в какой-то момент я понял, что устал тратить время на оправдание багов, которые никогда не фиксятся.
Меня беспокоило преподавание таких вещей, как событийный цикл, которым уже почти не пользовались. И был целый раздел, в котором я объяснял, почему y-координаты повернуты в противоположном направлении. PyGames обновлялась редко и базировалась на старой библиотеке SDL 1, а не чем-то более современном вроде OpenGL. На светлое будущее я не рассчитывал.
В моих мечтах была простая и мощная библиотека, которая бы использовала новые фичи Python 3, например, декораторы и тайп-хинтинг. Ей оказалась Arcade. Посмотрим, как начать ее использовать.

Установка
Arcade, как и многие другие пакеты, доступна на PyPi, а значит, можно установить Arcade при помощи команды pip (или pipenv). Если Python уже установлен, скорее всего можно просто открыть командную строку Windows и написать:
pip install arcade
А в Linux и MacOS:
pip3 install arcade
Для более детализированной инструкции по установке, почитайте документацию по установке Arcade.
Простой рисунок
Вы можете открыть окно и нарисовать простой рисунок всего несколькими строчками кода. В качестве примера, нарисуем смайлик, как на картинке ниже:

Скрипт ниже показывает, как это сделать, используя команды рисования Arcade. Заметьте, что вам не обязательно знать, как использовать классы или определять функции. Программирование с быстрым визуальным фидбеком — хороший старт для тех, кто только учится.
import arcade # Задать константы для размеров экрана SCREEN_WIDTH = 600 SCREEN_HEIGHT = 600 # Открыть окно. Задать заголовок и размеры окна (ширина и высота) arcade.open_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Drawing Example") # Задать белый цвет фона. # Для просмотра списка названий цветов прочитайте: # http://arcade.academy/arcade.color.html # Цвета также можно задавать в (красный, зеленый, синий) и # (красный, зеленый, синий, альфа) формате. arcade.set_background_color(arcade.color.WHITE) # Начать процесс рендера. Это нужно сделать до команд рисования arcade.start_render() # Нарисовать лицо x = 300 y = 300 radius = 200 arcade.draw_circle_filled(x, y, radius, arcade.color.YELLOW) # Нарисовать правый глаз x = 370 y = 350 radius = 20 arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK) # Нарисовать левый глаз x = 230 y = 350 radius = 20 arcade.draw_circle_filled(x, y, radius, arcade.color.BLACK) # Нарисовать улыбку x = 300 y = 280 width = 120 height = 100 start_angle = 190 end_angle = 350 arcade.draw_arc_outline(x, y, width, height, arcade.color.BLACK, start_angle, end_angle, 10) # Завершить рисование и показать результат arcade.finish_render() # Держать окно открытым до тех пор, пока пользователь не нажмет кнопку “закрыть” arcade.run()
Использование функций
Конечно, писать код в глобальном контексте — не лучший способ. К счастью, использование функций поможет улучшить ваш код. Ниже приведен пример того, как нарисовать елку в заданных координатах (x, y), используя функцию:
def draw_pine_tree(x, y): """ Эта функция рисует елку в указанном месте""" # Нарисовать треугольник поверх ствола. # Необходимы три x, y точки для рисования треугольника. arcade.draw_triangle_filled(x + 40, y, # Point 1 x, y - 100, # Point 2 x + 80, y - 100, # Point 3 arcade.color.DARK_GREEN) # Нарисовать ствол arcade.draw_lrtb_rectangle_filled(x + 30, x + 50, y - 100, y - 140, arcade.color.DARK_BROWN)
Для полного примера, посмотрите рисунок с функциями.

Более опытные программисты знают, что современные программы сначала загружают графическую информацию на видеокарту, а затем просят ее отрисовать batch-файлом. Arcade это поддерживает. Индивидуальная отрисовка 10000 прямоугольников занимает 0.8 секунды. Отрисовка того же количества батником займет менее 0.001 секунды.
Класс Window
Большие программы обычно базируются на классе Window или используют декораторы. Это позволяет программисту писать код, контролирующий отрисовку, обновление и обработку входных данных пользователя. Ниже приведен шаблон для программы с Window-основой.
import arcade SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 class MyGame(arcade.Window): """ Главный класс приложения. """ def __init__(self, width, height): super().__init__(width, height) arcade.set_background_color(arcade.color.AMAZON) def setup(self): # Настроить игру здесь pass def on_draw(self): """ Отрендерить этот экран. """ arcade.start_render() # Здесь код рисунка def update(self, delta_time): """ Здесь вся игровая логика и логика перемещения.""" pass def main(): game = MyGame(SCREEN_WIDTH, SCREEN_HEIGHT) game.setup() arcade.run() if __name__ == "__main__": main()
В классе Window есть несколько методов, которые ваши программы могут переопределять для обеспечения функциональности. Вот список тех, что используются чаще всего:
- on_draw: Весь код для отрисовки экрана находится здесь.
- update: Весь код для перемещения объектов и отработки игровой логики находится здесь. Вызывается примерно 60 раз в секунду.
- on_key_press: Обрабатывает события при нажатии кнопки, например, движение персонажа.
- on_key_release: Обрабатывает события при отпускании кнопки, например, остановка персонажа.
- on_mouse_motion: Вызывается каждый раз при движении мышки.
- on_mouse_press: Вызывается при нажатии кнопки мыши.
- set_viewport: Эта функция используется в скроллерах, когда мир значительно больше, чем то что видно на одном экране. Вызов set_viewport позволяет программисту задать ту часть экрана, которая будет видна.
Спрайты
Спрайты — простой способ создания 2D bitmap объектов в Arcade. В нем есть методы, позволяющие с легкостью рисовать, перемещать и анимировать спрайты. Также можно использовать спрайты для отслеживания коллизий между объектами.
Создание спрайта
Создать инстанс Sprite класса Arcade очень легко. Программисту необходимо только название файла изображения, на котором будет основываться спрайт, и, опционально, число раз для увеличения или уменьшения изображения. Например:
SPRITE_SCALING_COIN = 0.2 coin = arcade.Sprite("coin_01.png", SPRITE_SCALING_COIN)
Этот код создает спрайт, используя изображение coin_01.png. Картинка уменьшится до 20% от исходной.
Список спрайтов
Спрайты обычно организуются в списки. Они помогают упростить их управление. Спрайты в списке будут использовать OpenGl для групповой batch-отрисовки. Нижеприведенный код настраивает игру, где есть игрок и множество монет, которые игрок должен собрать. Мы используем два списка — один для игрока и один для монеток.
def setup(self): """ Настроить игру и инициализировать переменные. """ # Создать список спрайтов self.player_list = arcade.SpriteList() self.coin_list = arcade.SpriteList() # Счет self.score = 0 # Задать игрока и # Его изображение из kenney.nl self.player_sprite = arcade.Sprite("images/character.png", SPRITE_SCALING_PLAYER) self.player_sprite.center_x = 50 # Стартовая позиция self.player_sprite.center_y = 50 self.player_list.append(self.player_sprite) # Создать монетки for i in range(COIN_COUNT): # Создать инстанс монеток # и их изображение из kenney.nl coin = arcade.Sprite("images/coin_01.png", SPRITE_SCALING_COIN) # Задать положение монеток coin.center_x = random.randrange(SCREEN_WIDTH) coin.center_y = random.randrange(SCREEN_HEIGHT) # Добавить монетку к списку self.coin_list.append(coin)
Мы с легкостью можем отрисовать все монетки в списке монеток:
def on_draw(self): """ Нарисовать все """ arcade.start_render() self.coin_list.draw() self.player_list.draw()
Отслеживание коллизий спрайтов
Функция check_for_collision_with_list позволяет увидеть, если спрайт наталкивается на другой спрайт из списка. Используем ее, чтобы увидеть все монетки, с которыми пересекается спрайт игрока. Применив простой for- цикл, можно избавиться от монетки в игре и увеличить счет.
def update(self, delta_time): # Сгенерировать список всех спрайтов монеток, которые пересекаются с игроком. coins_hit_list = arcade.check_for_collision_with_list(self.player_sprite, self.coin_list) # Пройтись циклом через все пересекаемые спрайты, удаляя их и увеличивая счет. for coin in coins_hit_list: coin.kill() self.score += 1
С полным примером можно ознакомиться в collect_coins.py.
Игровая физика
Во многих играх есть физика в том или ином виде. Самые простое, например, что top-down игры не позволяют игроку проходить сквозь стены. Платформеры добавляют сложности с гравитацией и движущимися платформами. Некоторые игры используют полноценные физические 2D движки с массами, трением, пружинами и тд.
Top-down игры

Для простых игр с видом сверху программе на Arcade необходим список стен (или чего-то подобного), через которые игрок не сможет проходить. Обычно я называю это wall_list. Затем создается физический движок в установочном коде класса Window:
self.physics_engine = arcade.PhysicsEngineSimple(self.player_sprite, self.wall_list)
player_sprite получает вектор движения с двумя атрибутами change_x и change_y. Просто пример использования — перемещение игрока с помощью клавиатуры.
MOVEMENT_SPEED = 5 def on_key_press(self, key, modifiers): """Вызывается при нажатии пользователем клавиши""" if key == arcade.key.UP: self.player_sprite.change_y = MOVEMENT_SPEED elif key == arcade.key.DOWN: self.player_sprite.change_y = -MOVEMENT_SPEED elif key == arcade.key.LEFT: self.player_sprite.change_x = -MOVEMENT_SPEED elif key == arcade.key.RIGHT: self.player_sprite.change_x = MOVEMENT_SPEED def on_key_release(self, key, modifiers): """Вызывается, когда пользователь отпускает клавишу""" if key == arcade.key.UP or key == arcade.key.DOWN: self.player_sprite.change_y = 0 elif key == arcade.key.LEFT or key == arcade.key.RIGHT: self.player_sprite.change_x = 0
Несмотря на то что этот код задает скорость игрока, он его не перемещает. Метод update в классе Window вызывает physics_engine.update(), что заставит игрока двигаться, но не через стены.
def update(self, delta_time): """ Передвижение и игровая логика """ self.physics_engine.update()
Пример полностью можно посмотреть в sprite_move_walls.py.
Платформеры

Переход к платформеру с видом сбоку достаточно прост. Программисту необходимо переключить физический движок на PhysicsEnginePlatformer и добавить гравитационную константу.
self.physics_engine = arcade.PhysicsEnginePlatformer(self.player_sprite, self.wall_list, gravity_constant=GRAVITY)
Для добавления тайлов и блоков, из которых будет состоять уровень, можно использовать программу вроде Tiled.
Учитесь на примере
Учиться на примере — один из лучших методов. В библиотеке Arcade есть большой список образцов программ, на которые можно ориентироваться при создании игры. Эти примеры раскрывают концепты игр, о которых спрашивали мои онлайн и оффлайн студенты в течение нескольких лет.
Запускать демки при установленной Arcade совсем не сложно. В начале программы каждого примера есть комментарий с командой, которую нужно ввести в командную строку для запуска этого примера. Например:
python -m arcade.examples.sprite_moving_platforms
Как всегда ждём ваши комментарии и вопросы, которые можно оставить тут или зайти к Стасу на день открытых дверей.
Показать чувствительность мышки (DPI)
Как в Линуксе показать (или рассчитать) чувствительность мышки?
У меня следующая модель:
Bus 003 Device 008: ID 046d:c062 Logitech, Inc. M-UAS144 [LS1 Laser Mouse]
В сети я, к сожалению, не нашел инфу.
Хочу сравнить мышки по юзабилити в плане DPI.

forest22 ★
21.10.17 13:09:37 MSK
Попробуй что-нибудь из этого. Могу ошибаться.
/usr/sbin/hwinfo --mouse
xinput --list-props
sudo apt install python-pip sudo pip install rivalcfg rivalcfg -l
ult ★
( 21.10.17 13:41:34 MSK )
Ответ на: комментарий от ult 21.10.17 13:41:34 MSK

Пока без успеха.
forest22 ★
( 21.10.17 14:02:05 MSK ) автор топика

Знаю, как узнать/настроить refresh/polling rate в герцах: https://gitlab.com/iankelling/evhz. Задается через параметр ядра usbhid.mousepoll. Но это немного другое.
На счет DPI не знаю. Нужен специфический софт/драйвер для конкретной мыши. В системе оно задается обычно через настройки мыши с «ползунками» скорости, чувствительности и т.д.
Ну а если тебе просто надо:
Хочу сравнить мышки по юзабилити в плане DPI
то смотри в инете их технические характеристики. Как-то так.
Gonzo ★★★★★
( 21.10.17 16:28:37 MSK )
Ответ на: комментарий от ult 21.10.17 13:41:34 MSK

Он вроде только для SteelSeries Rival мышей, как razercfg — для Razer девайсов. Слишком специфично и вряд ли будет работать.
Gonzo ★★★★★
( 21.10.17 16:32:24 MSK )
Ответ на: комментарий от Gonzo 21.10.17 16:32:24 MSK

Именно на эту мышку (Logitech) не могу найти. Разные сведения. Пишут «5000» и «1100». Конечно, скорее 1100.