elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.  (Leído 11,263 veces)
Tachikomaia


Desconectado Desconectado

Mensajes: 1.210


Superhacker (es broma xD )


Ver Perfil
Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« en: 18 Noviembre 2022, 09:06 am »

1- Su velocidad de caída aumenta 0.01 por segundo (segundo es un decir, es más bien una centésima de segundo).

2- Sus velocidades hacia los costados (X), adelante (Y, arriba) y arriba (Z, distancia con respecto al suelo) deben ser acordes a la fuerza del jugador que realiza el tiro. La velocidad hacia abajo aumentará, pero me refiero a las velocidades iniciales. Si por ejemplo tiene fuerza 4 y aplicó 3 para que la pelota avance 3 pixeles (es un decir) por segundo entonces no puede ser que la pelota se eleve 2 pixeles por segundo, ya que la fuerza que queda disponible es sólo 1.

3- Cuando llega a la red la Z de la pelota debe ser igual o mayor a cierto valor, es decir, se debe preestablecer un valor que represente la mínima Z con la que la pelota pasa por encima de la red sin tocarla, y cuando llegue a la red debe tener ese valor o uno mayor. En mi caso es 17.5 pero elijan el que gusten.

4- Debe caer en la cancha rival.

5- Las velocidades deben ser tales que la pelota caiga en cierto punto. Por ejemplo:


6- Su velocidad hacia adelante (Y) debe ser la máxima posible.


Es decir, se intenta que se cumpla una condición en tanto eso no cause que no se cumplan las otras.
3- Se quiere que la pelota pase por encima de la red, pero sin que ello implique que haya caído más/menos de lo que debe (condición 1) ni que se le haya aplicado más fuerza de la que se estableció como posible (condición 2). Si el jugador no tiene suficiente fuerza como para que se cumpla esta condición, no se cumple.
4- La oración anterior.
5- Lo mismo. Si para cumplir las condiciones anteriores es necesario que el tiro no vaya tan diagonal como se quiere, entonces no irá tan así, irá más bien verticalmente.
6- En tanto se cumplan las condiciones anteriores... Si la fuerza es 10 la velocidad Y no debe ser mayor que eso. Si queriendo asignar determinada fuerza a Y luego sin importar cuánta se asigne a Z la pelota no pasa la red o no cae en la cancha rival, entonces habrá que reducir la velocidad Y...


Por si los necesitan o quieren, les dejo los datos del caso (pero pueden inventar otros, lo que sí debe tenerse en cuenta es que no necesito simplemente averiguar 3 numeritos basados en otros, sino un método para averiguarlos teniendo en cuenta que los otros pueden variar, por ejemplo se puede elegir hacer un saque hacia al medio o puede que el personaje tenga distinta fuerza):
NOTA: Ignoren lo de "_level0."
  Variable _level0.AlexFuerza = 10
  Variable _level0.BallX = 417
  Variable _level0.BallY = 548
  Variable _level0.BallZ = 43.8
  Variable _level0.DistanciahastaDestinoX = 136.9
  Variable _level0.DistanciahastaDestinoY = 368
  Variable _level0.DistanciahastaRed = 248
  Variable _level0.DistanciahastaMinsafeBallZ = 26.3


Gracias.

Ah: El incremento de Y está invertido, es decir, entre más abajo más valor.
0,0________600,0
0,800______600,800


« Última modificación: 18 Noviembre 2022, 09:52 am por Tachikomaia » En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #1 en: 22 Noviembre 2022, 04:23 am »

Esto se resuelve con cálculo de parábolas. Si entiendo bien, lo que quieres hacer es averiguar cuánta "fuerza" en x y en y debes ejercer para que la pelota caiga en un punto específico (y obviamente, que pase la red) ¿no?

Si es así, para resolverlo solo necesitas un poco de matemáticas, y en particular de trigonometría, pero nada demasiado complicado. No es una solución de cortar y pegar en tu código, pero no debería ser difícil implementarla y en su caso, tomarla como base para adaptarla. De todas formas, pongo en negrita los cálculos que necesitas hacer en tu programa. El resto son más bien explicaciones breves.

En tu mensaje no indicas que la pelota pueda hacer curva en el eje x, así que no hay necesidad de complicarte usando 3 dimensiones al hacer los cálculos, cuando en realidad es un problema de sólo 2 dimensiones. Por lo tanto, para calcular la parábola solo hay que usar los ejes (x, y). La forma de visualizar la curva que forma la pelota es esta:




El trayecto que recorre depende de la velocidad inicial, (lo que llamas fuerza), de su ángulo, y de la gravedad (lo que llamas "velocidad" de caída). Recalco lo de velocidad inicial, puesto que la fuerza es otra cosa y no se relaciona directamente con la velocidad. En tu programa la puedes seguir llamando fuerza sin problemas, pero aquí usaremos el término adecuado. También hay que aclarar que no se distribuye de la manera en que piensas, así que esto:

Citar
Si por ejemplo tiene fuerza 4 y aplicó 3 para que la pelota avance 3 pixeles (es un decir) por segundo entonces no puede ser que la pelota se eleve 2 pixeles por segundo, ya que la fuerza que queda disponible es sólo 1.

no es correcto. Si la velocidad inicial total (v0) es 4, y 3 "se van" a la velocidad inicial en x (vx), entonces la velocidad en y (vy) no es de solo 1 pixel/seg, sino aproximadamente 2.64.  Esto es porque la velocidad total no es igual a la suma de las velocidades horizontal y vertical. En realidad, v0 es exactamente igual a la hipotenusa de un triángulo cuyos catetos son vx y vy. O sea:

v0 = raiz(vx2 + vy2).

