简体   繁体   中英

What could be causing this “drone” to be jittery when turning at certain angles?

http://codepen.io/AlexKM/pen/JGEMjZ

turnTo: function (X, Y) {
    var angleDiff = 0,
        targetA = this.angleToPoint({
            x: X,
            y: Y
        }),
        dronA = this.angle;
    ///   If the angle difference can't be reached in a frame
    if (Math.abs(targetA - dronA) > this.turnSpeed * 1.25) {
        this.workingAngle = true;
        angleDiff = targetA - dronA;
        while (angleDiff < 0)
            angleDiff += 2 * Math.PI;
        while (angleDiff > 2 * Math.PI)
            angleDiff -= 2 * Math.PI;

        if (angleDiff >= Math.PI) {
            this.turningLeft = true;
        } else {
            this.turningRight = true;
        }

    } else ///  if the diff is negligible, reach it to save CPU
        this.angle = targetA;
},

Update function snippet dealing with actual turning:

    // apply turning
    if (this.turningLeft) {
        this.angle -= this.turnSpeed;
    }
    else if (this.turningRight) {
        this.angle += this.turnSpeed;
    }

Red dot - drone facing
Orange dots - signal if the drone is turning left or right
Cyan dot - signal if the drone is recalculating angles/doing trigonometry

The code DOES contain a part which helps it smooth out, by basically simply setting to the mouse's angle if it can be reached within a frame from the testDrone.turnSpeed variable.

About half the time, it turns and works smoothly. The other half, it goes jittery, alternatively turns left and right and continuously calculates trig.

What could be the reason for this?

Nice script. :)

I think the jitteriness may be a function of the difference between the (framerate ( fps ) + processing time) and the refresh rate of the monitor. I say this because sometimes it seems smooth and sometimes it goes a bit lumpy, and there doesn't seem to be a particular pattern about that as far as mouse position/movement goes.

Have you thought about using requestAnimationFrame() over setTimeout() ? See MDN HERE , which states...

This will request that your animation function be called before the browser performs the next repaint. The number of callbacks is usually 60 times per second, but will generally match the display refresh rate in most web browsers as per W3C recommendation.

See markE 's response to this StackOverflow question about throttling requestAnimationFrame calls to a particular framerate.

Hope that helps. :)

What fixed it was making sure the angles are actually RESET to certain values rather than being inc/decremented by Pi when they go past a certain limit. It was a design fault on my part, since the jitter elimination didn't work for angles "above" Pi or "below" Pi

This was meant to go in the update function:

update: function (ctx) {
    // reset angles below and above 2pi
    while (this.angle > Math.PI)
        this.angle = -Math.PI;
    while (this.angle < -Math.PI)
        this.angle = Math.PI;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM