Pregunta

He escrito algunos software de gráficos básica en Clojure / Java utilizando drawLine() en el contexto gráfico de un JPanel modificado. El trazado en sí está funcionando muy bien, pero he llegado a un punto muerto al intentar convertir un píxel pulsado hasta el punto de datos más cercano.

Tengo una biyección simple entre la lista de todos los píxeles que marca los puntos finales de mis líneas y mis datos brutos reales. Lo que necesito es un surjection de todos los píxeles (por ejemplo, 1200x600 píxeles 2 ) de la ventana gráfica para los píxeles en mi lista de píxeles, y me dio un mapeo trivial de que a mis puntos de datos reales.

por ejemplo.

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

Esta es la situación que yo estoy imaginando ahora:

  • Un píxel se hace clic en la ventana principal gráfico y la MouseListener atrapa ese evento y me da las coordenadas <x,y> de la acción.

  • Esa información se pasa a una función que devuelve un predicado que determina si es o no un valor que se le pasa es "suficientemente bueno", y el filtro aunque la lista con la pred, y toman el primer valor se aprueba.

    • Es posible que, en lugar de un predicado, que devuelve una función que se pasa a la lista de los píxeles puntos, y devuelve una lista de tuplas (x index) que indican qué bueno el punto es la magnitud de x, y donde ese punto es con index. Me gustaría hacer esto con ambos los puntos X y los puntos y. entonces el filtro aunque eso y encontrar el uno con el máximo x, y tomar que uno sea el punto de que es más probable que sea el que el usuario quería decir.

¿Son estas soluciones razonables a este problema? Parece que la solución que implica clasificaciones de confianza (distancia de pix-PT, tal vez) puede ser demasiado pesada procesador, la memoria y una pesada poco si me estoy conteniendo todos los puntos en la memoria de nuevo. La otra solución, utilizando sólo el predicado, no parece que siempre sería preciso.

Este es un resuelto problema, ya que otras librerías gráficas han demostrado, pero es difícil encontrar información sobre él con excepción de la fuente de algunos de estos programas, y no tiene que haber una manera mejor luego a excavar a través de los miles de líneas de Java para averiguar esto.

Estoy buscando mejores soluciones, o simplemente punteros y consejos generales sobre los que yo he ofrecido, si es posible.

¿Fue útil?

Solución

Así que supongo algo así como JFreeChart simplemente no se corte para su aplicación? Si no ha ido por ese camino, sin embargo, me gustaría sugerir echarle un vistazo antes de intentar rodar su propia cuenta.

De todos modos, si estás buscando el punto a un evento de ratón más cercana, conseguir el punto con el mínimo distancia euclídea (si está por debajo de cierto umbral) y la presentación que dará el comportamiento más predecible para el usuario. El inconveniente es que la distancia euclidiana es relativamente lento para grandes conjuntos de datos. Puede utilizar trucos como ignorar la raíz cuadrada o BSP árboles para acelerarlo un poco. Pero si esas optimizaciones son incluso necesario realmente depende de la cantidad de puntos de datos que está trabajando. Perfil una solución un tanto ingenua en un caso típico antes de entrar en el modo de optimización.

Otros consejos

Creo que su enfoque es decente. Básicamente, esto sólo requiere una iteración a través de su matriz de datos, un poco de matemáticas simples y no hay asignaciones a cada paso por lo que debe ser muy rápido.

Es probable que sea tan bueno como se va a conseguir a menos que empiece a usar algún tipo de esquema de partición espacial como un árbol de cuatro ramas, lo que en realidad sólo tiene sentido si la matriz de datos es muy grande.

Algunos código Clojure que puede ayudar a:

(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))))))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top