Si sustituyes v0 por 4, y vx por 3, comprobarás que vy = raiz(7) o alrededor de 2.64.

Lo que determina dónde caerá la pelota y cómo se distribuirá v0 en vx y vy, es el ángulo inicial. Calculándolo, obtienes vx y vy con las ecuaciones que pongo más adelante.

Aclarado todo lo anterior, las ecuaciones para calcular las coordenadas (x, y) de la pelota en cada instante del trayecto son:

1) x = v0 * cos(θ) * t
2) y = v0 * sen(θ) * t - (g * t2)/2

donde θ es el ángulo, g es la gravedad, t es el tiempo (que de momento no interesa, pero servirá más adelante), y ya sabes que v0 es la velocidad inicial total.

Para resolver tu problema, y hacerlo en 2D, primero debes calcular la distancia total (que llamaremos x) hasta el punto destino:

x =  raiz(DistanciahastaDestinoX2 +  DistanciahastaDestinoY2)

Luego tienes que determinar, dada v0, cuál es el ángulo que permite que la pelota alcance el destino. Para esto puedes aplicar la fórmula del rango (v0, como habíamos dicho, es el valor de AlexFuerza):

R = (v02 * sen(2θ))/g

donde R representaría la distancia total en x que se recorre antes de caer al suelo. Como este valor ya lo conocemos (lo calculamos en el paso anterior), podemos despejar para calcular el ángulo:

θ = arcsen(g * R / v02)/2

Ojo: si la distancia a recorrer es muy larga y tenemos poca "fuerza", puede darse el caso de que sea imposible alcanzar el destino. Si quieres verificarlo, asegúrate de que g * R / (v02) sea mayor o igual a -1 y menor o igual a 1, de lo contrario es imposible llegar, sin importar el ángulo. También aclaro que para simplificar he hecho algunas suposiciones basándome en tu mensaje (por ejemplo, no especificas si hay variaciones en la altura inicial), pero igualmente creo que te serviría de manera general.

Una vez conocido el ángulo, podemos calcular vx y vy:

vx = v0 * cos(θ)
vy = v0 * sen(θ)


que es lo que buscabas. Sin embargo, todavía falta verificar si con ese tiro libramos la red. Para eso hay que calcular la distancia hacia la red siguiendo la trayectoria de la pelota, pues aunque la posición de la red sea fija, en cada tiro, si cambia la posición inicial de la pelota y/o el destino, la distancia hacia la red también cambiará. La forma de hacerlo es calculando las coordenadas donde la línea del trayecto de la pelota intersecta la línea formada por la red. Veo que tienes la variable DistanciahastaRed, aunque no sé si la calculas con cada tiro, pero suponiendo que sea correcta, lo que sigue es calcular la altura de la pelota en el momento t en el que pasa por la red. Para esto usamos las ecuaciones de la parábola que te puse al inicio. La primera servirá para calcular t:

t = x/(v0 * cos(θ))
en tu caso: t = DistanciahastaRed/(v0 * cos(θ))

Una vez obtenida t, la sustituyes en esta ecuación para calcular la altura:

y = v0 * sen(θ) * t - (g * t2)/2

Ya sólo queda verificar que y > altura de la red. Si no es así, significa que no tienes suficiente fuerza para hacer ese tiro.


Editado con algunas correcciones y aclaraciones.


« Última modificación: 23 Noviembre 2022, 01:16 am por RayR » En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.210


Superhacker (es broma xD )


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #2 en: 23 Noviembre 2022, 10:51 am »

Esto se resuelve con cálculo de parábolas. Si entiendo bien, lo que quieres hacer es averiguar cuánta "fuerza" en x y en y debes ejercer para que la pelota caiga en un punto específico (y obviamente, que pase la red) ¿no?
Y en z.

Citar
En tu mensaje no indicas que la pelota pueda hacer curva en el eje x
¿Como sucede aquí:
https://www.youtube.com/watch?v=yDIWBPwzi_0
?
Por ahora no.

Citar
no hay necesidad de complicarte usando 3 dimensiones al hacer los cálculos, cuando en realidad es un problema de sólo 2 dimensiones
Pero son 3 velocidades a calcular...

Citar
El trayecto que recorre depende de la velocidad inicial, (lo que llamas fuerza), de su ángulo, y de la gravedad (lo que llamas "velocidad" de caída). Recalco lo de velocidad inicial, puesto que la fuerza es otra cosa y no se relaciona directamente con la velocidad. En tu programa la puedes seguir llamando fuerza sin problemas, pero aquí usaremos el término adecuado.
¿Me puedes dar más info?

Citar
También hay que aclarar que no se distribuye de la manera en que piensas
Más o menos lo tengo claro sí, hace años un profesor de matemática me dijo que yo estaba contando mal, usando el método del taxista, me explicó y más o menos entendí.
Lo que dije fue simplificando.

Citar
la velocidad total no es igual a la suma de las velocidades horizontal y vertical
¿Tampoco en caso de que se dedique el 100% a una velocidad sola?

Citar
g es la gravedad
Por las dudas: Mi "simulación" de la gravedad funciona así:
https://foro.rinconmatematico.com/index.php?topic=51754.msg205838#msg205838
¿Es como en la realidad? ¿cómo es en la realidad?

Citar
Ojo: si la distancia a recorrer es muy larga y tenemos poca "fuerza", puede darse el caso de que sea imposible alcanzar el destino.
Lo tenía en cuenta.

Citar
También aclaro que para simplificar he hecho algunas suposiciones basándome en tu mensaje (por ejemplo, no especificas si hay variaciones en la altura inicial)
No me di cuenta de especificarlo: Sí, puede variar.
Pídeme lo que creas necesario.

