2 votos

Ángulo de sujeción entre dos vectores

Estoy programando un juego tipo serpiente en 3 dimensiones sin restricciones de cuadrícula donde la ubicación del nuevo "bloque" está determinada por:

[Normalizado(últimaLocalizacióndelBloque - localizacióndelCursor) * longituddelBloque] + últimaLocalizacióndelBloque

donde las localizaciones son vectores 3D y blockLength es un escalar. Con este código, hago que la serpiente siga al jugador sin importar la distancia real; sin embargo, también me gustaría añadir un sistema para evitar ángulos demasiado pronunciados.

Entonces, esta es la pregunta: ¿cómo puedo sujetar un vector para que tenga un ángulo máximo n con un vector conocido?

3voto

amd Puntos 2503

Quieres que el ángulo $\beta$ por el que la serpiente cambia su rumbo para quedar en un ángulo fijo $\beta_\text{max}$ . Yo separaría la detección de la fijación de la nueva rúbrica.

Dejemos que $\mathbf u$ sea un vector unitario que apunta en la dirección actual y $\mathbf u_\text{cursor}={\mathbf r_\text{cursor}-\mathbf r\over\|\mathbf r_\text{cursor}-\mathbf r\|}$ un vector unitario en la dirección del cursor en relación con la última ubicación del bloque. Entonces el cambio de dirección es demasiado grande si $\mathbf u\cdot\mathbf u_\text{cursor}=\cos\beta\lt\cos{\beta_\text{max}}$ .

Si el cambio de ángulo es lo suficientemente pequeño, proceda como antes. Si no, hay que girar $\mathbf u$ por $\beta_\text{max}$ hacia el cursor. Hay varias formas de hacerlo, pero creo que la siguiente es una de las más eficientes. Calcular el rechazo ortogonal $\mathbf v_\perp=\mathbf u_\text{cursor}-(\mathbf u\cdot\mathbf u_\text{cursor})\mathbf u$ . Ya tienes este producto punto del paso anterior. Entonces, la nueva dirección fijada vendrá dada por el vector unitario $$\mathbf u_\text{clamped}=\cos\beta_\text{max}\mathbf u+\sin\beta_\text{max}{\mathbf v_\perp\over\|\mathbf v_\perp\|}.$$ El seno y el coseno de $\beta_\text{max}$ puede, por supuesto, calcularse previamente.

El caso $\mathbf u_\text{cursor}=-\mathbf u$ es decir, el cursor está directamente detrás de la serpiente, necesitará un manejo especial. Tendrás que elegir una dirección -en el sentido de las agujas del reloj o en sentido contrario- y un plano para el cambio de rumbo. [ Adición Una posibilidad es guardar la rúbrica anterior más reciente $\mathbf u_\text{prev}\ne\mathbf u$ y utilizar $-\mathbf u_\text{prev}$ en lugar de $\mathbf u_\text{cursor}$ para calcular el cambio de dirección de la abrazadera en este caso. Eso hará que la serpiente gire de manera consistente con su cambio de dirección más reciente.

0voto

He encontrado una forma de hacerlo que no es tan matemática, pero que da resultados bastante buenos. En lugar de comprobar si el cambio de dirección es demasiado grande, simplemente lerp entre mi dirección actual y la dirección de destino con esta fórmula:

Dirección = (DirecciónDelObjetivo - Dirección) / Velocidad

Para ver esta fórmula en acción, consulte http://www.somethinghitme.com/2013/11/13/snippets-i-always-forget-movement/ (el movimiento hacia un objeto con suavidad)

Esto no sólo evita que la serpiente gire demasiado o demasiado rápido; también hace que el movimiento sea mucho más fluido y agradable

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X