Отображение пикселей на данные - PullRequest
3 голосов
/ 11 августа 2010

Я написал несколько базовых графических программ на Clojure / Java, используя drawLine() в графическом контексте модифицированного JPanel.Сам график работает хорошо, но я зашел в тупик, пытаясь преобразовать нажатый пиксель в ближайшую точку данных.

У меня есть простая биекция между списком всех пикселей, которые отмечают конечные точки моих линий, и моими фактическими необработанными данными.Что мне нужно, так это обрезка из всех пикселей (скажем, 1200x600 px 2 ) моего окна графика в пиксели в моем списке пикселей, что дает мне тривиальное отображение из этого в мои действительные точки данных.

например,

<x,y>(px) ----> <~x,~y>(pixel points) ----> <x,y>(data)

Это ситуация, которую я себе представляю сейчас:

  • В главном окне графика щелкают пиксель,и MouseListener ловит это событие и дает мне <x,y> координаты действия.

  • Эта информация передается в функцию, которая возвращает предикат, который определяет, является ли значение, переданное ему, «достаточно ли хорошим», и фильтрует ли список с этим предопределением, и принимаетпервое значение, с которым все в порядке.

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

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

Это проблема решена , как показали другие графические библиотеки, но трудно найти информацию о ней, кроме как в источнике некоторых из этих программ, и должна бытьлучший способ, чем копаться в тысячах строк Java, чтобы выяснить это.

Я ищу лучшие решения или просто общие советы и рекомендации по тем, которые я предлагал, если это возможно.

Ответы [ 2 ]

1 голос
/ 11 августа 2010

Итак, я думаю, что-то вроде JFreeChart просто не подходит для вашего приложения? Если вы еще не пошли по этому пути, я бы посоветовал проверить его, прежде чем пытаться свернуть свой собственный.

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

0 голосов
/ 11 августа 2010

Я думаю, что ваш подход приличный. По сути, для этого требуется всего одна итерация массива данных, немного простых математических вычислений и никаких выделений на каждом шаге, поэтому это должно быть очень быстро.

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

Некоторые коды Clojure, которые могут помочь:

(defn squared-distance [x y point]
  (let [dx (- x (.x point))
        dy (- y (.y point))]
     (+ (* dx dx) (* dy dy))))

(defn closest 
  ([x y points]
    (let [v (first points)] 
      (closest x y (rest points) (squared-distance x y v) v)))
  ([x y points bestdist best]
    (if (empty? points)
      best
      (let [v (first points)
            dist (squared-distance x y v)] 
        (if (< dist bestdist)
          (recur x y (rest points) dist v)
          (recur x y (rest points) bestdist best))))))
...