Angle of Projection
#1

How did you calculate an object's projection path?

Like for example, The start point would be the player, and the angle would be his camera's angle... But how do you move the object along the line... (I want to simulate a cannon and slingshot.)



I'd like it to follow this picture's physics as closely as possible... It's good slingshot range... But the power would be slightly random, I can adjust the power, I just don't know how to do the rest...
Reply
#2

You will need to generate frames to do this then play them back with MoveObject() this won't work with dynamic objects they are too slow.
Reply
#3

So... Generate the path, play it by moving the object along it... That's what I wanted to know how to do, I have no clue where to start on getting the path...
Reply
#4

Someone probably has a better way to do this than me but I will try and come up with an idea for you.

Main variables

distance - Distance of object to move
height - Height of object to attain
numframes - Number of frames in sequence
angle - Angle of origin
origin-x - Origin position
origin-y - Origin position
origin-z - Origin position

Calculating x/y/z positions

dist = distance / numframes

I will give you a test script to make sure that worked as expected. There is probably a better way to do this but I will admit I'm actually terrible at trig.

Ok here we go sorry about that
pawn Код:
#include <a_samp>
#include <zcmd>

CMD:testp(playerid, arg[])
{
    new Float:ox, Float:oy, Float:oz, Float:angle, Float:x, Float:y, Float:z;
    GetPlayerPos(playerid, ox, oy, oz);
    GetPlayerFacingAngle(playerid, angle);
    new numframes = 15;
    new Float:height = 40;
    new Float:distance = 20;
    new Float:framedistratio = numframes / distance;
   
    new Float:dist = floatdiv(distance, float(numframes));

    printf("%f", dist);

    for(new i = 1; i <= numframes; i++)
    {
        x = ox + ((dist*i) * floatsin(-angle,degrees));
        y = oy + ((dist*i) * floatcos(-angle,degrees));
        z = oz + floatmul(floatsin(floatmul(floatdiv(3.14159265359/framedistratio, distance), i)), height);


        CreateObject(1974, x, y, z, 0.0, 0.0, 0.0);

    }
    return 1;
}
Printing

pawn Код:
floatmul(floatsin(floatmul(floatdiv(3.14159265359/2, distance), i)), height);
Код:
0.500000
1.564344
3.090169
4.539905
5.877852
7.071067
8.090169
8.910065
9.510565
9.876883
10.000000
9.876883
9.510564
8.910064
8.090169
7.071067
5.877851
4.539903
3.090167
1.564344
-0.000000
Result your moveobject frames


Okay now that code seems to work you will need to create a frame generator / playback function I will give the function definitions but no code

pawn Код:
frameindex = GenerateFrames(numframes, Float:ox, Float:oy, Float:oz, Float:angle, Float:distance, Float:height)
ClearFrames(frameindex);
PlaybackFrames(objectid, frameindex, Float:speed);
forward OnFinishFramePlayback(objectid, frameindex);
Reply
#5

So, for each frame I would set the position of the object?
pawn Код:
for(new i = 1; i <= numframes; i++)
{
    x = (ox + (dist*i) * floatsin(-angle,degrees));
    y = (oy + (dist*i) * floatcos(-angle,degrees));
    z = oz + floatmul(floatsin(floatmul(floatdiv(3.14159265359, distance), i)), height);
    SetObjectPos//?
}
Or Move object? I'd like to see the test script, maybe I'll learn from it better...
Reply
#6

Please review the formula again I made a big mistake I found with some further testing there is a relationship between the number of frames and and distance to get the correct pi division.
Reply
#7

I like it, and I completely understand it now...

But, Could you make a similar code, but for camera vectors instead of players facing angle? Also, using camera vectors and an amount of power in which the object is launched, could you calculate a height instead of using a set height? In the first picture from the main post, the power is the same in each angle, but the height is not set, that is the correct way for doing this...

I will temporarily use the code you have just presented, it does work, but I don't like having a set height like that.

Also, the frame count, I think there should be a way to calculate the number of frames too, like each frame should be 2 meters apart or something...

Thanks Pottus, this has really helped alot...
Reply
#8

You need to pre-calculate everything before doing anything it really depends on how your variables are set to give you your result.
Reply
#9

You could try using this include: https://sampforum.blast.hk/showthread.php?tid=446286

It has nice functions for making friction and air resistance. I have never tried that include, but the videos are quite amazing and in the soccer video you can see the ball flying like you wanted. You can also make the grenade bounce off the walls with that include, which would be awesome.
Reply
#10

Quote:
Originally Posted by Finn
Посмотреть сообщение
You could try using this include: https://sampforum.blast.hk/showthread.php?tid=446286

It has nice functions for making friction and air resistance. I have never tried that include, but the videos are quite amazing and in the soccer video you can see the ball flying like you wanted. You can also make the grenade bounce off the walls with that include, which would be awesome.
Unfortunately it is not well suited for the application he is trying to achieve you must define walls etc there is really no way to do this with San Andreas objects that include is better suited for small games like pool / air hockey soccer etc.

@Edit but it does give me an idea actually I would like to try but requires some updating with map andreas to introduce dynamic lower z-bounds I will test it out for him.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)