¿Cuál es la mejor manera de dibujar una línea de ancho variable sin usar glLineWidth? ¿Solo dibujar un rectángulo? ¿Varias líneas paralelas? ¿Ninguna de las anteriores?Dibujando una línea de ancho variable en OpenGL (Sin glLineWidth)
Respuesta
Suponga que sus puntos originales son (x1, y1) -> (x2, y2). Use los siguientes puntos (x1-width/2, y1), (x1 + width/2, y1), (x2-width/2, y2), (x2 + width/2, y2) para construir un rectángulo y luego use quads/tris para dibujarlo. Esta es la manera simple e ingenua. Tenga en cuenta que para anchos de línea grandes obtendrá un comportamiento de punto final extraño. Lo que realmente quiere hacer entonces son algunos cálculos inteligentes de líneas paralelas (que no deberían ser tan malos) utilizando vectores matemáticos. Por alguna razón, viene a la mente el producto punto/cruz y la proyección vectorial.
se puede dibujar dos triángulos:
// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1 and
// end thickness t2.
void DrawLine(float x1, float y1, float x2, float y2, float t1, float t2)
{
float angle = atan2(y2 - y1, x2 - x1);
float t2sina1 = t1/2 * sin(angle);
float t2cosa1 = t1/2 * cos(angle);
float t2sina2 = t2/2 * sin(angle);
float t2cosa2 = t2/2 * cos(angle);
glBegin(GL_TRIANGLES);
glVertex2f(x1 + t2sina1, y1 - t2cosa1);
glVertex2f(x2 + t2sina2, y2 - t2cosa2);
glVertex2f(x2 - t2sina2, y2 + t2cosa2);
glVertex2f(x2 - t2sina2, y2 + t2cosa2);
glVertex2f(x1 - t2sina1, y1 + t2cosa1);
glVertex2f(x1 + t2sina1, y1 - t2cosa1);
glEnd();
}
¡Esto es demasiado complicado! Demasiada trigonometría donde no es necesaria también. – PierreBdR
Resultó esto no es lo que quería el OP (véase su respuesta a continuación). Pero me gustaría ver un algoritmo más simple, si le importaría compartirlo. –
he añadido una versión libre trig aquí ahora – bobobobo
un rectángulo (es decir, dos o GL_QUAD GL_TRIANGLES) suena como su mejor apuesta por los sonidos de la misma, no está seguro de lo que puedo pensar en ninguna otra manera.
Ok, ¿qué tal esto: (Ozgar)
A /\ / \ . p1 \ / \ / D B - .p2 - - - C
Así AB es width1
y el CD es width2
.
Entonces,
// find line between p1 and p2
Vector p1p2 = p2 - p1 ;
// find a perpendicular
Vector perp = p1p2.perpendicular().normalize()
// Walk from p1 to A
Vector A = p1 + perp*(width1/2)
Vector B = p1 - perp*(width1/2)
Vector C = p2 - perp*(width2/2)
Vector D = p2 - perp*(width2/2)
// wind triangles
Triangle(A, B, D)
Triangle(B, D, C)
Nota hay potencialmente un problema CCW CW/bobinado con este algoritmo - si perp se calcula como (-y, x) en el diagrama anterior, entonces será devanado CCW, si (y, -x) entonces será un bobinado CW.
Otra forma de hacerlo, si está escribiendo un rasterizador de software por casualidad, es utilizar coordenadas baricéntricas en la etapa de coloración de píxeles y píxeles de color cuando una de las coordenadas baricéntricas está cerca de 0. Mientras más asignación hagas, más gruesas serán las líneas.
He tenido que hacer lo mismo hoy.
Para la creación de una línea que se extiende por (x1,y1) -> (x2,y2)
de un determinado width
, un método muy fácil es transformar un simple cuadrados unidad de tamaño que abarca (0., -0.5) -> (1., 0.5)
usando:
glTranslatef(...)
para moverlo a su(x1,y1)
ubicación deseada;glScalef(...)
para escalarlo a la derechalength
ywidth
deseado: utilicelength = sqrt((x2-x1)^2 + (y2-y1)^2)
o cualquier otra aproximación de baja complejidad;glRotatef(...)
aangle
a la orientación correcta: useangle = atan2(y2-y1, x2-x1)
.
La unidad-cuadrado se crea de forma muy simple a partir de una tira de dos triángulos GL_TRIANGLE_STRIP
, que se convierte en una línea continua después de las transformaciones anteriores.
La carga aquí se coloca principalmente en OpenGL (y su hardware de gráficos) en lugar de su código de aplicación. El procedimiento anterior se convierte fácilmente en una función genérica al rodear llamadas glPushMatrix()
y glPopMatrix()
.
Para los que vienen en busca de una buena solución a esto, este código se escribe utilizando LWJGL, pero puede adaptarse fácilmente a cualquier implementación de OpenGL.
import java.awt.Color;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
public static void DrawThickLine(int startScreenX, int startScreenY, int endScreenX, int endScreenY, Color color, float alpha, float width) {
Vector2f start = new Vector2f(startScreenX, startScreenY);
Vector2f end = new Vector2f(endScreenX, endScreenY);
float dx = startScreenX - endScreenX;
float dy = startScreenY - endScreenY;
Vector2f rightSide = new Vector2f(dy, -dx);
if (rightSide.length() > 0) {
rightSide.normalise();
rightSide.scale(width/2);
}
Vector2f leftSide = new Vector2f(-dy, dx);
if (leftSide.length() > 0) {
leftSide.normalise();
leftSide.scale(width/2);
}
Vector2f one = new Vector2f();
Vector2f.add(leftSide, start, one);
Vector2f two = new Vector2f();
Vector2f.add(rightSide, start, two);
Vector2f three = new Vector2f();
Vector2f.add(rightSide, end, three);
Vector2f four = new Vector2f();
Vector2f.add(leftSide, end, four);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha);
GL11.glVertex3f(one.x, one.y, 0);
GL11.glVertex3f(two.x, two.y, 0);
GL11.glVertex3f(three.x, three.y, 0);
GL11.glVertex3f(four.x, four.y, 0);
GL11.glColor4f(1, 1, 1, 1);
GL11.glEnd();
}
- 1. Ancho de línea OpenGL
- 2. OpenGL 3.2 Core Profile glLineWidth
- 3. Dibujando una esfera en OpenGL ES
- 4. Dibujando muchas esferas en OpenGL
- 5. Dibujando curvas de Hermite en OpenGL
- 6. Dibujando grandes cantidades de píxeles en OpenGL
- 7. Dibujando líneas con OpenGL en Haskell
- 8. Dibujando una línea en iPhone/iPad
- 9. Dibujando una línea con flecha en Java
- 10. Dibujando una pinza en forma sin bordes
- 11. Dibujando una ruta con una línea en OpenLayers usando JavaScript
- 12. Gráficos básicos: dibujando una línea en un ángulo
- 13. Lienzo HTML5 y ancho de línea
- 14. dibujando una línea en google maps perpendicular a dos puntos
- 15. Dibujando triángulo/flecha en una línea con CGContext
- 16. Código no está dibujando una línea horizontal en mi PDF
- 17. Dibujando una línea iso de un campo escalar implícito 2D
- 18. Dibujando una línea con un degradado de color
- 19. CSS: simulando ancho flexible (sin ancho mínimo) -
- 20. OpenGL sin una tarjeta gráfica
- 21. Dibujando mapas sin márgenes en R
- 22. Android dibujando una línea para seguir su dedo
- 23. css layout ancho fijo y ancho variable en la misma línea
- 24. Ancho de línea en raphaeljs
- 25. Dibujando el borde superior en una forma en Android
- 26. impresión variable en Python sin espacio ni salto de línea
- 27. Dibujando líneas con el algoritmo de línea de Bresenham
- 28. ggplot - Cambiar el ancho de línea
- 29. OpenGL sin X.org en Linux
- 30. Buscando tutoriales en línea OpenGL 3.1+
respuesta @Ozgur 's es mucho mejor. Considere agregar el vector matemático del que está hablando. – Valdrinit