开发者

Calculate a circular wrapper?

开发者 https://www.devze.com 2023-03-09 02:20 出处:网络
I just started learning iphone development and after a friend recommended Corona SDK for the ease of use I finally decided to try it out.

I just started learning iphone development and after a friend recommended Corona SDK for the ease of use I finally decided to try it out.

Now, I've just started learning how to use the accelerometer and drawing shapes and make them move around by tilting the device. So I thought I could make a level tool as my first app and I got everything working when I tilt, but now I decided to try to make a flat level but I can't figure out how to make the bubble stay within a circle.

Heres how I limit the bubble from moving outside the vial in the horizontal level:

function bubbleBounds()
    -- left side
    if bubble.x < (_W/2 - vial.width/2 + bubble.width/2) then 
       bubble.x = (_W/2 - vial.width/2 + bubble.width/2)
    end

            -- right side
    if bubble.x > (_W/2 + vial.width/2 - bubble.width/2) then
       bubble.x = (_W/2 + vial.width/2 - bubble.width/2)
    end
    end

I have learned that you should always make images with the power of 2, so I made a circle with a diameter of 256 pixels and my bubble is 64 pixels.开发者_开发问答 How do I write a function that limits the bubble from moving outside the circle?

Thanks Cindy


@Mac, I know about the icon sizes but the power of 2 is just used in games for memory optimization, right?

@Tim C;

So if I write my bounds function like this;

local bubbleRadius = 32
local circleRadius = 128
local sqrt = math.sqrt
local centerX = display.contentWidth/2;
local centerY = display.contentHeight/2;

local function bubbleBounds()
       Length = sqrt(centerX * centerX + centerY * centerY)
       normalizedX = centerX/Length;
       normalizedY = centerY/Length;

       limitedX = normalizedX * circleRadius;
       limitedY = normalizedY * circleRadius;

       if bubble.x < centerX - limitedX + bubbleRadius then
          bubble.x = centerX - limitedX + bubbleRadius
       end

       if bubble.x > centerX + limitedX - bubbleRadius then
          bubble.x = centerX + limitedX - bubbleRadius
       end

       if bubble.y < centerY - limitedY + bubbleRadius then
          bubble.y = centerY - limitedY + bubbleRadius
       end

       if bubble.y > centerY + limitedY - bubbleRadius then
          bubble.y = centerY + limitedY - bubbleRadius
       end

 end
 Runtime:addEventListener("enterFrame", bubbleBounds)

But now when I run this it's rectangular wrapper and not a circle, the accelerometer also acts real strange and laggy. Here's how I set up the accelerometer:

    local acc = {}

function acc:accelerometer(event)
        bubble.x = centerX - (centerX * event.yGravity * 2);

    bubble.y = centerY - (centerY * event.xGravity * 2);
    end
    Runtime:addEventListener("accelerometer", acc)

Where did it all go wrong?


What you need here is to calculate the vector from the center of your circle to the bubble object, and limit movement to never exceed the radius of your circle.

To do this, take the vector from the center of your circle to the bubble object, normalize it, and then multiply it by the radius of the circle. This will resut in a new vector with the same angle as your original, but limited to within the bounds of the circle.

For example, assuming the center of the circle is 0,0 and the position of the bubble is x,y.

Pseudo Code:

Length = sqrt(x*x + y*y);  //pythagorean theorem

normalizedX = x/Length;
normalizedY = y/Length;

limitedX = normalizedX * circleRadius;
limitedY = normalizedY * circleRadius;

Additionally, in order to prevent the bubble from breaking the bounds of the circle at all, you should use the radius of the circle minus the radius of the bubble as your limiting radius.


After looking at the newly posted code, the problem appears to be in how you've implemented the math.

First off, the length calculation should be for the vector of the bubble, not of your center point.
Secondly, you're still checking the bounds on each axis individually against the radius. This will always result in a rectangular bounding box, unless you do things based purely on the length of the vectors from the center.

Try something like this instead:

local bubbleRadius = 32;
local circleRadius = 128;
local sqrt = math.sqrt;
local centerX = display.contentWidth/2;
local centerY = display.contentHeight/2;

local function bubbleBounds()

   bubbleX = bubble.x - centerX;
   bubbleY = bubble.y - centerY;

   Length = sqrt(bubbleX * bubbleX + bubbleY * bubbleY);

   normalizedX = bubbleX/Length;
   normalizedY = bubbleY/Length;

   if Length > circleRadius then
       bubbleX = normalizedX * circleRadius;
       bubbleY = normalizedY * circleRadius;
       bubble.x = bubbleX + centerX;
       bubble.y = bubbleY + centerY;
   end
end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号