Citar
aunque la posición de la red sea fija, en cada tiro, si cambia la posición inicial de la pelota y/o el destino, la distancia hacia la red también cambiará
Correcto.

Citar
Veo que tienes la variable DistanciahastaRed, aunque no sé si la calculas con cada tiro
Es la idea, aunque aún no la apliqué. Por las dudas: Esa distancia la calculo usando sólo la distancia Y. No sé si así sirve.


Perdona pero no me cierra mucho que resuelvas el problema usando sólo 2 dimensiones, además de que calculas 2 velocidades y yo necesito 3, o al menos con 2 no veo cómo puede funcionar.

Antes de intentar aplicar tu método decime qué piensas de esto (me lo dijeron hace tiempo o le agregué Z basado en lo que me habían dicho):
Código
  1. Norma = Math.sqrt(DistanciahastaDestinoX*DistanciahastaDestinoX+DistanciahastaDestinoY*DistanciahastaDestinoY+BallZ*BallZ);
  2.  
  3. BallXSpeed = DistanciahastaDestinoX/Norma*-AlexFuerzadetiros;
  4.  
  5. BallYSpeed = DistanciahastaDestinoY/Norma*-AlexFuerzadetiros;
  6.  
  7. BallZSpeed = BallZ/Norma*-AlexFuerzadetiros;
  8.  

AlexFuerzadetiros es lo que antes llamé AlexFuerza.

BallZ es lo mismo que decir DistanciahastaDestinoZ ya que el destinoZ es 0 (el suelo) y BallZ es la altura a la que está la pelota, es la distancia al suelo...

Este proceso me da buenos resultados AUNQUE como podrás deducir no cumple todas las condiciones.
La 3 (pasar por encima de la red) no la cumple a menos que el jugador estuviera muy cerca de la red o algo así.
La 4 (caer en la cancha rival) no la cumple si la fuerza es muy baja, pero también ocurre porque el método no tiene en cuenta que la pelota cae +0.01 por segundo.
Lo que pasa con la 5 (caer en cierto punto) es muy similar a lo que pasa con la 4.

Bueno ¿qué opinás de este método? ¿va bien encaminado y necesita ajustes, o hacer esos ajustes es más complicado que usar tu método? Es que me supera. Igual lo intentaré aplicar próximamente a ver qué resulta.

Por si te interesa te dejo lo que tengo hecho del juego:
https://workupload.com/file/WDjGSMhbSje
Es un rar con un exe dentro. Te pasaría un swf en vez de eso pero dudo que lo puedas reproducir. Está enlentecido porque intento ver claramente algunas cosas.
Etapa 1: Te movés con las flechas del teclado. Al presionar la tecla A, eleva la pelota y pasa a la etapa 2.
Etapa 2: Al presionar A de nuevo, saca. Si la pelota vuelve a la mano (si no presionas A antes de que pasen algunos segundos), vuelve a la etapa 1.
Cliqueando en el botón Reset o presionando Space vuelve a empezar.
« Última modificación: 23 Noviembre 2022, 10:58 am por Tachikomaia » En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #3 en: 26 Noviembre 2022, 03:44 am »

¿Como sucede aquí:
https://www.youtube.com/watch?v=yDIWBPwzi_0
?
Por ahora no.


Sí, a eso me refería, y mejor, porque eso lo podría complicar bastante.

Citar
Pero son 3 velocidades a calcular...


Cuando escribí esto:

Citar
en realidad es un problema de sólo 2 dimensiones. Por lo tanto, para calcular la parábola solo hay que usar los ejes (x, y). La forma de visualizar la curva que forma la pelota es esta:

Me refería a que para calcular el ángulo inicial de v para la parábola, sólo se usan 2 dimensiones: la altura y la distancia "hacia adelante". Esta última tú la ves como 2 dimensiones (y como una diagonal en tu dibujo) porque la perspectiva es aérea, pero no tendría que ser forzosamente así. Una buena forma de visualizar esto es imaginar que observamos el tiro desde una perspectiva lateral donde el eje horizontal es paralelo a la trayectoria que seguirá la pelota. Se ve mejor en esta imagen:



Si estuviéramos donde está el círculo amarillo de esa imagen, y a ras de suelo, veríamos lo que te puse en la imagen de mi mensaje anterior, que es la que debes tener en mente todo el tiempo que hablemos de la parábola. Desde ahí sólo tenemos 2 dimensiones, ya que la pelota ni se acerca ni se aleja de nosotros. Los cálculos que se hagan son igualmente válidos. Ese cambio de perspectiva, por así decirlo, es lo que se consigue al hacer esto que te había escrito:

Citar
Para resolver tu problema, y hacerlo en 2D, primero debes calcular la distancia total (que llamaremos x) hasta el punto destino:

x =  raiz(DistanciahastaDestinoX2 +  DistanciahastaDestinoY2)

Nota que estamos combinando DistanciahastaDestinoX y DistanciahastaDestinoX en una sola dimensión, que llamamos x, para hacer los cálculos de la parábola. Naturalmente, luego habrá que reconvertir a 3D para mostrar en pantalla. No lo especifiqué porque no tenía idea de qué tanto conoces de estos temas, pero básicamente lo que se hace es revertir la combinación. Más adelante te digo cómo.

Para evitar confusiones, siempre que mencione x o y, me estaré refiriendo a estos ejes desde la perspectiva lateral del dibujo de mi mensaje anterior. Y cuando quiera hacer referencia a la toma aérea (llamémosla coordenadas de pantalla), usaré tus variables BallX, BallY, etc. Si ves el dibujo de la toma lateral, verás que x se refiere a la trayectoria de la pelota (que en coordenadas de pantalla puede ser diagonal, pero desde nuestra perspectiva siempre es de izquierda a derecha simplemente), mientras que y es la altura, que se correspondería con BallZ.

