2011-10-21 14 views
11

Estoy tratando de trazar una línea entre dos puntos (2D) cuando el usuario pasa el dedo por una pantalla táctil. Para hacer esto, planeo dibujar un rectángulo en cada actualización táctil entre la X y la Y de la actualización táctil anterior y las X e Y de la última actualización táctil. Esto debería crear una línea continua y sólida a medida que el usuario pasa el dedo por la pantalla. Sin embargo, también me gustaría que esta línea tenga un ancho arbitrario. Mi pregunta es, ¿cómo debo hacer para calcular las coordenadas que necesito para cada rectángulo (x1, y1, x2, y2)?Rectángulo de dibujo entre dos puntos con ancho arbitrario

-

También: si alguien tiene alguna información sobre cómo podría entonces ir sobre la aplicación de anti-aliasing a esta línea sería una ayuda masiva.

+2

Estoy confundido, entonces usted tiene la parte superior izquierda (x1, y1) y la inferior derecha (x2, y2) y necesita crear un rectángulo con esos puntos? ¿Las coordenadas no serían simplemente [(x1, y1), (x2, y1), (x1, y2), (x2, y2)]? – Danny

+0

Toda la información con la que tengo que trabajar es la ubicación anterior de dónde estaba el dedo del usuario en la pantalla y la última ubicación. Necesito trazar una línea entre los dos, con un ancho arbitrario. Tenga en cuenta que el rectángulo también debe estar centrado. No es tan simple como crees. Esta espantosa ilustración podría ayudar o no. [link] (http://dl.dropbox.com/u/17610534/picutre.png) (tenga en cuenta que la segunda coordenada en el rectángulo superior debería ser de 150,50, pero espero que comprenda a qué me refiero) – AaronDS

+0

¿Por qué piensas usar rectángulos? ¿Por qué no segmentos de línea gruesos? – datenwolf

Respuesta

18

Calcula un vector entre los puntos de inicio y fin

V.X := Point2.X - Point1.X; 
V.Y := Point2.Y - Point1.Y; 

luego calcular una perpendicular a ella (sólo cambio coordenadas X e Y)

P.X := V.Y; //Use separate variable otherwise you overwrite X coordinate here 
P.Y := -V.X; //Flip the sign of either the X or Y (edit by adam.wulf) 

Normalizar que perpendicular

Length = sqrt(P.X * P.X + P.Y * P.Y); //Thats length of perpendicular 
N.X = P.X/Length; 
N.Y = P.Y/Length; //Now N is normalized perpendicular 

Calcule 4 puntos que forman un rectángulo agregando perpendicular normalizado y múltiple ying it por la mitad del ancho deseado

R1.X := Point1.X + N.X * Width/2; 
R1.Y := Point1.Y + N.Y * Width/2; 
R2.X := Point1.X - N.X * Width/2; 
R2.Y := Point1.Y - N.Y * Width/2; 
R3.X := Point2.X + N.X * Width/2; 
R3.Y := Point2.Y + N.Y * Width/2; 
R4.X := Point2.X - N.X * Width/2; 
R4.Y := Point2.Y - N.Y * Width/2; 

Dibuja un rectángulo con estos 4 puntos.

Aquí está la foto:

Drawing rectangle between two points

EDIT: Para responder a los comentarios: Si X e Y son iguales entonces la línea es exactamente perpendicular a la diagonal y una diagonal es una diagonal. La normalización es un método para hacer que una longitud sea igual a 1, de modo que el ancho de su línea en este ejemplo no dependerá de la longitud de las perpendiculares (que es igual a la longitud de las líneas aquí).

+1

@Krom Stern Por favor elabore el 'Draw rectangle usando estos 4 puntos. Su respuesta es genial, pero estoy confundido al determinar el tamaño del rectángulo por estos 4 puntos. Súplica ayuda. Gracias. –

+0

@SalmanKhakwani: No estoy seguro de cómo puedo explicarlo aún más simple. ¿Qué es exactamente lo que te confunde? – Kromster

+0

Estoy siguiendo la pregunta http://stackoverflow.com/questions/18229683/resize-line-from-endpoints, y su respuesta parece muy adecuada para esta pregunta. ¿Puede por favor responder esa pregunta, será muy útil para mí :) –

0

Si le entiendo correctamente, tiene dos puntos finales que dicen A (x1, y1) y B (x2, y2) y un ancho arbitrario para el rectángulo dicen w. Supongo que los puntos finales estarán justo en el medio de los lados más cortos del rectángulo, lo que significa que la distancia de las coordenadas de la esquina final de los rectángulos sería w/2 a A y B.

Puede calcular la pendiente de la línea;

s1 = (y2 - y1) /! (X2 - x1) // suponiendo x1 = x2

La pendiente de los lados más cortos no es sino s2 = -1/s1.

Tenemos pendiente, tenemos distancia y tenemos los puntos de referencia.

Tenemos que pueden derivar dos ecuaciones para cada punto de la esquina:

Para una esquina cerca de un

C (x3, y3):

(y3 - y1)/(x3 - x1) = s2 // by pendiente

(y3 - y1)^2 + (x3 - x1)^2 = (w/2)^2 // por distancia

reemplazar (y3 - y1) por una y (x3 - x1) por b produce

a = b * s2 // pendiente ecuación

// sustituir una por b * s2

b^2 * s2^2 + b^2 = (w/2)^2 // distancia equaiton

b^2 = (w/2)^2/(s2^2 + 1)

b = sqrt ((w/2)^2/(s2^2 + 1))

sabemos w y s2 y, por tanto, calcular b

Si se conoce b, podemos deducir x3

x3 = b + x1

y una, así

a = b * s2

y así y3

y3 = b * s2 + y1

tenemos un punto de esquina C (x3, y3).

para calcular el otro punto de la esquina más cerca de A, dicen D (x4, y4), la ecuación de la pendiente puede ser construido como

(y1 - y4)/(x1 - x4) = s2 y los cálculos enumerados arriba deben ser aplicados.

Se pueden calcular otras dos esquinas con los pasos enumerados aquí reemplazando A (x1, y1) con B (x2, y2).

+0

Muchas gracias por su respuesta, realmente lo aprecio. Trabajaré en esto ahora. – AaronDS

4

manera fácil (que llamaré el "ancho", el grosor de la línea):

tenemos que calcular los valores 2, el cambio en el eje X y el turno en el eje y para cada una de las 4 esquinas. Lo cual es bastante fácil.

Las dimensiones de la línea son:

width = x2 - x1 

height = y2 - y1 

Ahora el x turno (vamos a llamarlo xS):

xS = (thickness * height/length of line)/2 

yS = (thickness * width/length of line)/2 

para encontrar la longitud de la línea, utilice el teorema de Pitágoras:

length = square_root(width * width + height * height) 

Ahora tiene el desplazamiento xy el desplazamiento y.

First coordinate is: (x1 - xS, y1 + yS) 

Second: (x1 + xS, y1 - yS) 

Third: (x2 + xS, y2 - yS) 

Fourth: (x2 - xS, y2 + yS) 

Y listo! (Esas coordenadas se dibujan en sentido contrario a las agujas del reloj, por defecto para OpenGL)

+0

Muchas gracias, realmente agradezco la ayuda! – AaronDS

+0

me parece que es más fácil de entender. mientras que yo no entiendo la respuesta más votado. –

Cuestiones relacionadas