En Java, ¿cómo decidir si un punto está en el límite de un GeneralPath?

Descubrí que la GeneralPathclase en Java solo proporciona métodos para verificar si un punto está dentro de una ruta general (para ser específicos, un polígono con segmentos de línea recta ). ¿Alguien sabe cómo verificar eficientemente si un punto está en el límite de una ruta general o no?

Gracias

Solución ficticia 1: podemos definir un círculo con radio $ \ epsilon $ ($ \ epsilon $ es un valor real positivo muy pequeño). Y luego, verificamos un número suficiente de puntos en el círculo para ver si uno / algunos de ellos cae en la ruta general o no. Sin embargo, tal método ficticio puede requerir una cantidad considerable de esfuerzo computacional, lo cual no es muy deseable.

Solución ficticia 2: podemos calcular las distancias desde el punto (en el límite) a cada lado del polígono. Si la distancia mínima es suficientemente pequeña, este punto está en el límite; de lo contrario, no lo es. Nuevamente, este método aún puede ser computacionalmente intensivo.

Respuesta 1

No he encontrado un método de biblioteca ... o una solución en maceta para el problema. Creo que la razón es que el problema es fundamentalmente imposible de resolver con exactitud.

La GeneralPathclase hereda un método llamado getPathIteratordesde Shape2D. Si observa el javadoc, verá que el PathIteratorobjeto modela el camino como una secuencia de segmentos de línea recta. Y el getPathIteratormétodo toma un flatnessparámetro especificado de la siguiente manera:

"planitud: la distancia máxima que los segmentos de línea utilizados para aproximar los segmentos curvos pueden desviarse de cualquier punto de la curva original".

Ahora, si la forma que está viendo consiste en segmentos de línea recta, hay una buena posibilidad de que el iterador de ruta le dé esos segmentos de línea. Pero si la forma tiene segmentos curvos, entonces los segmentos de línea son solo una aproximación. Y es claramente imposible probar si un punto está exactamente en un límite si no sabe cuál es el límite exacto.

Incluso suponiendo que los segmentos de línea modelen exactamente la curva real, todavía tiene el problema de que (excepto en casos especiales), la mayoría de los puntos en la curva real no se pueden representar exactamente utilizando tipos de datos primitivos de Java (int, double, etc.). Entonces, una vez más, la "exactitud" es problemática.

Creo que lo mejor que puede esperar es probar si su punto está dentro de un pequeño delta del límite ... y elegir un flatnessvalor que sea menor que ese delta, iterar los segmentos de línea de ruta y probar la distancia tangencial del punto de cada segmento.

Nota: si lo hace flatnessmuy pequeño, puede esperar tener que probar una gran cantidad de segmentos de línea. No creo que haya alguna forma de evitar esta preocupación computacional mientras se adhiere a la API de GeneralPath.


Si restringe el problema a los polígonos verdaderos (es decir, de lados rectos), simplemente necesita iterar los segmentos de línea y, para cada prueba, ver si la distancia desde el punto a la línea es menor que alguna epsilon adecuada. Esta entrada de Wikipedia te da las matemáticas. Tenga en cuenta que la exactitud seguirá siendo una preocupación aquí ...

No tiene un cálculo enormemente costoso, pero calcular una raíz cuadrada precisa no es gratis, y tiene que hacerlo hasta N veces para un polígono de N lados.

Hacerlo mejor que eso (es decir, mejorarlo O(N)) será difícil. Sin embargo, si el polígono es fijo y va a probar una gran cantidad de puntos en su contra, entonces podría considerar usar una estructura de datos de cuatro árboles para calcular la resolución. La precomputación del quad-tree será costosa, pero si N es lo suficientemente grande, un punto de prueba será más barato. (Aproximadamente O(log(1/epsilon))en el peor de los casos, en lugar de O(N)en promedio. Y cuanto más lejos del límite es un punto, más barata es la respuesta).

Pero como dije, los árboles cuádruples solo ayudarán en situaciones limitadas ...

Respuesta: 2

Estoy tratando de configurar un servidor de aplicaciones para ejecutar un sitio web simple y una aplicación cliente Java que necesita comunicarse de nuevo con un servidor Java. Lo que me gustaría hacer es lo siguiente: sitio web / web ...

He reunido un programa simple que usa reemplazo de fragmentos con una sola actividad y dos fragmentos. Un fragmento tiene un botón que, cuando se presiona, reemplaza el fragmento con un segundo fragmento ...

En mi aplicación estoy usando un código como el siguiente para descargar varias imágenes. ¿Es de alto rendimiento hacerlo así o puedo reutilizar la conexión de alguna manera? for (int i = 0; i <100; i ++) {URL ...

Estoy atrapado con el siguiente problema. Digamos, tengo una solicitud que tiene 1000 elementos, y me gustaría utilizar Java Executor para resolver esto. Aquí está el método principal public static void main (String [] ...