setorigin within a movetype_push's think function is a special case. the movement is detected upon return and the engine pushes all entities to get the pusher to match the setorigin.
Its common to call setorigin to try to kill any precision errors from SUB_CalcMove.
you can only 'swerve' around corners by updating the velocity in fairly small time increments. SUB_CalcMove can be used to update the velocity, but you need to calculate the position yourself and do the repeated callings each time it reaches the previous point.