Hey guys I’ve been trying to over come the problem of angles wrapping from 360 to 0 or from 0 to 360 and its playing on my mind how to do it I’ve tried all the methods I can think of and still get this problem. It’s a car that gets the angle from a joysticks position (npryces joystick) and i smoothed out the turning which cause the problem of the angle wrapping, anyway here’s the code -:
-- racing
-- Use this function to perform your initial setup
function setup()
controller = VirtualStick {
moved = function(v) steer = v end,
released = function(v) steer = vec2(0,0) end
}
controller:activate()
pos = vec2(WIDTH/2, HEIGHT/2)
steer = vec2(0,0)
speed = 400 -- pixels per second
verts = {vec2(0,5),vec2(0,45),vec2(5,50),vec2(35,50),vec2(40,45),vec2(40,5),vec2(35,0),vec2(5,0)}
car = physics.body(POLYGON,unpack(verts))
car.position = vec2(WIDTH/2,HEIGHT/2)
car.interpolate = true
car.sleepingAllwoed = false
car.gravityScale = 0
carm = mesh()
carm:setColors(255,255,255,255)
carr = carm:addRect(car.x,car.y,40,50,0)
ang = 0
end
function clamp(x, min, max)
return math.max(min, math.min(max, x))
end
function angleOfPoint( pt )
local x, y = pt.x, pt.y
local radian = math.atan2(y,x)
local angle = radian*180/math.pi
if angle < 0 then angle = 360 + angle end
return angle
end
-- This function gets called once every frame
function draw()
pos = pos + steer*speed*DeltaTime
-- This sets a dark background color ()
background(40, 40, 50)
-- This sets the line thickness
strokeWidth(5)
if steer:len()>0.2 then
car.linearVelocity = car.linearVelocity+steer*30
end
car.linearVelocity.x = clamp(car.linearVelocity.x,-59,50)
car.linearVelocity = car.linearVelocity*0.95
if steer ~= vec2() then
angle = angleOfPoint(steer)
ang = (angle+90-car.angle)/10
else
ang = 0
end
car.angle = clamp(car.angle + ang,-1,181)
if car.angle > 180 then
car.angle = -180+car.angle
end
-- Do your drawing here
controller:draw()
carm:setRect(carr,car.x,car.y,40,50,car.angle/57.3)
carm:draw()
end
-------------
Controller = class()
function Controller:activate()
touched = function(t)
self:touched(t)
end
end
function Controller:draw()
-- nothing
end
-- Utility functions
function touchPos(t)
return vec2(t.x, t.y)
end
function clamp(x, min, max)
return math.max(min, math.min(max, x))
end
function clampAbs(x, maxAbs)
return clamp(x, -maxAbs, maxAbs)
end
function clampLen(vec, maxLen)
if vec == vec2(0,0) then
return vec
else
return vec:normalize() * math.min(vec:len(), maxLen)
end
end
-- projects v onto the direction represented by the given unit vector
function project(v, unit)
return v:dot(unit)
end
function sign(x)
if x == 0 then
return 0
elseif x < 0 then
return -1
elseif x > 0 then
return 1
else
return x -- x is NaN
end
end
function doNothing()
end
--------
VirtualStick = class(Controller)
function VirtualStick:init(args)
self.radius = args.radius or 100
self.deadZoneRadius = args.deadZoneRadius or 25
self.releasedCallback = args.released or doNothing
self.steerCallback = args.moved or doNothing
self.pressedCallback = args.pressed or doNothing
touches = {}
pos1 = vec2()
pos2 = vec2()
nt={}
end
function abs(v2)
return math.abs(v2)
end
function VirtualStick:touched(t)
local pos = touchPos(t)
if t.state == BEGAN and self.touchId == nil then
self.touchId = t.id
self.touchStart = pos
self.stickOffset = vec2(0, 0)
self.pressedCallback()
elseif t.id == self.touchId then
if t.state == MOVING then
self.stickOffset = clampLen(pos - self.touchStart, self.radius)
self.steerCallback(self:vector())
elseif t.state == ENDED or t.state == CANCELLED then
self:reset()
self.releasedCallback()
end
end
end
function VirtualStick:vector()
local stickRange = self.radius - self.deadZoneRadius
local stickAmount = math.max(self.stickOffset:len() - self.deadZoneRadius, 0)
local stickDirection = self.stickOffset:normalize()
return stickDirection * (stickAmount/stickRange)
end
function VirtualStick:reset()
self.touchId = nil
self.touchStart = nil
self.stickOffset = nil
end
function VirtualStick:draw()
if self.touchId ~= nil then
pushStyle()
ellipseMode(RADIUS)
strokeWidth(1)
stroke(255, 255, 255, 255)
noFill()
pushMatrix()
translate(self.touchStart.x,self.touchStart.y)
fill(150,150,150,100)
ellipse(0, 0, self.radius, self.radius)
fill(164, 164, 164, 150)
ellipse(0, 0, self.deadZoneRadius, self.deadZoneRadius)
fill(150,150,150,100)
translate(self.stickOffset.x, self.stickOffset.y)
ellipse(0, 0, 25, 25)
popMatrix()
popStyle()
end
end