Взаимодействие с пользователем при обработке
У меня есть общий вопрос (я знаю, что должен представить конкретный код с проблемой, но в моем случае проблема носит более общий характер).
Допустим, в процессе обработки я делаю эллипс:
ellipse(30, 30, 10, 10);
Теперь, есть ли способ получить пиксели, где этот эллипс находится на холсте? Причина заключается в том, чтобы иметь способ создания взаимодействия пользователя с мышью (например). Поэтому, когда кто-то щелкает мышью по эллипсу, что-то происходит.
Я думал о том, чтобы превратить все в объекты и использовать конструктор, чтобы каким-то образом сохранить положение фигуры, но это легче сказать, чем сделать, особенно для более сложных форм. И это то, что меня интересует. Одно дело вычислить положение эллипса, но как насчет более сложных форм? Есть ли библиотеки?
3 ответа
Проверьте геомеративную библиотеку. У него есть способ проверить, находится ли мышь внутри какой-либо формы SVG. Я не могу вспомнить с макушки головы, но это работает так, будто вы делаете форму:
myShape = RG.loadShape("shape.svg");
и точка:
RPoint p = new RPoint(mouseX, mouseY);
и булева функция содержит () скажет вам, находится ли точка внутри формы:
myShape.contains(p);
Лучше использовать математическую формулу, чем попиксельную проверку положения мыши (это намного быстрее и требует меньше кода).
Для идеального круга вы можете рассчитать евклидово расстояние, используя теорему Пифагора. Предположим, что ваш круг центрирован в позиции (circleX
,circleY
) и имеет радиус (не диаметр) circleR
, Вы можете проверить, находится ли мышь над кругом, вот так:
if(sq(mouseX-circleX)+sq(mouseY-circleY) <= sq(circleR)) {
// mouse is over circle
} else {
// mouse is not over circle
}
Этот подход в основном представляет собой прямоугольный треугольник, в котором гипотенуза (самая длинная сторона) проходит от центра круга к положению мыши. Он использует теорему Пифагора для расчета длины этого гипотенузы, и если он меньше радиуса круга, то мышь находится внутри круга. (Он включает в себя небольшую оптимизацию - он сравнивает квадраты, чтобы избежать корня квадратного, поскольку это может быть сравнительно медленно.)
Альтернатива моему первоначальному математическому ответу также пришла мне в голову. Если вы можете позволить себе использовать память и вычислительную мощность для прорисовки всех элементов пользовательского интерфейса дважды, вы можете получить хорошие результаты, используя вторичный буфер.
Принцип предполагает наличие внеэкранного графического буфера (например, с использованием PGraphics). Он должен быть точно такого же размера, что и основной дисплей, и сглаживание должно быть отключено. Нарисуйте все ваши интерактивные элементы пользовательского интерфейса (кнопки и т. Д.) В этот буфер. Однако вместо того, чтобы рисовать их обычным способом, присвойте каждому уникальный цвет, который он использует для заливки и обводки (не добавляйте текст или изображения... только сплошные цвета). Например, одна кнопка может быть полностью красной, а другая - полностью зеленой. Любое другое значение RGB работает, если каждый элемент имеет уникальный цвет. Убедитесь, что фон имеет уникальный цвет.
Пользователь никогда не видит этот буфер, поэтому не рисуйте его на экране (если только вы не отлаживаете что-то). Если вы хотите определить, над каким элементом мыши находится курсор, просто найдите положение мыши в этом закадровом буфере. Получите цвет пикселя в этом месте и сопоставьте его с элементом пользовательского интерфейса.
После того, как вы все это сделали, просто начните рисовать все на главном экране в обычном режиме.
Стоит отметить, что вы можете значительно сократить время обработки этого подхода, если ваши элементы пользовательского интерфейса никогда (или редко) не перемещаются. Вам нужно перерисовать вторичный буфер только тогда, когда что-то появляется / исчезает, оживляет или изменяет размер / положение.