Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved] Consistent speed on trajectory given by a linear function  (Read 2586 times)

0 Members and 1 Guest are viewing this topic.

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
[Solved] Consistent speed on trajectory given by a linear function
« on: September 14, 2012, 04:16:44 am »
The problem is not with SFML in general, but rather some logic that I don't know how to implement.
In my project I get an item to get a linear trajectory, and while the trajectory is perfect in mathematical sense, the speed of the sprite is not consistent. I am using an external struct that handles the movements through the main loop until the sprite is out of bounds.

The problem is that as it goes through the given line of movement, the closer the sprite's "x" is to the other point's "x" it's speed becomes less consistent, in other words it goes faster than as if the sprite's "x" was further from the given point's "x". I need a mathematical formula to correct this so that the speed I give my sprite becomes the same for any two points given.

At first I was using an unsigned int which is what was causing the problem, when the "x" difference was too small it just went and drew some few points.

I would give a minimal code example right away, but since for this I have need of many classes and not just a small dependency like with other problems it'll take a while. For now I'll attach two images showing what happens just as a small overview of the issue. 

The images show the output of the positions drawn.
Sample1 shows the furthest possible "x".
Sample2 shows the closest  possible "x".
Both coordinates start with an "x" from 0 to 800.

So the first sprite sample follows slowly through a line and the other just draws three positions and goes out of bounds.

As soon as I have the minimal sample code I'll add it to the post. For now if anyone has an idea of how to make a sprite follow a linear function in the same time and distance regardless of the points of the grid chosen I'm all ears, I have been thinking on alternate ways all day and haven't gotten to anything useful.

Thanks in advance for any help I may get.


[attachment deleted by admin]
« Last Edit: September 15, 2012, 07:53:25 pm by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Re: Consistent speed on trajectory given by a linear function
« Reply #1 on: September 14, 2012, 04:41:52 am »
I don't quite follow 100% what you're trying to do, but maybe I can help anyways...

For simplicity let's first just take a constant positive velocity in x direction and zero in y direction, so we know that the sprite moves at the speed v in the x direction. We also know that our screen gets updated every 60 seconds, thus the resulting formula would be:
pos.x = pos.x * v.x * dt
Whereas dt is the delta time (= time difference) between two frames. Our screen gets updated 60 times per second thus the inverse is our dt, i.e. 1/60fps.
This little example simulates an 'numerical' movement, i.e. every new calculation is based up on the old one.

With a predefined function like you have, one should be able to calculate the position of the sprite to any given point in time, so you have a function depending on time. You now only need to sum up the passed time  and hand it over to that function, which in return will tell you the new position. The trick for a nice movement is to have a small enough timestep.

Maybe I got you all wrong, but it's a bit hard to understand without the example. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Consistent speed on trajectory given by a linear function
« Reply #2 on: September 14, 2012, 05:39:11 am »
Your solution sounds interesting, I'll give it a try, but I have a problem with it which is that it can't just take a direction, but an specific line based on the start point of the first sprite and the current location of a movable sprite which makes it more complex.

I'll add the sample now since I have finished extracting all the needed code:


struct LinearIndex
{
    float i;
    LinearIndex();
    LinearIndex(const float x);
    void setFunction(const float m, const float b);
    float getM();
    float getB();

    private:
    float m, b;
};

class Bullet
{ private:
        sf::Vector2f Start;
       float CurrentSpeed;
public:
        sf::Sprite Bshot;
        LinearIndex Line;
        unsigned L_type;
};
 

That's it for class definitions.


void LinearIndex::setFunction(const float tilt, const float intersect)
{ m = tilt; b = intersect; }


Bullet::Bullet(sf::Vector2f begin, const float Speed, Shot_Type SType)
{
    Start = begin; CurrentSpeed = Speed;
    Type = SType; TransformTo = Undefined;
    After_Effect = Transform = false; DistanceMoved = 0.0;
}

void Bullet::LinearAssignation(const sf::Vector2f vec)
{   if( (int)Start.x == (int) vec.x ) ///To avoid float comparisson annoyance.
    { Start.x -= 1; }
    float m = ( (vec.y - Start.y) / (vec.x - Start.x) );
    float b = ( vec.y - (m * vec.x) );
    Line.setFunction(m, b);
    Line.i = Start.x;
    if (m > 0)
    { L_type = 1; }
    else if (m < 0)
    { L_type = 3; }
}