Citar
¿Me puedes dar más info?

Si te refieres a la fuerza, es sólo por ser quisquilloso. Lo que pasa es que en física la fuerza es algo muy concreto que no se mide en distancia por segundo sino en newtons y se refiere a cuánta aceleración le puedes imprimir a un cuerpo de acuerdo con su masa, por lo que no se traduce directamente en velocidad. Solamente sería útil si quisieras una simulación ultra realista, que tome en cuenta la masa de la pelota, quizás resistencia del viento, etc., pero para algo como un juego sencillo sólo complicaría las cosas innecesariamente. Como dije es perfectamente válido llamarla fuerza en tu juego, pero si buscas información en internet o libros, el término que encontrarás es velocidad inicial.

Citar
¿Tampoco en caso de que se dedique el 100% a una velocidad sola?

En ese caso sí, pero es más bien por coincidencia. Como te comenté, la forma en que se distribuye la velocidad es: v0 = raiz(vx2 + vy2). Si la velocidad es totalmente vertical, la horizontal será cero (y viceversa), luego v0 = raiz(vy2 + 0), así que v0 = vy, pero sólo para este caso.

Citar
Por las dudas: Mi "simulación" de la gravedad funciona así:
https://foro.rinconmatematico.com/index.php?topic=51754.msg205838#msg205838
¿Es como en la realidad? ¿cómo es en la realidad?

Más o menos, en el sentido de que va ejerciendo una aceleración hacia abajo a lo largo del tiempo. En la realidad es más o menos como el método que te pongo (salvo que simplificamos obviando resistencia del viento, masa, etc.). De hecho, las ecuaciones de parábola que uso son justo las que encontrarías en un libro de física.

Citar
No me di cuenta de especificarlo: Sí, puede variar.

Entonces hay que hacer algunos cambios, ya que la fórmula del rango R es para cuando la altura inicial y final son iguales. También se hacía esa suposición en la ecuación de la parábola para y, que ahora quedaría así (otra vez, en negrita lo que realmente necesitas calcular en el programa):

y = h + v0 * sen(θ) * t - (g * t2)/2

donde h es la altura inicial de la pelota.

La distancia en línea recta, x, entre la pelota y el objetivo se sigue calculando igual:

x =  raiz(DistanciahastaDestinoX2 +  DistanciahastaDestinoY2)

El cálculo del ángulo se complica, pero sólo un poco. Queremos el valor de θ que permite que cuando la bola caiga (cuando y = 0) haya recorrido la distancia x deseada, así que la ecuación para y queda:

h + v0 * sen(θ) * t - (g * t2)/2 = 0

Pero como no conocemos t, necesitamos usar la otra ecuación que puse en el otro mensaje:

t = x/(v0 * cos(θ))

Sustituimos t por esto en la ecuación para y:

h + v0 * sen(θ) * x/(v0 * cos(θ)) - (g * (x/(v0 * cos(θ)))2)/2 = 0

Si la manipulamos un poco usando las propiedades de las funciones trigonométricas, la podemos convertir en una ecuación de segundo grado que se puede resolver con la fórmula general, y que al final reducimos a esto:

θ = arctan((v02 ± raiz(v04 - (g * (g*x2 - 2*v02*h))))/(g*x))

Como toda ecuación cuadrática puede tener 2 soluciones, por lo que es posible que haya 2 ángulos válidos.

Aquí conviene primero calcular el valor del que se saca la raíz:

disc  = v04 - (g * (g*x2 - 2*v02*h))

Si disc (que es equivalente al discriminante típico de la ecuación cuadrática) es negativo, significa que no tienes la "fuerza" necesaria para el tiro. Si es cero, las 2 soluciones son idénticas, así que sólo hay un ángulo. En caso contrario, hay dos ángulos distintos. Procedes a calcularlo(s):

θ1 = arctan((v02 + raiz(disc))/(g*x))
θ2 = arctan((v02 - raiz(disc))/(g*x))


Lo que seguiría es verificar, para cada ángulo, si pasa la red. Esto no cambia, y se sigue haciendo como en el mensaje anterior. Si sólo uno de los 2 ángulos lo consigue (o sólo había un ángulo), es el que hay que usar. Si los dos lo hacen, toca elegir el que quieras. Si lo que buscas es el que permita mayor velocidad hacia adelante (y menor altura), escoge el menor de θ1 y θ2.

Finalmente, para poder ir mostrando en pantalla la trayectoria, toca convertir las velocidades a 3D. BallZSpeed es la más simple (recuerda que en el mensaje anterior se calcularon vx y vy):

BallZSpeed = vy

aunque con este método no la necesitarías, ya que lo ideal sería calcular directamente la posición BallZ con la misma ecuación de la parábola:

BallZ = h + v0 * sen(θ) * t - (g * t2)/2

de nuevo, h es el valor original de BallZ al momento del tiro, y en t pones el número de segundos transcurridos.

Para las otras dos, hay que hacer unos cálculos. De la misma forma que nuestra x combina DistanciahastaDestinoX con DistanciahastaDestinoY, vx combina  BallXSpeed con BallYZSpeed. Para separarlas hay que conocer el ángulo de inclinación del trayecto de la bola visto desde arriba. Primero, hay que considerar el caso especial para cuando el destino está en línea totalmente vertical: eso significaría que toda la velocidad se aplicó en una sola dirección:

si (DistanciahastaDestinoX == 0)
   BallYSpeed = vx
   BallXSpeed = 0


