Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
New day, new problems :) (Rotate an physics object towards direction of movement) — Gideros Forum

New day, new problems :) (Rotate an physics object towards direction of movement)

kontinyukontinyu Member
edited March 2013 in General questions
So i have a complex body which is combined from a triangle and a rectangle (think this as a fish)
When my fish bounces of a border of my pool i want my fish to turn towards direction of movement (because fish can't swim backwards - duh!)
I've tried "body:setAngle(-body:getAngle())" on collision but no luck there as always :)
I probably need to get it's moving direction and then rotate it on Enter Frame event.
unfortunately i have no idea about formula

Comments

  • ar2rsawseenar2rsawseen Maintainer
    @kontinyu how do you set movement direction?
    You probably provide a vector for setLinearVelocity right?
    So if you have xVect and yVect for direction, then you can calculate the angle as
    --calculate vector length
    local length = math.sqrt(xVect*xVect + yVect*yVect)
    --calculate angle
    local angle = math.acos(yVect/length)
     
    --if 0 radians is up (default state of image is up)
    if(xVect > 0) then
    	angle = -angle
    end
  • kontinyukontinyu Member
    edited March 2013
    @ar2sawseen Actually i'm using this formula to bounce them back from pool borders;
    secondbody:applyLinearImpulse( 2*math.cos( secondbody:getAngle()-1.5 ) ,2*math.sin( secondbody:getAngle()-1.5 ) ,0,0)

    And it seems like it's not working with your code, shoul i try different "bounceback" formulas?
  • Okay! I give up.
    I hate to do this but i've been working on this problem since this morning and i can't figure it out. I believe my trigonometry is really bad :(
    Sadly as you can see in attachment i've got some fish in a fishtank. And sadly i need some working code from you guys. If someone can give me proper functions to
    1- bounce the fish (calculate from original angle etc.)
    2- Set rotation of body as direction of movement.
    I'm using this as a solution to my first problem; secondbody:applyLinearImpulse( 2*math.cos( secondbody:getAngle()-1.5 ) ,2*math.sin( secondbody:getAngle()-1.5 ) ,0,0)
    It works, but not perfect. I think there's something wrong with it too...
    And @ar2sawseen's solution to my second problem seems not to work.
    So thanks in advance. I know i'm asking for a lot.
    Believe me i tried :]
    Untitled.png
    500 x 253 - 11K
  • Have you tried messing with the restitution (I'd try 1 if they're not supposed to lose speed) of the fish and relying on the default collision instead of manually applying an impulse to bounce off?

    Also, what didn't work about @ar2rsawseen's code?
  • kontinyukontinyu Member
    edited March 2013
    Have you tried messing with the restitution (I'd try 1 if they're not supposed to lose speed) of the fish and relying on the default collision instead of manually applying an impulse to bounce off?

    Also, what didn't work about @ar2rsawseen's code?
    Wow i liked the restitution. It can be used for what i need. It's not perfect like the other option. But since i can't get it work, i could use this for now.

    Well basicly it's not setting the direction correctly. ie. my body goes directly left. and the
    "angle" reports 180 degrees. I need it to be -180. and i put a "-" before it. but my body doesnt budge. and keeps his head just the opposite way.

    I think this is maybe where magic happens, but i couldn't fix it.
    if(xVect > 0) then
    angle = -angle

    end
  • ar2rsawseenar2rsawseen Maintainer
    edited March 2013
    @kontinyu
    Firstly I agree that your bounce function seems kind of "interesting", but I don't have any better to suggest right now :)

    Secondly there can be multiple problems, but I'd need to know what happens. Does your object has incorrect direction of image, or image keeps rotating, or something else?

    You see, you apply impulse to 0 0 world coordinates, which in most cases is outside of your object, which in most cases would result in rotation of body.

    So firstly you could try applying impulse to the center of object as
    local x, y = secondbody:getPosition()
    secondbody:applyLinearImpulse( 2*math.cos( secondbody:getAngle()-1.5 ) ,2*math.sin( secondbody:getAngle()-1.5 ) ,x,y)
    Secondly as stated my code was provided when default state of image is up (your fish is looking up, when you look at plain image). If you default position is other, then it should be applied a little differently or you should apply little offset.

    Thirdly you might be applying rotation to image, whereas you need to apply it to body.

    Fourthly body may still be rotating, so you could apply setAngularVelocity(0) before changing angle.

    Basically lots of things can be wrong. :)


    So provide anything you can, description of what happens, screenshots, videos using http://screenr.com or even code blocks, and we will try to help you ;)
  • @kontinyu

    Secondly as stated my code was provided when default state of image is up (your fish is looking up, when you look at plain image). If you default position is other, then it should be applied a little differently
    ""or you should apply little offset."" --> i probably should :) but i couldn't fix it whatever i tried.

    Thirdly you might be applying rotation to image, whereas you need to apply it to body. --> i don't think thats my problem. I'm using another onEnterFrame listener to cycle through sprites and repositions them.

    Fourthly body may still be rotating, so you could apply setAngularVelocity(0) before changing angle. --> i don't think thats it too...

    Basically lots of things can be wrong. :) --> yeah i figured. believe me :D
    I'm going crazy about this.


    So provide anything you can, description of what happens, screenshots, videos using http://screenr.com or even code blocks, and we will try to help you ;)
    SOO here is my problem as a video :)
    http://www.screenr.com/pOz7
  • ar2rsawseenar2rsawseen Maintainer
    Oh, ok, looks kind of cool :)
    Is the default state of your fish image is fish looking to the right?
  • kontinyukontinyu Member
    edited March 2013
    Oh, ok, looks kind of cool :)
    Is the default state of your fish image is fish looking to the right?
    haha thanks!
    well my fish "image" state is "up"
    but my fish "body" state is looking "left" i believe. i could change them to be the same. but i wanna be sure before mess with my physic body.
    Do you think thats causing my problem?
    EDIT: I've tried every position for my fish "image" and it still don't set "true angle" .
  • ar2rsawseenar2rsawseen Maintainer
    Accepted Answer
    Ok, it's completely my fault, it's actually meant for the downwards fish, for upwards you need to add math.pi to it.

    I've attached example project to this post

    And here's an example video:
    http://www.screenr.com/4cz7
    zip
    zip
    Box2D_draggable_fish.zip
    16K

    Likes: kontinyu

    +1 -1 (+1 / -0 )Share on Facebook
  • petecpetec Member
    That's good. I did notice that every time the fish hits a side wall it turns upside down compared with it's orientation before the collision. Did you mean that?
  • kontinyukontinyu Member
    edited March 2013
    @ar2sawseen; I can't thank you enough for your efforts and time.
    My fish swims happily in the pond now.
    There is only one problem left, when they bounce back, fish "image" needs to flip on y-axis because fish can't swim upside down too. I think i can manage that. but if you have any ideas out of your head, please shoot out :)

    Anyways, thank you :]
  • I think to flip on y-axis you can setScaleY(-1) (assuming your anchor point is in the middle)
  • ar2rsawseenar2rsawseen Maintainer
    Flipping might be one of the solutions, but I don't know if it would mess some internal rotation
    So other solution would be using flipped image as second one.
    So for example fish.png is your normal image and fish2.png is your flipped image, then simply modify code as:
    if(xVect > 0) then
    	angle = -angle
    end
     
    angle = angle + math.pi
     
    if angle <= math.pi/2 and angle >= 0 then
    	self.ball:setTexture(Texture.new("fish2.png", true))
    elseif angle <= math.pi and angle > math.pi/2 then
    	self.ball:setTexture(Texture.new("fish2.png", true))
    elseif angle <= 1.5*math.pi and angle > math.pi then
    	self.ball:setTexture(Texture.new("fish.png", true))
    elseif angle <= math.pi*2 and angle > 1.5*math.pi then
    	self.ball:setTexture(Texture.new("fish.png", true))
    end
     
    self.ball.body:setAngle(angle)
  • the problem of rotation is in the simulation . I can see that bodies not collide as they should. You need to check your angular dampening and friction of the fixtures. Combined with density they are responsible for rotation of the body after the collision. Also the shape of the fixture is not very good for fish natural movement simulation. I would suggest to use polygon with front part shape closer to fish head. I am solving same case in my project and box2d implementation in Gideros do it just fine.
Sign In or Register to comment.