Hi
My need is to decrease the rebound angle of a ball.
In the attached photos I show in orange what happens and in green what I would like:
Thanks to the help of @StarCrunch and @roaminggamer, I made the following code that only works in part and I still can not get to the green conclusion:
local physics = require("physics") physics.setDrawMode( "hybrid" ) --debug hybrid normal physics.start() physics.setGravity( 0, 0 ) --"math2do" taken from the examples of @roaminggamer local math2do = {} local mRad = math.rad local mCos = math.cos local mSin = math.sin local mSqrt = math.sqrt function math2do.dot( ... ) -- ( objA, objB ) or ( x1, y1, x2, y2 ) local retVal = 0 if( type(arg[1]) == "number" ) then retVal = arg[1] \* arg[3] + arg[2] \* arg[4] else retVal = arg[1].x \* arg[2].x + arg[1].y \* arg[2].y end return retVal end function math2do.scale( ... ) -- ( objA, scale [, altRet] ) or ( x1, y1, scale, [, altRet] ) if( type(arg[1]) == "number" ) then local x,y = arg[1] \* arg[3], arg[2] \* arg[3] if(arg[4]) then return { x=x, y=y } else return x,y end else local x,y = arg[1].x \* arg[2], arg[1].y \* arg[2] if(arg[3]) then return x,y else return { x=x, y=y } end end end function math2do.length( ... ) -- ( objA ) or ( x1, y1 ) local len if( type(arg[1]) == "number" ) then len = mSqrt(arg[1] \* arg[1] + arg[2] \* arg[2]) else len = mSqrt(arg[1].x \* arg[1].x + arg[1].y \* arg[1].y) end return len end function math2do.normalize( ... ) -- ( objA [, altRet] ) or ( x1, y1 [, altRet] ) if( type(arg[1]) == "number" ) then local len = math2do.length( arg[1], arg[2], false ) local x,y = arg[1]/len,arg[2]/len if(arg[3]) then return { x=x, y=y } else return x,y end else local len = math2do.length( arg[1], arg[2], true ) local x,y = arg[1].x/len,arg[1].y/len if(arg[2]) then return x,y else return { x=x, y=y } end end end function math2do.angle2Vector( angle, tableRet ) local screenAngle = mRad(-(angle+90)) local x = mCos(screenAngle) local y = mSin(screenAngle) if(tableRet == true) then return { x=-x, y=y } else return -x,y end end --====-- --ball-- --====-- local ballSpeed = 100 local ball = display.newCircle( 160, 50, 15 ) ball:setFillColor( 1, 0, 0 ) physics.addBody( ball, {density=0.1, radius = 15, bounce = 0.7, friction = 1 } ) ball.isBullet = true local PrevVX, PrevVY function Correct (vx, vy) -- velocity to correct local lx, ly = math2do.normalize(PrevVX, PrevVY) -- "left" (we don't care about the length) local ux, uy = ly, -lx -- "up" local htf\_len vx, vy = math2do.normalize(vx, vy) local dot = math2do.dot(lx, ly, vx, vy) local angle = math.acos(dot) if math.deg(angle) \>= 160 then return ux \* ballSpeed, uy \* ballSpeed -- for corrections using other reflection angles (in radians), do: -- local ca, sa = math.cos(ref\_angle), math.sin(ref\_angle) -- local dir\_x, dir\_y = ca \* lx + sa \* ux, ca \* ly + sa \* uy -- return dir\_x \* ballSpeed, dir\_y \* ballSpeed else return vx \* ballSpeed, vy \* ballSpeed -- original direction fine end end local enterFrame = function( self ) local vx,vy = self:getLinearVelocity() vx,vy = Correct(vx, vy) PrevVX, PrevVY = vx, vy self:setLinearVelocity( vx, vy ) end local angleStart = 180 local vec = math2do.angle2Vector( angleStart, true ) vec = math2do.scale( vec, ballSpeed ) ball:setLinearVelocity( vec.x, vec.y ) PrevVX, PrevVY = vec.x, vec.y ball.enterFrame = enterFrame Runtime:addEventListener( "enterFrame", ball ) --========-- --obstacle-- --========-- local points = { -7.8459095727845 ,99.691733373313, -15.643446504023 ,98.768834059514, -23.344536385591 ,97.236992039768, -30.901699437495 ,95.105651629515, -38.268343236509 ,92.387953251129, -45.399049973955 ,89.100652418837, -52.249856471595 ,85.264016435409, -58.778525229247 ,80.901699437495, -64.944804833018 ,76.040596560003, -70.710678118655 ,70.710678118655, -76.040596560003 ,64.944804833018, -80.901699437495 ,58.778525229247, -85.264016435409 ,52.249856471595, -89.100652418837 ,45.399049973955, -92.387953251129 ,38.268343236509, -95.105651629515 ,30.901699437495, -97.236992039768 ,23.344536385591, -98.768834059514 ,15.643446504023, -99.691733373313 ,7.8459095727845, -100, 2.4492935982947e-014, } local obstacle = display.newRect( 240, 300, 10, 10 ) physics.addBody( obstacle, "static", { chain = points, } )
first part of the question here (https://forums.coronalabs.com/topic/73586-constant-speed-ball-after-collision/#entry387526)
It’s possible you’ll still run into this situation, say when hitting a wall at a right angle.