en caso contrario, primero calculas la pendiente m de la trayectoria (vista desde perspectiva aérea/de pantalla):

m = DistanciahastaDestinoY/DistanciahastaDestinoX

luego su ángulo α:

α = arctan(m)

y con eso obtienes:

BallXSpeed = vx * cos(α)
BallYSpeed = vx * sen(α)


Sí, es vx en ambos casos, porque contiene las 2 velocidades combinadas.

Citar
Es la idea, aunque aún no la apliqué. Por las dudas: Esa distancia la calculo usando sólo la distancia Y. No sé si así sirve.

No. Eso sólo te serviría si el tiro es exactamente en línea recta vertical (en coordenadas de pantalla/vista aérea), pero cuando es en diagonal esa distancia cambia, y además depende del punto de la red por el que la pelota pase.Como te había dicho, lo que se hace es calcular la intersección de la recta que define la red con la del trayecto de la pelota. Hay más de un método para la intersección; no sé si los conozcas.

Citar
Antes de intentar aplicar tu método decime qué piensas de esto (me lo dijeron hace tiempo o le agregué Z basado en lo que me habían dicho):

¿Es el método que usas en tu juego? No está mal, salvo que, como dices, no toma en cuenta la gravedad, y si después la aplicas, descompones totalmente los cálculos. Además ese método hace que la pelota baje desde el primer momento, cuando para ciertos ángulos, primero debería elevarse. Así y todo se ve aceptable, pero no sé si podrías meterle la gravedad de forma convincente ni qué tan complicado sería.
En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.210


Superhacker (es broma xD )


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #4 en: 1 Mayo 2023, 13:51 pm »

En otro foro alguien me estaba respondiendo esto de un modo que yo lo entendía más que como me lo estaban explicando aquí y no seguí respondiendo aquí porque si intentar entenderlo de una manera me resultaba complicado, se imaginan si fueran 2, pero la persona del otro foro abandonó, yo en parte también, y ahora quiero retomar, así que retomo esto y envío un privado a RayR a ver si él también quiere. Respuestas de otros también son bienvenidas.

fuerza
Yo le llamaba fuerza a la medida de la capacidad de hacer que la pelota se mueva rápido, ahora uso fuerza de tiros que es calculado basado en varias cosas, pero en el fondo sigue siendo lo mismo. Músculos, no sé, es una palabra común en videojuegos.

...

Si la gravedad atrayera 1cm/s a la pelota, y la pelota está en 100cm, entonces con mi fórmula ocurriría esto:
En 1s cayó 1cm.
En 2s cayó 1cm+2cm
En 3s cayó 3cm+3cm
En 4s cayó 6cm+4cm
En 5s cayó 10cm+5cm
¿Con la fórmula que me dices qué ocurriría? Puede que necesite saberlo por si hago algo simplificado en algún momento y resulta que no quedaría bien porque caería a velocidades distintas.

Citar
primero debes calcular la distancia total (que llamaremos x) hasta el punto destino:

x =  raiz(DistanciahastaDestinoX^2 +  DistanciahastaDestinoY^2)
Considerando que estás trabajando en 2d y midiendo las distancias de un modo más complejo que yo, primero te pediría que me digas cómo obtengo DistanciahastaDestinoX y DistanciahastaDestinoY.

Si DhDX es como la línea que has puesto en la imagen, ten en cuenta que no sé cómo hacer que el programa gire los datos de modo que la línea quede totalmente horizontal.

DhDY supongo que es simplemente la altura a la que está la pelota (Z en la perspectiva aérea).

Empecemos por eso o, si quieres, continúa donde la otra persona me dejó, te muestro lo que me parece más relevante del cálculo pero si crees que falta algo me puedes avisar.
Nota: Es vista aérea.
Código
  1. // Datos para determinar velocidades del tiro.
  2. DistanciahastaDestinoX = 280.1-BallX;
  3. DistanciahastaDestinoY = 180-BallY;
  4. DistanciahastaMinsafeBallZ = BallZ-18.6;
  5. BallZwhenstriked = BallZ;
  6. DistanciahastaDestinoXY = Math.sqrt(DistanciahastaDestinoX*DistanciahastaDestinoX+DistanciahastaDestinoY*DistanciahastaDestinoY);
  7. DistanciahastaRed = DistanciahastaDestinoXY * Math.abs(BallY-300) / DistanciahastaDestinoY;
  8. // Determinando velocidades del tiro.
  9. BallXSpeed = DistanciahastaDestinoX/DistanciahastaDestinoXY*AlexFuerzadetiros;
  10. BallYSpeed = DistanciahastaDestinoY/DistanciahastaDestinoXY*AlexFuerzadetiros;
  11. BallZSpeed = 0;
  12. // Datos para determinar posiciones de la pelota.
  13. Tiempotranscurridodeltiro = 0;
  14. BallXwhenstriked = BallX;
  15. BallYwhenstriked = BallY;
DistanciahastaRed no entiendo cómo está calculada. BallY es en qué punto del eje Y está la bola, 300 es donde está la red, la distancia es la resta hecha absoluta, lo demás no lo entiendo.
AlexFuerzadetiros es básicamente lo que te expiqué, la fuerza del personaje, Alex.
Falta calcular la velocidad Z, pero la fuerza del personaje parece haber sido usada toda en dar velocidad X e Y, así que el cálculo de esas parece mal.

