Quiero dibujar un camino invisible que el usuario debe seguir. He almacenado ese camino como puntos. Cuando un jugador dibuja una línea, ¿cómo puedo probar si sigue la ruta que he almacenado?
Aquí hay un ejemplo para rastrear la letra A.
if((traitSprite.getX()<=Invisible.X && traitSprite.getX()>=Invisible.X )){...}
( traitSprite
es un sprite)
libgdx
algorithm
vector
hand-drawn
Androide
fuente
fuente
Respuestas:
Aquí hay una solución basada en vectores. No lo he probado, pero parece estar bien conceptualmente.
Teoría
Supongo que has almacenado la forma como segmentos de línea. Aquí está la letra A representada con tres segmentos de línea.
Supuse que las rutas en el dibujo del usuario se almacenan como listas de puntos.
Podemos "inflar" esos segmentos de línea para permitir un margen de error al verificar la proximidad : si la ruta dibujada del usuario está cerca del margen de error de las líneas correctas.
Sin embargo, eso solo no es suficiente. También tenemos que verificar la cobertura : si el dibujo del usuario "cubre" una gran fracción de la forma. Estos dibujos son malos, porque a pesar de que se ajustan al margen de error, les falta parte de la letra:
Si verificamos ambas cosas, podemos aproximarnos si el dibujo del jugador es bueno.
Implementación
Verificar la cercanía solo significa para cada punto de ruta del usuario, encontrar la distancia entre esa y cada línea que forma la letra, tomar la más baja y verificar que sea menor que el margen de error.
Verificar la cobertura es más complicado, pero puede obtener una muy buena aproximación con las matemáticas vectoriales si para cada segmento de línea, encuentra la ruta dibujada por el usuario más cercana (verde) y proyecta sus partes (verde oscuro) en ese segmento de línea (negro), luego verifique qué tan bien lo cubren los vectores proyectados (azul):
Para proyectar un vector
a
sobre otro vectorb
, hagadonde
dotProduct
calcula el producto punto de los dos vectores ylengthSquared
es lo que parece. Básicamente, esto encuentra el valor escalar de cuántoa
va enb
la dirección y se multiplicab
por eso para obtener un vector en la misma dirección. (El tutorial de detección de colisión de Metanet Software A tiene una buena visualización de esto en el Apéndice A § proyección ).La dirección del vector proyectado podría no ser realmente importante. Si solo suma las longitudes de los vectores proyectados y los compara con la longitud total del segmento de línea, eso le indicará qué fracción está cubierta. (Excepto en casos extraños, ver § Limitaciones a continuación).
En la imagen de arriba, la ruta cubriría aproximadamente la mitad del segmento. Puede elegir cualquier valor de tolerancia que desee.
Limitaciones
Letras curvas
Los segmentos de línea son sub ideal: ¡muchas letras son curvas! ¿Cómo se representa una 'P' o una 'O'?
Podría usar muchos segmentos de línea (tal vez con un margen de error mayor).
También podría comenzar a usar curvas de Bézier en lugar de líneas para un ajuste más cercano, pero tenga en cuenta que encontrar el punto más cercano en un Bézier es mucho más complejo, al igual que muchas otras operaciones de medición.
Desajustes
Los márgenes de tolerancia demasiado relajados para la distancia de las líneas y la cobertura de la carta podrían tener consecuencias no deseadas.
Por ejemplo, el jugador podría haber estado tratando de dibujar una 'H' aquí.
Bucles y superposiciones
Los bucles o superposiciones en la ruta dibujada por el jugador pueden hacer que algunas partes del dibujo se cuenten dos veces al proyectarlas en el segmento de línea más cercano.
Esto podría solucionarse haciendo un procesamiento más elegante en los vectores proyectados, tal vez almacenando exactamente dónde estaría el vector proyectado (almacene también la dirección de la proyección y el punto más cercano en el segmento de línea al punto en la línea dibujada por el jugador) , luego rechaza los nuevos que se superponen.
Si el jugador dibujó un solo camino y se procesó comenzando en el extremo marcado con el círculo azul, las partes verdes de ese camino serían aceptadas y las rojas rechazadas, porque su proyección se superpondría con algunas partes procesadas anteriormente.
La implementación tiene muchas sutilezas técnicas que probablemente pertenecerían a una pregunta diferente.
Jugadores aventureros impredecibles
Un jugador puede dibujar algo extraño que todavía pasa .
¡Aunque podrías llamar a eso una característica! :)
fuente
tl; dr Sugiero hacer que la pintura con pincel de los jugadores sea un plano 2D visible (o invisible). Difunde la imagen pintada de los usuarios con el origen (la silueta deseada o el modelo 2D). Si desea aumentar la precisión, haga que las líneas de guía y el pincel sean más estrechas, para permitir más margen de error, haga que el pincel y el diseño sean más gruesos.
De lo contrario, podría medir la distancia de cada (x, y) en la que los usuarios hacen clic / tocan desde la spline calculando la distancia punto a segmento. Luego puede promediar las distancias para componer una medida de precisión y eficiencia. Se requerirá más trabajo para obtener una medida significativa de finalización y darse cuenta de la eficacia del desempeño del usuario.
Consideración: sugiero no hacerlo (comprobar directamente si una línea sigue una ruta). Posiblemente sea una mala idea. Parece que quieres que el usuario rellene una silueta. El camino en sí es una spline (esquelética) que representa la silueta.
Si simplemente hace que el pincel de los jugadores aplique una masa monocromática pulposa de píxeles al plano 2D, puede ejecutar un proceso en segundo plano que verifique cuántos píxeles hay dentro de la silueta y cuántos de ellos están afuera. Esto puede resultar fácilmente en un% de éxito, donde la cantidad de% del patrón es una estadística de interés y otra es la cantidad de porcentaje que está fuera de los límites del modelo. Si verifica las distancias del subsegmento, no está muy claro si el trabajo de los usuarios es exacto.
fuente
La mejor solución es no usar gráficos, ¡hazlo con las matemáticas!
Puede comprender fácilmente cuánto cada punto (pintado por el usuario) está lejos del segmento /programming/849211/shortest-distance-between-a-point-and-a-line-segment
Que puede calcular el error promedio, así que mida cuánto usuario está correcto.
fuente