How do I use cosp with angles?

0 favourites
  • 14 posts
  • I need an Ease-In-Out (Quad or Quart) dealing with rotation and angles.

    can anyone help? ... InOut.capx

  • While lerp() can be used for easing out, there's no way to do easing that way.

    The main way to use easing like that is this:


    Although that's not really suitable for a moving target like yours.

    You could treat it a bit different by using angular speed. Basically just accelerate toward the target and decelerate to stop at the angle exactly.

    For that you could use this older example: ... rret2.capx

  • thanks R0J0hound ! This is actually for a top-down space shooter.. I have a big heavy cruiser that catches up with the player (in a straight line making course corrections until the ship is in range). Once the Cruiser is in range, it slows down and uses it's 360 degree cannon to shoot at the player. Once the player is out of range the Cruiser needs to pursue. This is where the easing comes in.. If the Cruiser needs to rotate it looks horrible with lerp() because there is no easing into the rotation - it happens way too fast - and if I slow the rate down, the ship does WAY too big of a loop to catchup to the player. It looks fine easing out of the rotation.

    I'm just trying to make the movement seem semi-realistic due to the size of the ship - with so much mass you'd probably see slow and small rotations.

    so currently I'm doing:


    and instead I need:


    The one bug is if the course corrections(Cruiser ship rotation) are still happening when the target is in range. (because it's not supposed to rotate when the target is in range). The rotation suddenly stops - which kills the easing. But I've coded for that giving the ship some fake "aftertouch" which helps it looks like it'm slowing down to a natural speed. Even if it over shoots it doesn't matter since the ship has a gun with a 360 degree range - as long as it's headed in the direction of the player its fine.

    thanks for the capx.. that looks perfect! it should work!

  • The main way to use easing like that is this:

    yes I've used lerp and cosp already just like this.. I was just hoping to use cosp with angles. I would definitely request an anglecosp() function.. how else is there to ease in/out simply.

    your old turret capx is a good work around though- thanks. I should be able to adapt it to my needs but it would be so much more simple to have 1 math function. I wonder if I could just do an Ease In and then fake the Ease Out. I could do the lerp backwards somehow..

  • The difference between lerp and anglelerp is anglelerp lerps in the closest direction.

    Also I'd like to point out that while something like:

    lerp(a, b, 0.5) will give an easing out effect, so will cosp(a,b,0.5), qarp(a,b,c,0.5) ... etc.

    As long as a constant value is used for any of the interpolation functions it will only give an easing out effect.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • R0J0hound cosp seems to have an Ease In effect as well no?

    I've used lerps inside of a lerp..

    i.e. lerp(lerp(a,b,0.1),lerp(c,d,0.1),0.1)

    it depends on the application but maybe I can give lerp an Ease In effect by changing both values at different rates?? (now I'm starting to go over my own head)

  • although for easein&out seems like you would need a 4th value that defines the curve maybe?

  • In the first link I posted I did show how to use interpolation for all easing effects. What I'm saying is only using a fixed value (0.1 is fixed) for the last parameter won't give anything but an easing out effect.

    Basically all the interpolation functions define some kind of curve from a to b. For example cosp() could look like this:

     |   `-.      
     |      `.
     |        `.
     |           |           \           
     |             |             \          
     |              \         
     |               `.         
     |                 `.       
     |                   `-.    
    b|                     `--,
     0                        1[/code:1n6dc089]
    The last parameter specifies a location along this curve from 0 to 1.  Now if you gradually increase that value from 0 to 1 you'll get whatever easing as the curve provides.  If you instead just use a fixed value for the last parameter and keep changing "a" then none of the functions will give any advantage over just using lerp.
    But the best proof is to try it.
  • What I'm saying is only using a fixed value (0.1 is fixed) for the last parameter won't give anything but an easing out effect.t.

    okay, I'll give that a try.. thanks!

  • R0J0hound I'm trying to use the angle as the last lerp parameter, so that when the rotation makes a smaller angle the last parameter will change... the only probably is the angle gets smaller. I need that number to go up to make an easing-in effect. any ideas?

    I could just make a variable I supposed and add dt to it, but it seems like I would want to relate it to the difference in angle..


    spriteA angle: 180

    spriteB angle: 0

    rotating sprite A:

    anglelerp(spriteA.angle,spriteB.angle,0.05) - creates a nice easing out effect, but the start is too abrupt.

    instead I'm trying:

    anglelerp(spriteA.angle,spriteB.angle,angle(spriteA,spriteB) / 10000) //works similar unless I can figure out how to get the last number to go up instead of down.

    feels like I should add 180 or something to it... since my greatest angle would be 180? (which I would want to be 0.001) and my closest angle would be 0 (which I'd want to be 0.05).. but so far it's not working.. any suggestions?

    EDIT: I was saying anglediff but I just meant angle()

  • updated capx

    once the "X" leaves the dotted circle, the blue pointer jumps(rotates) too fast toward the X, would love to figure a way for the pointer to: ease into the rotation, increase speed midway, then near the end, slow down...

  • okay, update..

    I was able to make it better, but it's still not quite right.. it's definitely better.. but there must be a real way to do it.

    Every Tick Set Pointer.angle_diff_to_x to anglediff(Self.Angle,angle(self.X,self.Y,PointToThis.X,PointToThis.Y))

    T=min(abs(self.anglediff_to_x - 180) * (0.02/180),1)

    Pointer Set Angle: anglelerp(self.Angle,angle(self.X,self.Y,PointToThis.X,PointToThis.Y),T)

    This is nightmarish.. I'm spending days and days just trying to get the movement right... ready to scrap it a design a different movement...

  • jobel

    You can't do it with just one formula, you need a variable that you change over time to do it.

    One you could use is speed. It starts as 0 and it increases over time so you get an easing in effect.

    Add 100*dt to speed

    rotate self.speed*dt degrees toward target_angle

    In the actions above the 100 is the acceleration.

    You can also make an easing out effect with it by giving speed an initial speed and using negative acceleration to slow it down.

    Set speed to max(self.speed-100*dt, 0)

    rotate self.speed*dt degrees toward target_angle

    The max() is used above so the speed never becomes negative. The one problem is you need to handle is if the start speed is too low the sprite will stop short. To fix that we can calculate what the speed should start at with:

    speed= sqrt(anglediff(self.angle, target_angle)*2*100)

    Or instead of 100 use whatever you're using as an acceleration.

    Next to do an easing in-out effect (which is basically what the first capx I posted) you can accelerate or deccelerate depending on the stopping distance which can be calculated with:

    dist = (speed^2)/(2*acceleration)

    So then it can be reduced to two actions as follows:

    global number acceleration=100

    global number target_angle =270

    every tick:

    --- set speed to max(0,(((self.speed^2)/(2*acceleration)<anglediff(self.angle, target_angle))?acceleration:-)acceleration)

    --- rotate self.speed*dt degrees toward target_angle

    You may also want to reset the speed to 0 when the target is reached.

    Here's a capx: ... n_out.capx

    It differs from the first capx in that it doesn't try to be physically accurate.

  • Thanks R0J0hound I'll check it out! (I very much appreciate the help!)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)