Luego tengo:
Código
  1. function Ballmoving () {
  2. Tiempotranscurridodeltiro = Tiempotranscurridodeltiro+1;
  3. BallX = BallXwhenstriked+BallXSpeed*Tiempotranscurridodeltiro;
  4. setProperty (BallShadow, _x, BallX);
  5. setProperty (Ball, _x, BallX);
  6. BallY = BallYwhenstriked+BallYSpeed*Tiempotranscurridodeltiro;
  7. setProperty (BallShadow, _y, BallY);
  8. DistanciaXYrecorrida = AlexFuerzadetiros * Tiempotranscurridodeltiro * C;
  9. Senodelangulodeltiro = Math.sqrt(1-C*C);
  10. BallZ = BallZwhenstriked + AlexFuerzadetiros * Tiempotranscurridodeltiro * Senodelangulodeltiro;
  11. BallZ = BallZ - 0.01 * Tiempotranscurridodeltiro*Tiempotranscurridodeltiro /2;
  12. }
C supongo que es Coseno, pero casi nada sé de eso.
La posición de BallZ parece que está mal calculada, demasiadas sumas y multiplicaciones (a menos que fueran números negativos pero lo dudo).
Y el resultado es este si el personaje tiene poca fuerza:
https://drive.google.com/file/d/1bY60WE73Gvh7eUFoRX8NAeuBoWIaYtNJ/view?usp=share_link
está aplicando más de la que tiene y además la pelota debe pasar más cerca de la red.

Con un poco más:
https://drive.google.com/file/d/1YEhAz8nrcztWpttScLOeMekfXlZHUVZ9/view?usp=share_link

¿Puedes arreglar eso? Aquí tienes su post:
https://foro.rinconmatematico.com/index.php?topic=122044.msg492794#msg492794

Gracias.
« Última modificación: 1 Mayo 2023, 14:00 pm por Tachikomaia » En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #5 en: 3 Mayo 2023, 04:29 am »

Actualmente no tengo mucho tiempo, pero si tienes algunas dudas puntuales con respecto a lo que te expliqué anteriormente, te podría ayudar cuando pueda.

Sólo vi muy de pasada lo del otro foro, pero por lo que veo el método es esencialmente el mismo que te di, aunque algunas cosas allá las calculan de forma más directa, pero, en mi opinión, más difícil de entender si no estás muy metido en las matemáticas, como creo que es el caso. También parece que te estaban dando ecuaciones para que la bola pase sobre la red exactamente a una cierta altura (¿?), pero, al menos aquí en este foro, lo que pedías era simplemente que fuera mayor o igual a un valor.

Si la gravedad atrayera 1cm/s a la pelota, y la pelota está en 100cm, entonces con mi fórmula ocurriría esto:
En 1s cayó 1cm.
En 2s cayó 1cm+2cm
En 3s cayó 3cm+3cm
En 4s cayó 6cm+4cm
En 5s cayó 10cm+5cm
¿Con la fórmula que me dices qué ocurriría?

Esos cálculos están mal. Como te había dicho, con tu fórmula sí estás aplicando una especie de "aceleración" pero no correctamente. Si la gravedad es 1 cm/s2,  entonces, si empezamos a contar en el momento en que la bola comienza a caer:

en 1 s, habrá caído 0.5 cm
en 2 s, habrá caído 2 cm
en 3 s, habrá caído 4.5 cm

porque la distancia s recorrida por un cuerpo con aceleración constante a (en este caso, la gravedad, o g), luego de t segundos es:

s = v0 * t + a * t2/2

donde v0 es la velocidad inicial. Como en tu ejemplo calculas el momento justo en que empieza a caer, v0 = 0, por lo que sólo queda: a * t2/2, y de ahí salen las distancias que te puse. Esas son las que te daría con la fórmula que yo te puse, y que en realidad es la misma que se usa en este fragmento de código que acabas de poner:

Código
  1. BallZ = BallZwhenstriked + AlexFuerzadetiros * Tiempotranscurridodeltiro * Senodelangulodeltiro;
  2. BallZ = BallZ - 0.01 * Tiempotranscurridodeltiro*Tiempotranscurridodeltiro /2;

Citar
Considerando que estás trabajando en 2d y midiendo las distancias de un modo más complejo que yo, primero te pediría que me digas cómo obtengo DistanciahastaDestinoX y DistanciahastaDestinoY.

Primero, corrijo un error de tecleo de mi mensaje anterior. Donde puse:

Citar
Nota que estamos combinando DistanciahastaDestinoX y DistanciahastaDestinoX en una sola dimensión,


Debería decir:

Citar
Nota que estamos combinando DistanciahastaDestinoX y DistanciahastaDestinoY en una sola dimensión,

Creo que era muy obvio, pero mejor aclarar.

Ahora, DistanciahastaDestinoX y DistanciahastaDestinoY son exactamente las variables que se supone que tú ya tienes, como pusiste en tu primer mensaje. Recuerda que como te mencioné ahí, cuando use tus nombres de variables, me estaré refiriendo a ellas desde la vista aérea. O sea, en cualquier ecuación que yo ponga, si aparecen nombres de variables de tu código, las debes poner tal cuál las tengas, sin necesidad de convertirlas.


Citar
Empecemos por eso o, si quieres, continúa donde la otra persona me dejó, te muestro lo que me parece más relevante del cálculo pero si crees que falta algo me puedes avisar.

Lo de revisar y arreglar lo de la otra persona sería una pérdida de tiempo para mí, dado que en mis otros dos mensajes ya está, me parece, casi todo lo necesario para implementar lo que quieres.

Citar
DistanciahastaRed no entiendo cómo está calculada.

Esto sí es conveniente explicarlo, dado es algo que omití porque, como te dije en el mensaje anterior, no sabía si ya lo estabas calculando. Va un ejemplo para entenderlo. Supongamos que la distancia hasta la red estuviera justo a la mitad del trayecto desde el jugador al destino (DistanciahastaDestinoXY). Entonces:

