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

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


  Mostrar Mensajes
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 24
41  Informática / Software / Re: Excel 2013: Lograr que el resultado de una fórmula sea por ejemplo 1, 1, 10 en: 9 Enero 2023, 03:00 am
Si entendí bien lo que quieres, puedes lograrlo así:

=TEXTO(MIN(A2:C2), "0") & ", " & TEXTO(MIN(D2:F2), "0") & ", " & TEXTO(MIN(G2:I2), "0")

De hecho, dado que no necesitas un formato especial, esto también debería funcionar:

=MIN(A2:C2) & ", " & MIN(D2:F2) & ", " & MIN(G2:I2)
42  Programación / Programación C/C++ / Re: AYUDA POR FAVOR en: 29 Diciembre 2022, 19:50 pm
Eso huele a código copiado, pero dando el beneficio de la duda:

Código
  1. putchar(argv[1][0]);  //El primer caracter en la salida estandar y escribe en la tuberia, imprime el primer caracter

*primer caracter*. ¿Cómo esperas que se muestre el nombre completo del archivo si sólo estás imprimiendo el primer caracter (algo que "tu" propio comentario explica  :silbar:)?

Y además tienes esto:

Código
  1. #define NUM_HIJOS 10
  2. ...
  3. pid_t pids[NUM_HIJOS];

pero la ruta que le pasas al programa puede tener más de 10 entradas, y de hecho, en tu caso, dices que son 17, así que estás provocando un desbordamiento de buffer. Y tienes estos for inconsistentes:

Código
  1. for(i=1; i<argc; i++){
  2. ...
  3. for(i=1; i<NUM_HIJOS; i++){

pero NUM_HIJOS no tiene por qué ser igual a argc. De hecho casi nunca lo será. Lo que debes hacer es reservar dinámicamente la memoria para pids de acuerdo al número de archivos (argc - 1), y en tus dos for usar argc como límite superior.


Y esto:
Código
  1.            /*Redireccion de la entrada estandar al archivo*/
  2.            if ((fd[0] = open(argv[1], O_RDONLY)) == -1){
  3.                fprintf(stderr, "Error en la apertura del archivo de datos\n");
  4.                return EXIT_FAILURE;
  5.            }

 no tiene razón de ser. Sustitúyelo por un simple:

Código
  1. close(fd[0]);
43  Programación / Programación General / Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones. 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.
44  Programación / Programación General / Re: Ayuda con cálculos para que la trayectoria de una pelota cumpla ciertas condiciones. 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.
45  Programación / Programación C/C++ / Re: equivalente a los tipos de dato Date y ArrayList<T> de Java pero en C++ en: 1 Noviembre 2022, 01:46 am
Para ArrayList, sería std::vector. Para Date tienes varias opciones. Puedes usar las funciones de <ctime> (o <time.h>), aunque como vienen desde C, no hay clases sino sólo las funciones sueltas.

Si no te sirve o quieres algo más "moderno", en la cabecera <chrono> (y namespace std::chrono) hay varias clases que te podrían servir, como sys_days o sys_seconds (dependiendo de cuánta precisión quieras, días o segundos), o directamente time_point, que te permite especificar otras unidades de precisión. Lo único malo es que apenas fueron agregadas a C++ en 2020, y algunos compiladores tardaron en implementarlas bien, así que necesitas usar un compilador muy reciente. Además, como pasa casi siempre con la STL, su funcionamiento tiene sentido (más o menos :rolleyes:) una vez que lo aprendes bien, pero es muy poco intuitivo al principio. Si con ctime te basta para lo que necesitas, te recomendaría que eso uses.
46  Programación / Programación General / Re: algoritmo en asseblmer en: 29 Octubre 2022, 17:29 pm
Siempre al hablar de ensamblador es importante especificar la arquitectura, ya que cada una tiene uno completamente distinto.

Eso debe ser Motorola 6800 o algún derivado. No hay nada de raro con ese espacio de memoria, sino que estás confundiendo hexadecimal con decimal. En hexadecimal, el número que sigue a 149 no es 150 sino 14A. Cambia las direcciones de ldaa y cmpaa por $014A y $014B y debería funcionar.
47  Programación / Programación C/C++ / Re: Almacenar bytes en un char ¡¡AYUDA!! en: 13 Octubre 2022, 17:21 pm
En el otro tema que habías abierto te había dicho que podías usar memcpy para eso. Si no conoces esa función, búscala en algún manual o tutorial, porque es importante. De cualquier forma, te pongo un ejemplo de cómo podrías juntarlas desde el cliente (esto obviamente iría después de los htons):

Código
  1. memcpy(buffer, &A, sizeof(A));
  2. memcpy(buffer + sizeof(A), &B, sizeof(B));
  3. buffer[sizeof(A) + sizeof(B)] = sign[0];
  4. send(sock, buffer, 5, 0);

En el servidor harías prácticamente lo mismo, pero copiando desde el buffer hacia las variables. De nuevo, si revisas la documentación de memcpy, es simple.

Como también te comenté en el otro tema, normalmente uno no debería simplemente confiar en que todos los bytes se hayan enviado en un solo send (ni, desde el servidor, que se hayan recibido todos en un read), pero aquí estás manejando un número tan pequeño de bytes que igual no vale la pena complicar tu código.
48  Programación / Programación C/C++ / Re: Hola necesito ayuda en estructura de datos Stack <E> en: 10 Octubre 2022, 22:59 pm
Sí. Apilar y desapilar (push y pop),  que son las operaciones principales de las pilas, se ejecutan en tiempo constante.
49  Informática / Hardware / Re: ¿Por qué ahora la memoria interna la llaman rom? en: 29 Septiembre 2022, 16:55 pm
Aunque es cierto que ahora a veces se le llama ROM al sistema operativo, ese es un uso incorrecto, aunque muy extendido, del término.

Como ya te comentaron ROM se refiere a memoria de sólo lectura. Lo que pasa es que con el tiempo surgieron variantes (PROM, EPROM, EEPROM) que permitían, de una forma u otra, (re)escribir y/o borrar, pero siguen siendo técnicamente ROM. Las memorias que actualmente suelen usar los teléfonos son de tipo flash, que es también un tipo de ROM (en los documentos técnicos de los fabricantes, se suele usar el término Flash ROM).

Así, pues, no es un error llamar ROM al almacenamiento interno.
50  Programación / Programación C/C++ / Re: duda con una clase de un libro en: 26 Septiembre 2022, 16:30 pm
Bueno, sí, claramente esa no es una implementación completa de la clase, sino simplemente de algunas de sus funciones y variables miembro. Ya te tocaría a ti crear la clase completa.

Por cierto, aunque creo que siempre es importante (incluso diría indispensable) saber implementar de cero las distintas estructuras de datos, como ya te dijeron, C++ sí que incluye, desde hace muchos años, arrays que conocen su propio tamaño, (como std::array) entre muchas otras estructuras. El libro debe ser muy viejo.

También una aclaración: la clase vector de C++ no es una lista enlazada, sino simplemente un array dinámico, con los elementos almacenados en direcciones contiguas dentro de un mismo bloque de memoria, o sea, nada que ver con las listas. Igualmente, deque no es una lista doblemente enlazada, sino una cola doblemente terminada. La complejidad de las operaciones que estas clases ofrecen es completamente distinta a la de las listas. En realidad, forward_list y list son las clases que C++ proporciona para listas y listas doblemente enlazadas.
Páginas: 1 2 3 4 [5] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 24
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines