Program for the calculation of a projectile trajectory


#1

Hello guys, this is the first time I post here so dont take it hard with me. Im a cross-platform application design student, and im currently learning about JavaScript. So far I only got teached about functions, if and else, arrays and for, while and do while. Today I had a trial about all but arrays, and we had to develop a program that calculates a projectile trajectory every 0.1 seconds. We must use 2 functions, one to get X and another one to get Y, and the program must finish whenever y<=0. The thing is I really dont know how to finish my program and tomorrow is the last day to try and get a solution. This is what I have:

I am spanish btw so here you have a dictionary

angulo = angle = ang
velocidad = velocity = v
tiempo = time = t
aceleracion = acceleration = a

let readlineSync = require("readline-sync");

function coordX(v, ang, t){
    x = v * Math.cos(ang) * t;
    return x;
}

function coordY(v, ang, t, a){
    y = ( v * Math.sin(ang) * t ) - (0.5 * a *(t*t));
    return y;
}

let angulo = readlineSync.questionFloat("Introduce el angulo de tiro en radianes: ")
let velocidad = readlineSync.questionFloat("Introduce la velocidad de lanzamiento: ")
console.log("Tabla de lanzamiento para un tiro de inclinación: " + angulo + " y velocidad: " + velocidad + "m/s.")

let tiempo = 0;
let aceleracion = 40;
let x = 0;
let y = 0;

while(y >= 0){
    tiempo += 0.1;
    coordX(velocidad, angulo, tiempo)
    coordY(velocidad, angulo, aceleracion, tiempo);
}

console.log(x, y)

I know this is probably a mess but dont forget im still learning. Thank you very much for your help.


#2

This looks like a node project due to the readlineSync, so let’s get some setup done.

> mkdir projectile-trajectory

> npm init -y
...
> npm install readline-sync

I can then place your script in src/script.js and we’re ready to start investigating the code.

Would it help if you placed the console command inside of the while loop?


#3

So far I have done small changes and I have this now:

let readlineSync = require("readline-sync");

function coordX(v, ang, t){
    x = v * Math.cos(Math.PI / 180 * ang) * t; 
    return x;
}

function coordY(v, ang, t, a){
    y = ( v * Math.sin(Math.PI / 180 * ang) * t ) - (0.5 * a * (t * t));
    return y;
}

let angulo = readlineSync.questionFloat("Introduce el angulo de tiro: ")
let velocidad = readlineSync.questionFloat("Introduce la velocidad de lanzamiento: ")
console.log("Tabla de lanzamiento para un tiro de inclinación: " + angulo + " y velocidad: " + velocidad + "m/s.")
console.log("Iniciando lanzamiento...")

let aceleracion = 40;
let tiempo = 0;
let x = 1;
let y = 1;

while(y > 0){
    coordX(velocidad, angulo, tiempo)
    coordY(velocidad, angulo, aceleracion, tiempo);
    console.log(tiempo, coordX(), coordY());
    tiempo += 0.1;
}

#4

I finally finished it, this is what I have:

let readlineSync = require("readline-sync");

function coordX(v, ang, t){
    x = (v * Math.cos(Math.PI / 180 * ang) * t);
    return x;
}

function coordY(v, ang, t){
    y = ( (v * Math.sin(Math.PI / 180 * ang) * t) - (20 * (t * t)) ); //20 porque .5 * 40 y asi me ahorra la variable aceleracion
    return y;
}

let angulo = readlineSync.questionFloat("Introduce el angulo de tiro: ")
let velocidad = readlineSync.questionFloat("Introduce la velocidad de lanzamiento: ")
console.log("Tabla de lanzamiento para un tiro de inclinación: " + angulo + " y velocidad: " + velocidad + "m/s.")
console.log("Iniciando lanzamiento...")
let tiempo = 0;
let x;
let y;

do{
    tiempo += 0.10;
    console.log(tiempo, coordX(velocidad, angulo, tiempo), coordY(velocidad, angulo, tiempo))
    
} while(y > 0);

#5

I think the problem here:

do{
    tiempo += 0.10;
    console.log(tiempo, coordX(velocidad, angulo, tiempo), coordY(velocidad, angulo, tiempo))
    
} while(y > 0);

is that you don’t alter the value of y anywhere in that loop, unless I am misunderstanding how console.log works. You call the coordY() function inside your console.log line, but while that calculates a variable called y that is inside the function, so the value is not accessible from the calling code (see “variable scope” for more information). You do return that value, but again don’t do anything inside the loop with the returned value.

After your console.log line inside the loop, you could perhaps just add a line

y = coordY(velocidad, angulo, tiempo);

which should allow it to exit the loop.


#6

That got me curious how I’d solve that … obviously using objects since in physics you’d describe that using vectors.

// I don't use classes when the language doesn't support it
// ... hence using a factory
function vector(x, y)
{
    var obj = Object.create(vector.prototype)
    // make the x & y properties immutable
    // also apply rounding since floating-point math is inaccurate (quick fix)
    Object.defineProperty(obj, 'x', { value: +x.toFixed(vector.scale) })
    Object.defineProperty(obj, 'y', { value: +y.toFixed(vector.scale) })

    return obj
}
// rounding scale
vector.scale = 3
// the vector that changes the object
vector.prototype.delta = false
// create a new vector from applying the change-vector
vector.prototype.next = function (time=0) {
    if (!this.delta) {
        return this
    }
    var delta = this.delta.next(time)
    var obj = this.add(delta.mult(time))
    obj.delta = delta
    return obj
}
vector.prototype.add = function (vec) {
    return vector(this.x + vec.x, this.y + vec.y)
}
vector.prototype.mult = function (factor) {
    return vector(this.x * factor, this.y * factor)
}

var gravity = vector(0, -9.81)

var speed = vector(1, 0)
// acceleration is the change-vector of velocity
speed.delta = gravity

var obj = vector(10, 10)
// velocity is the change-vector of position
obj.delta = speed
while (obj.y >= 0) {
    obj = obj.next(0.1)
    console.log(obj.x, obj.y)
}

that got me a nice down-curving parable. (the inaccuracy comes through the iteration steps, though)