void Bullet::LineToPoint()
{ if (!OutofBounds())
  {
    if(L_type == 2)
    { Bshot.move( 0.0, CurrentSpeed );
    std::cout << "Velocidad: " << CurrentSpeed << std::endl;}
    else
    {
        Bshot.setPosition(Line.i, Line.getM()*Line.i + Line.getB() );
        if (L_type == 1)
        { Line.i +=  CurrentSpeed; }     /**Here I know that for it to work with consistent speeds
for all points I have to multiply the speed with a function
that makes it all move at the same speed regardless of the point,
for example in the 399 case it works well when you multiply it by 0.05,
but I need something that calculates that value from the difference
between the two points  “x”  */

        else if (L_type == 3)
        { Line.i -= CurrentSpeed; }
    }
    std::cout << "Coordinates: " << Bshot.getPosition().x << ", " << Bshot.getPosition().y << std::endl;
///For  output generation.
  }
}
 

And the main function:

int main()
{
   sf::RenderWindow window(sf::VideoMode(800, 600), "Bullet Testing");  
   sf::Event event;
   sf::IntRect d;
   sf::Image img; img.loadFromFile("Images\\Bullets\\HQtest.jpg");
   img.createMaskFromColor(sf::Color::Black, 0);
   sf::Texture Img;
   Img.loadFromImage(img, d);
   Img.setSmooth(true);
   sf::Vector2i vec(400, 300);
  Bullet shot5(399.f, 0.0, 1); shot5.Bshot.setTexture(Img, true);
  /**The samples I took use shot5 with 0.0 and 399 as startlocations, 0.0 being sample1 and 399 being sample2*/
   shot5.Bshot.setColor(sf::Color(50, 25, 208, 200));
   Bullet shot6(400.f, 300.f, 3.f); shot6.Bshot.setTexture(Img, true);
   shot6.Bshot.setColor(sf::Color(50, 208, 25, 200));
  shot5.LinearAssignation(shot6.Bshot.getPosition());
  while (window.isOpen())
    {   window.clear();
        shot5.LineToPoint();
       window.draw(shot5.Bshot);
        window.draw(shot6.Bshot);
        window.display();
    }
Return 0;
}
 

I know it's too long but I tried to cut it as much as possible without taking dependencies out. I am also open to something that might do the same thing but in a different way, your first suggestion is good , but maybe seeing the code might give you an idea of what exactly I am trying to do.  I just chose the mathematical approach because I couldn't think of anything other than that. I will use this code with many bullet objects that shoot themselves in the linear function trajectory based on a reference movable sprite or some other point, yet the "visible" speed must be the same for any point given in the grid.

What I was trying to do when writing these methods was to focus on making it as easy to use as possible, since my final program will sometimes have to deal with 500 moving sprites or even more. I also know that I should make my Bshot sprite private, but for easy testing I am leaving it public for the time being.   

My approach for trying to solve this is in the comments in a function in the code above, yet I don't know which formula may help me do this so I am stuck on someone knowing how to or having an idea of how to do something that reaches the same visual effect.
« Last Edit: September 14, 2012, 05:41:10 am by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Consistent speed on trajectory given by a linear function
« Reply #3 on: September 15, 2012, 04:16:23 pm »
Sorry for double posting but I think I found a solution that doesn't require use of time and will still allow me a constant speed regardless of the two points chosen. I just have to use polar coordinates, if I use a constant angle and use an increasing radius as index there will be no unwanted accelerations or decelerations, the result will be a line that constantly and consistently gets longer with each loop.

I'll change the status to solved if this works out.

Edit: Using polar coordinates did work even better than expected. Still thanks to eXpl0it3r, your algorithm will help me for something I want to implement in the future.
« Last Edit: September 15, 2012, 07:53:02 pm by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10846
    • View Profile
    • development blog
    • Email
Re: Consistent speed on trajectory given by a linear function
« Reply #4 on: September 16, 2012, 01:32:35 pm »
Sorry for double posting...
No problem! :D
It's way better than editing the last posted or so and for me it's not even double posting, since it contains different content. ;D

Edit: Using polar coordinates did work even better than expected. Still thanks to eXpl0it3r, your algorithm will help me for something I want to implement in the future.
I'm grad it worked out.
I wasn't 100% what you wanted and then forgot to answer further... As for the formula it's what you'll find in most of the games for linear movement. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/