Código
  1. DistanciahastaRed = DistanciahastaDestinoXY * 0.5;

Y si en realidad la distancia hasta la red fuera 1/4 de la distancia al destino, multiplicarías por 0.25, etc. Así que necesitamos calcular esa razón (1/2, 1/4, etc.) y con ello obtenemos DistanciahastaRed. Dado que conocemos la distancia en Y hasta la red (BallY-300), y también la distancia en Y hasta el destino DistanciahastaDestinoY, si las divimos, conseguimos el valor necesitado. Así, en cada tiro:

DistanciahastaRed = DistanciahastaDestinoXY * Math.abs(BallY-300) / DistanciahastaDestinoY;

la parte en negrita será 0.5, 0.25, etc.
En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.210


Superhacker (es broma xD )


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #6 en: 3 Mayo 2023, 16:35 pm »

También parece que te estaban dando ecuaciones para que la bola pase sobre la red exactamente a una cierta altura (¿?), pero, al menos aquí en este foro, lo que pedías era simplemente que fuera mayor o igual a un valor.
Me entreveré porque hay 2 tipos de tiros: Rápido y profundo.

La diferencia se nota si el personaje no tiene tanta fuerza.

En el profundo, se intenta que la bola bote en lo más profundo del área de saque, por lo que, si el personaje no tiene suficiente fuerza (pero suficiente como para pasar la red), golpeará un poco hacia arriba, será como un globito, la bola pasará a una distancia considerable de la red.

En el rápido, se intenta que la bola llegue a la cancha rival lo más rápido posible, independientemente de si bota profundo o no, por lo que siempre que el personaje tenga suficiente fuerza como para pasar la red, pasará a la mínima altura posible (18.6).

Prefiero que los cálculos sean para el profundo, ya que si se saca hacia el centro con poca fuerza, botaría fuera del área de saque y tendría que corregir eso; primero quiero lo mínimo necesario, o más importante.

Citar
Esos cálculos están mal. Como te había dicho, con tu fórmula sí estás aplicando una especie de "aceleración" pero no correctamente. Si la gravedad es 1 cm/s2,  entonces, si empezamos a contar en el momento en que la bola comienza a caer:

en 1 s, habrá caído 0.5 cm
en 2 s, habrá caído 2 cm
en 3 s, habrá caído 4.5 cm

porque la distancia s recorrida por un cuerpo con aceleración constante a (en este caso, la gravedad, o g), luego de t segundos es:

s = v0 * t + a * t2/2

donde v0 es la velocidad inicial. Como en tu ejemplo calculas el momento justo en que empieza a caer, v0 = 0, por lo que sólo queda: a * t2/2, y de ahí salen las distancias que te puse.
Gracias por la explicación.

Citar
corrijo un error de tecleo (...) Creo que era muy obvio
Sí, no problem.

Gracias también por la explicación de DistanciahastaRed.

Bueno... ¿y qué hago en el código? ¿qué agrego, qué modifico o quito?
« Última modificación: 3 Mayo 2023, 16:52 pm por Tachikomaia » En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #7 en: 5 Mayo 2023, 04:43 am »

Me entreveré porque hay 2 tipos de tiros: Rápido y profundo.

La diferencia se nota si el personaje no tiene tanta fuerza.

En el profundo, se intenta que la bola bote en lo más profundo del área de saque, por lo que, si el personaje no tiene suficiente fuerza (pero suficiente como para pasar la red), golpeará un poco hacia arriba, será como un globito, la bola pasará a una distancia considerable de la red.

En el rápido, se intenta que la bola llegue a la cancha rival lo más rápido posible, independientemente de si bota profundo o no, por lo que siempre que el personaje tenga suficiente fuerza como para pasar la red, pasará a la mínima altura posible (18.6).

Prefiero que los cálculos sean para el profundo, ya que si se saca hacia el centro con poca fuerza, botaría fuera del área de saque y tendría que corregir eso; primero quiero lo mínimo necesario, o más importante.

Sí, esa parte está clara, la pelota no sólo debe pasar por encima de la red sino que además debe hacerlo a la menor altura posible. Pero "lo más bajo posible" es distinto de "exactamente".

Piensa bien qué es lo que quieres hacer, porque si arbitrariamente cambias las condiciones, no se llega a ningún lado. Como te dije, lo que te pusieron en el otro foro es para que la pelota pase exactamente a la mínima altura posible, y en ese caso, la velocidad no la puedes decidir tú, sino que se calcula con las ecuaciones que te dieron. Y esas velocidad resultante no tiene por qué corresponderse con la "fuerza" que tiene tu jugador. Es decir, no usan AlexFuerza para nada, sino que te imponen el valor que esa variable debe tener.

El método que yo te puse no tiene la restricción de que la pelota tenga que pasar exactamente a una altura, sino simplemente que lo haga sobre la red, y por eso no impone o "inventa" la fuerza, sino que la toma directamente de la que tú eliges (mi variable v0 es lo mismo que AlexFuerza) y lo que te da es el ángulo (o distribución de las velocidades, que es lo que pedías) o ángulos, pues pueden ser dos, con los que debe ser lanzada la pelota para que caiga en el destino deseado. Luego se verifica si alguno de esos ángulos pasa por encima de la red, y si ambos lo hacen, eliges el que convenga: el menor tendrá más velocidad "hacia adelante" y el mayor se elevará más. Sin embargo, también tiene sus limitaciones. Dado que no es nada flexible con la fuerza (toma exactamente el valor de AlexFuerza, que al menos yo entendí que era lo que pretendías), el tiro no necesariamente será el más óptimo, a diferencia del otro que te dieron, pero que no usa tu fuerza. No hay una única solución perfecta que cumpla todas las condiciones, por lo que antes que nada debes pensar cuál te parece más conveniente.
En línea

