Necesito compensar todos los triángulos (azules), cada uno independientemente de los demás, usando el sombreador de vértices. Para manipular el triángulo como un todo, he creado atributos personalizados (vec3) para cada vértice (rojo) que representa los vértices vecinos hacia la izquierda (púrpura) y hacia la derecha (verde). A partir de esto, necesito derivar el punto naranja, equidistante (en el espacio de la pantalla ) de ambos bordes adyacentes. Con tres de estos puntos naranjas derivados de cada triángulo, el triángulo procesado (naranja) se pasa al sombreador de fragmentos.
Idealmente, el triángulo se eliminará (como en el retroceso / no renderizado) si los desplazamientos niegan cualquier espacio disponible dentro del triángulo, como en el segundo triángulo en la segunda imagen.
Estoy usando THREE.BufferGeometry () como mi estructura de datos.
Aquí hay una captura de pantalla del efecto al que apunto:
Respuestas:
Dado el triángulo ▲ ABC, bisecamos el ángulo ∠BAC con la línea AD, derivada con el teorema de la bisectriz de ángulo :
BA / BD = CA / CD El punto E representa nuestra posición objetiva refinada en el triángulo de inserción resultante deseado. Como yace sobre la bisectriz de ángulo AD, es equidistante de los lados BA y CA, formando triángulos rectángulos idénticos ▲ AFE y ▲ EDAD. Ahora podemos usar Seno para triángulos rectángulos para encontrar la longitud de AE:
AE = EG / Sin (∠EAG)
¡Esas son todas las matemáticas que necesitamos, así que cocinemos un poco de GLSL!
Comenzamos con todos los atributos típicos: posición, normal y matrices de transformación, pero dado que el sombreador de vértices solo funciona en un solo vértice, necesitamos agregar los vértices vecinos como atributos adicionales. De esta manera, cada vértice encontrará su propio "punto E", creando el triángulo insertado resultante. (Nota: no los llamo "B" y "C" aquí, porque todavía no están en el espacio de la pantalla ).
Hablando del espacio de la pantalla, también incluyo la relación de aspecto de la pantalla (y la hago uniforme, en caso de que la ventana cambie de tamaño).
Después de preparar diferentes valores normales para el sombreador de fragmentos y de transformar la cara en un espacio de recorte, podemos dedicarnos al negocio de aplicar las matemáticas anteriores:
Este código nos da los resultados a continuación.
Tenga en cuenta que hay algunos casos extremos que tienen que ver con triángulos casi sin fondo que se voltean por este proceso, y comencé a abordar esto en código, pero decidí simplemente evitar estos casos por ahora. Quizás lo vuelva a visitar cuando termine este proyecto.
fuente
Esto se puede lograr sin funciones trigonométricas reduciendo la escala del triángulo.
incircle()
calcula el círculo del triángulo formado por los vérticesA,B,C
, devuelve centro y radio comovec4
. Los vérticesX=A,B,C
se mueven hacia adentro por la fracción de su distancia al centro del círculo (Q-X
), que es igual a la proporción del margen deseado al radio del círculo (m/Q.w
).fuente