2010-02-06 16 views

Respuesta

1

círculos son fácil, simplemente comprobar que la distancia desde el punto al centro del círculo es menor que el radio del círculo utilizando el Pythagorean theorem (ver también this question).

Los polígonos son more challenging. Ese artículo enlaza con el código C para hacerlo, que debe ser traducible a JavaScript.

10

Para el caso círculo que es muy fácil, sólo simplemente comprobar si la distancia desde el punto del centro es menor que (OEt) el radio:

function intersects(x, y, cx, cy, r) { 
    var dx = x-cx 
    var dy = y-cy 
    return dx*dx+dy*dy <= r*r 
} 

para el polígono, el más fácil es imaginar una línea que vaya directamente desde el punto. Si esta línea cruza un número impar de bordes poligonales, su punto está dentro del polígono. (Simplemente cruzaría un borde poligonal para un polígono convexo simple)

También es posible que pueda encontrar una biblioteca de geometría de un tercero, pero es probable que le tome más tiempo que codificarlo usted mismo.

22

Según lo sugerido por some other answers, seguí algunos enlaces y found the c code here. Aquí está la traducción de JavaScript para encontrar si un punto está en un polígono

Copyright (c) 1970-2003, Wm. Randolph Franklin

Se concede permiso, sin cargo, a cualquier persona que obtenga una copia de este software y archivos de documentación asociados (el "Software") para tratar el Software sin restricciones, incluyendo, entre otros, los derechos de uso , copiar, modificar, fusionar, publicar, distribuir, sublicenciar y/o vender copias del Software, y para permitir a las personas a las que se suministra el software para hacerlo, con sujeción a las siguientes condiciones:

  1. redistribuciones del El código fuente debe conservar el aviso de copyright anterior, esta lista de condiciones y las siguientes renuncias de responsabilidad.
  2. Las redistribuciones en formato binario deben reproducir el aviso de copyright anterior en la documentación y/u otros materiales proporcionados con la distribución.
  3. El nombre de W. Randolph Franklin no se puede utilizar para respaldar o promocionar productos derivados de este Software sin un permiso previo específico por escrito.

SOFTWARE se proporciona "tal cual", sin garantía de ningún tipo, expresa o implícita, incluyendo pero no limitado a las garantías de comerciabilidad, IDONEIDAD PARA UN FIN PARTICULAR Y NO. EN NINGÚN CASO LOS AUTORES O PROPIETARIOS DE DERECHOS DE AUTOR SERÁN RESPONSABLES DE NINGUNA RECLAMACIÓN, DAÑOS U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN CONTRACTUAL, EXTRACONTRACTUAL O DE OTRO TIPO, QUE SURJA DE, O RELACIONADA CON EL SOFTWARE O EL USO U OTRAS OFERTAS EN LA SOFTWARE.

function pnpoly(nvert, vertx, verty, testx, testy) { 
    var i, j, c = false; 
    for(i = 0, j = nvert-1; i < nvert; j = i++) { 
     if(((verty[i] > testy) != (verty[j] > testy)) && 
      (testx < (vertx[j] - vertx[i]) * (testy - verty[i])/(verty[j] - verty[i]) + vertx[i])) { 
       c = !c; 
     } 
    } 
    return c; 
} 

nvert - Número de vértices del polígono. Si se repite el primer vértice al final se analiza a continuación.
vertx, verty - Matrices que contienen las coordenadas xey de los vértices del polígono.
testx, testy - coordenada X e Y del punto de prueba.

+0

Muchas gracias por enviarme este ejemplo. Pero supongo que no está funcionando. ¿Puedes por favor probarlo y enviarme el código probado? También, por favor, hágamelo saber la significación del parámetro nvert – Dheeraj

+2

Funciona para mí. Si sigues mi enlace a la página donde encontré este código, hay una explicación completa de por qué las cosas se hacen como están y cómo usar esta función – meouw

+0

Hola otra vez ... Estoy haciendo algo como esto // Poly Start var myArray2x = new Array (90, 640, 70,50); // poli myArray2y x eje var = new Array (20, 25, 190,60) resultado = false resultado = pnpoly (myArray2x.length, myArray2x, myArray2y, mx, my) si (resultado == true) { \t alert ("Hace clic dentro del Polígono en x =" + mX + "y y =" + mY); \t \t \t } // poli Fin – Dheeraj

0

I montado un ejemplo con la función anterior: http://jsfiddle.net/jcspader/Vz6ka/

var gDrawingContext = $("canvas")[0].getContext("2d"); 


gDrawingContext.beginPath(); 
gDrawingContext.arc(50, 50, 10, 0, Math.PI*2, false); 
gDrawingContext.closePath(); 
gDrawingContext.strokeStyle = "red"; 
gDrawingContext.stroke(); 

gDrawingContext.beginPath(); 
gDrawingContext.arc(55, 55, 10, 0, Math.PI*2, false); 
gDrawingContext.closePath(); 
gDrawingContext.strokeStyle = "blue"; 
gDrawingContext.stroke(); 

function intersects(x, y, cx, cy, r) { 
    var dx = x-cx 
    var dy = y-cy 
    return dx*dx+dy*dy <= r*r 
} 
console.clear(); 
$("canvas").on("click", function (e){ 
    if (intersects(e.pageX, e.pageY, 55, 55, 10)) 
    console.info(e.pageX + ", " + e.pageY); 
}); 
2

me gustaría echar un vistazo al método isPointInPath.

Te requerirá trazar la ruta en un elemento 'lienzo', pero hay muchas posibilidades de que quieras hacerlo de todos modos para renderizarlo. Si no necesita representar su polígono en un lienzo, puede crear un elemento canvas invisible (créelo pero nunca lo agregue al DOM).

var canvas = document.getElementById('canvas'); // Or document.createElement('canvas'); 
var ctx = canvas.getContext('2d'); 
ctx.beginPath(); 
for (var i = 0; i < coords.length; i++) { 
    ctx.lineTo(coords[i].x, coords[i].y); 
} 
ctx.isPointInPath(50,50); 

Suponiendo que haya una gran variedad de objetos con coordenadas x e y en ellos el código anterior debe decirle si el punto (50, 50) se encuentra dentro de los límites de su forma.

+0

¿Es sensible esta opinión?Si cambio el tamaño de la ventana del navegador, ¿seguirá funcionando correctamente? – Mawg

+0

@Mawg no, esto opera en una matriz de coordenadas para la forma y un punto. No tiene relación con el diseño. –

+0

Hnmmmm ... crear una instantánea de cada ruta, capturar el tamaño de los eventos y escalar la ruta de copia en consecuencia, y cuando el usuario hace clic en X, Y, invoca 'isPointInPath()' en la copia escalada? Funcionaría eso? – Mawg

Cuestiones relacionadas