(resolved) Require help with getting velocity limit to work properly

I’ve placed a velocity limit on a circle as it moves around the screen. However, when the velocity limit is reached the circle stops turning smoothly and will lock onto diagonals. When you run the code below you will see that the line that turns in the middle of the circle keeps on locking onto the diagonals when tilting the iPad when at maximum velocity.

Any help with this problem is appreciated. Thanks. :slight_smile:


--# Main

function setup()
    ball = Ball()
    supportedOrientations(PORTRAIT)
    parameter.watch("ball.acceleration")
    parameter.watch("ball.velocity")
    parameter.watch("ball.position")
end

function draw()
    ball:update()
    background(0, 0, 0)
    ball:draw() 
end


--# Ball

Ball = class()

function Ball:init()
    self.acceleration = vec2(0, 0)
    self.velocity = vec2(0, 0)
    self.velocityLimit = vec2(2, 2)
    self.position = vec2(WIDTH/2, HEIGHT/2)
    self.radius = 50
    strokeWidth(2)
end

function Ball:screen_bounds()
    if self.position.x < self.radius then
        self.position.x = self.radius
    elseif self.position.x > WIDTH-self.radius then
        self.position.x = WIDTH-self.radius
    end
    
    if self.position.y < self.radius then
        self.position.y = self.radius
    elseif self.position.y > HEIGHT-self.radius then
        self.position.y = HEIGHT-self.radius
    end 
end

function Ball:velocity_limit()
    if self.velocity.x < -self.velocityLimit.x then
        self.velocity.x = -self.velocityLimit.x
    elseif self.velocity.x > self.velocityLimit.x then
        self.velocity.x = self.velocityLimit.x
    end
    
    if self.velocity.y < -self.velocityLimit.y then
        self.velocity.y = -self.velocityLimit.y
    elseif self.velocity.y > self.velocityLimit.y then
        self.velocity.y = self.velocityLimit.y
    end 
end

function Ball:update()
    self.acceleration.x = Gravity.x
    self.acceleration.y = Gravity.y
    self.velocity = self.velocity + self.acceleration
    self:velocity_limit()
    self.position = self.position + (self.velocity * (60*DeltaTime))
    self.velocityNormalize = self.velocity:normalize()  -- draw the ball line
    self:screen_bounds()
end

function Ball:draw()    
    pushStyle()
    fill(28, 68, 148, 255)
    ellipse(self.position.x, self.position.y, self.radius*2)
    line(self.position.x, self.position.y,
         self.position.x + (self.velocityNormalize.x * (self.radius * 0.8)),
         self.position.y + (self.velocityNormalize.y * (self.radius * 0.8)))
    popStyle() 
end

You need to take the length of the velocity vector and measure it. If it’s too long, normalize the velocity and times it by speed.

Untested changes, but should work:
in init()

self.velocityLimit = 3 --max allowed length

in velocity_limit()

if self.velocity:len()>self.velocityLimit then
local norm=self.velocity:normalize()
self.velocity=norm*self.velocityLimit
end

Your code works beautifully, this is exactly the result I’m after.

Thanks for taking the time to help me yojimbo2000. :smiley:

Glad it worked, no worries!