Tachikomaia


Desconectado Desconectado

Mensajes: 1.210


Superhacker (es broma xD )


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #8 en: 8 Mayo 2023, 18:27 pm »

Sí, esa parte está clara, la pelota no sólo debe pasar por encima de la red sino que además debe hacerlo a la menor altura posible. Pero "lo más bajo posible" es distinto de "exactamente".
¿Cual es la diferencia?

Repito:
Código:
Si el jugador no tiene suficiente fuerza como para que la pelota pase la red,
   no debe pasar
sino si tiene suficiente fuerza pero debe lanzarla hacia arriba para que pique en lo profundo del área del saque, o para que bote ahí al menos,
   la lanza hacia arriba, puede que pase bastante por encima de la red
sino
   pasará casi rozando la red, a la mínima altura posible (pero por encima de la red), que exactamente determiné que es 18,6.

En el siguiente video puedes ver esos casos, pero no está bien porque la fuerza se reparte 100% en XY y luego también puede usarse 100% en Z o algo así, el código es un lío además.
https://drive.google.com/file/d/1jyrIyycu_joxlfIblj5IDEwZ_Y3giSPR/view?usp=share_link

Con fuerza 10 no hay problema (aunque no puede usarla toda creo, tendría que usar un golpe liftado o algo así, pero eso es otro tema).
Con fuerza 5 pasa un poco más arriba.
Con fuerza 2 pasa muy por arriba.
Con fuerza 1 no pasa la red aunque se apunte desde el centro hacia el centro.

Citar
lo que te pusieron en el otro foro es para que la pelota pase exactamente a la mínima altura posible, y en ese caso, la velocidad no la puedes decidir tú, sino que se calcula con las ecuaciones que te dieron. Y esas velocidad resultante no tiene por qué corresponderse con la "fuerza" que tiene tu jugador. Es decir, no usan AlexFuerza para nada, sino que te imponen el valor que esa variable debe tener.
Es porque expliqué mal o quien respondió no entendió. Creo que desde el inicio dije que quería que la fuerza dependiera del personaje, de una variable (eso es la condición 2 y está al comienzo de este tema), que por dónde pase es secundario (condición 3, es decir, que debe cumplirse pero sin que dejen de cumplirse las anteriores).

...

Por lo que dices tu método daría el resultado que quiero. Si además sirve para determinar 2 posibles tipos de tiro (profundo o veloz), mejor. Que el tiro no sea el más óptimo está bien, si el personaje no tiene suficiente fuerza no debe poderla usar de la nada ¿o es posible que con menos fuerza pueda hacer tiros mejores?
En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones.
« Respuesta #9 en: 9 Mayo 2023, 03:05 am »

¿Cual es la diferencia?

Como te había dicho, las ecuaciones que estoy poniendo usan exactamente la fuerza que tu personaje tenga, de manera que cuando digo "lo más bajo posible", es lo más bajo posible con la fuerza disponible. Pudiera ser que no tengas la suficiente para pasar la pelota a exactamente 18.6 m al llegar a la red, pero sí a 19.5 m. En tal caso, si pidieras exactamente 18.6 m, la respuesta sería que es imposible. Si en cambio pides la menor altura posible (siempre que sea por encima de la red) se te daría el ángulo que la pasa a 19.5 m.

Citar
Repito:
Código:
...pero debe lanzarla hacia arriba para que pique en lo profundo del área del saque, o para que bote ahí al menos

Eso no estaba estaba originalmente, así que mi método no lo toma en cuenta. De todas formas creo es mejor que primero trates de hacer que funcione bien con las condiciones originales.

Citar
En el siguiente video puedes ver esos casos, pero no está bien porque la fuerza se reparte 100% en XY y luego también puede usarse 100% en Z o algo así, el código es un lío además.
https://drive.google.com/file/d/1jyrIyycu_joxlfIblj5IDEwZ_Y3giSPR/view?usp=share_link

Sin conocer bien todos los parámetros, como las coordenadas (¿y AlexAcc es la gravedad?), es difícil saber bien lo que pasa, pero en ninguno de los casos la fuerza se está repartiendo al 100% en XY. Como te había dicho anteriormente, la velocidad total no es la suma de las individuales sino:

v = raiz(vx2 + vy2).

De hecho, aún incorporando la velocidad en Z, no llega al 100% de la disponible. ¿Estás usando el método del otro foro?

Citar
Por lo que dices tu método daría el resultado que quiero. Si además sirve para determinar 2 posibles tipos de tiro (profundo o veloz), mejor.

Si te refieres a profundo y veloz tal como los definiste arriba, no. Ninguno de los dos tiros que obtengas hará que la pelota pique en el área de saque, porque, de nuevo, esa condición no estaba cuando escribí mis primeras dos respuestas. Con los dos posibles ángulos que te dan mis ecuaciones, la pelota cae directamente en el destino deseado en la cancha rival, simplemente uno es más "globeado" y otro más directo.

Citar
Que el tiro no sea el más óptimo está bien, si el personaje no tiene suficiente fuerza no debe poderla usar de la nada ¿o es posible que con menos fuerza pueda hacer tiros mejores?

Con mi método obtienes el tiro ideal usando exactamente la fuerza disponible. Sin embargo, en algunos casos, usando menos fuerza podrías conseguir tiros que pasen más bajo, es decir, más cercanos a la red (y obviamente, cumpliendo con tus otras condiciones), pero determinar esto complicaría las cosas, por lo que aquí también creo que es mejor que te enfoques en tratar de implementar correctamente mi método o el del otro foro.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines