¿Cómo puedo hacer un algoritmo que detecte si un punto (x, y) se intercepta con una línea? (x1, y1, x2, y2)?
Ya he probado:
boolean onLine(float a, float b, float c, float d, float x, float y){ boolean answer = false; float[] p1 = new float[] {a, b}; float[] p2 = new float[] {c, d}; float x_spacing = (p2[0] - p1[0]) / ((a+c)/2 + (b+d)); float y_spacing = (p2[1] - p1[1]) / ((a+c)/2 + (b+d)); List<float[]> line = new ArrayList(); float currentX = 0; float currentY = 0; while(currentX+a<c&¤tY+b<d){ currentX += x_spacing; currentY += y_spacing; line.add(new float[]{a+currentX, b+currentY}); } for(int j = 0; j < line.size(); j++){ if(x > line.get(j)[0]-x_spacing && x < line.get(j)[0]+x_spacing && y > line.get(j)[1]- y_spacing && y < line.get(j)[1]+y_spacing){ answer = true; println("Hit line!"); break; } } return answer;}
Esto funciona a veces, pero no siempre es consistente.
Estoy poniendo esto con un juego de física, y lo necesito para que la pelota pueda rodar por una línea.
¿Cuáles son algunas formas en que puedo mejorarlo para que funcione?
EDITAR: Gracias a Felix Castor lo hice funcionar. Aquí está el código final:
boolean onLine(float x1, float y1, float x2, float y2, float xt, float yt, float wid, float hit){ float Y = (y2 - y1)/(x2 - x1)* xt + y1 -(y2 - y1)/(x2 - x1) * x1; boolean answer = false; if(abs(Y - yt) < 5) answer = true; if(abs(Y - yt-hit) < 5) answer = true; if(abs(Y - yt-(hit/2)) < 5) answer = true; if(abs(Y - yt+hit) < 5) answer = true; if(abs(Y - yt+(hit/2)) < 5) answer = true; return answer;}
Usando el formulario de intercepción de la pendiente, puede conectar su x y ver si las y son iguales.
y = m*x + b
m = (y2 - y1)/(x2 - x1)
b = y1 - (y2 - y1)/(x2 - x1) * x1
Entonces la ecuación se convierte en
Y = (y2 - y1)/(x2 - x1)* X + y1 -(y2 - y1)/(x2 - x1) * x1
dado un punto (xt, yt) puede conectar xt a X y evaluar y luego comparar el resultado con yt. Si son iguales, entonces el punto está en la línea.
si Y == yt dada xt entonces el punto está en la línea.
Deberá manejar el caso en el que tiene líneas estrictamente horizontales como casos de borde. Esos harán explotar la ecuación.
Como desea determinar qué tan lejos de la línea está un punto, diría que la fórmula para la distancia entre un punto y una línea en el espacio cartesiano sería el camino a seguir. Consulte la sección Distancia de un punto a una línea Línea definida por dos puntos . La fórmula se ve fea pero es sencilla.
double numerator = Math.abs((y2 - y1) * xt - (x2 - x1) * yt + x2 * y1 - y2 * x1); double denominator = Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)); double distance = numerator / denominator;Como antes, su punto de prueba es (xt, yt) y su línea está definida por dos puntos (x1, y1) y (x2, y2). Debido a que la distancia siempre es> = 0, su prueba sería:
if( distance <= tolerance) return trueCreo que este es un mejor enfoque si está interesado en una tolerancia.