A Flash Developer Resource Site

Results 1 to 19 of 19

Thread: Adjusting Angles of a Physics Engined object

  1. #1
    Member
    Join Date
    Dec 2007
    Posts
    85

    Adjusting Angles of a Physics Engined object

    I've been building an application using a physics engine that has the user aim and launch a cannon shell. It uses a physics engine to simulate its firing. That said, however, I cannot make it simulate being at the proper angles while flying through the air.

    http://www.cove.org/ape/index.htm

    This is the engine I'm using.

    I can already obtain the initial angle the shell should be when the cannon is fired, as well as the velocity, both along the x and the y, of the shell. I am hopefully looking for a math formula that could then get the proper angle.

    In addition, I have a weird, minor problem. I recently added a one pixel line, which was designed to simulate a ground. However, when it's there, the shell won't be shown by the code anymore when the user fires the cannon. When I remove it, the shell is shown once again. I'm not too sure what the cause of it is.

  2. #2
    Senior Member
    Join Date
    Oct 2007
    Location
    Leeds, UK
    Posts
    118
    You want the gradient at any point of the curve traced by the shell as it zooms through the air.

    If it leaves the ground with horizontal velocity H, and vertical velocity V,
    then by my reckoning the angle you're looking for at any point on its trajectory is

    Code:
    Math.atan(V/H - g*x/Math.pow(H,2))
    where V,H are the initial velocities as already stated,
    g is the acceleration due to gravity (roughly 10 metres per second, per second)
    and x is the horizontal distance travelled since being fired.

    My guess is you're going to have to play around with the value you give g until you get something that 'looks right' but hopefully this will give you enough to make a start.

    EDIT: That's the angle between the trajectory and the horizontal by the way.
    Last edited by DiamondDog; 06-17-2008 at 01:13 PM.

  3. #3
    Member
    Join Date
    Dec 2007
    Posts
    85
    After looking through my code and at the formula given, I can get all but gravity. Should I just try working with a hard-coded number for gravity, or is there a way I could "make" gravity with the FPS of the Flash and aspects of the engine that define gravity?

  4. #4
    Senior Member
    Join Date
    Oct 2007
    Location
    Leeds, UK
    Posts
    118
    I don't know how these engines work, so it's diffcult for me to advise you.

    My guess is you could start with a hard-coded value for g and play around with it until you get something that looks right.

    If it helps, the horizontal range of a shell - that's the distance it travels horizontally before coming back down to earth (assuming it doesn't hit anything on the way!) - should be 2HV/g (assuming no air resistance).

  5. #5
    Member
    Join Date
    Dec 2007
    Posts
    85
    Ok, tried inputting a hard number. Actually, I used several. Each time, I hit the same thing: The numbers were simply TOO small to be of any use to me.

    This, of course, could be because of the velocities, but I doubt it.

    I used the same formula, got the values for the initial vertical and horizontal velocities, got the distance traveled, and hardcoded a gravity that accurately matched the force I used earlier to "create" gravity. However, the results always came out to be between -0.1 and -0.2, which just seemed useless to me. Is there anything missing by chance?

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Instead of trying to fake the rotation, why not let the physics engine handle it for you? Simply make your projectile have some rotational inertia by making it have some length in the physic engine (make it a long box instead of a point or circle, or two joined points, or something like that). It may "just work" doing that. If not, you can probably get it to work by applying the launch forces to just one end of the projectile (the "front", I'd think). The other end should trail behind automatically. If that doesn't work, you could explicitly tell the physics engine that the projectile has some angular momentum, so it'll rotate during flight.

  7. #7
    Member
    Join Date
    Dec 2007
    Posts
    85
    That's how it's designed now. Simply put, this engine doesn't seem to have the natural capability to do that.

    I'm using a rectangle-shaped projectile, the code knows it is being fired at an angle, yet it lacks the ability to do to the curve. It remains at the same angle the entire time until it hits a surface, at which point it will change.

    This is why I'm trying to force it.

    Edit: Ok, turns out I'm a dummy, haha.

    I forgot to convert the radians to degrees. Did that and it now looks like it's rotating. Also did some tweaking and it overall is fine. However...

    As the angle for firing increases, the weirder the shell gets. If I fire it horizontally, it's fine. However, if I fire it at 15 degrees, it looks as if the the shell starts off pointing in the wrong direction. This is, of course, leading to it pointing downwards far sooner than it should.
    Last edited by Skye McCloud; 06-20-2008 at 12:38 PM.

  8. #8
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    A single rectangle shaped object's center of mass is directly in the geometric center. There is no natural torque generated simply by giving it an acceleration. However, if you are able to move that center of gravity towards the front, or compose the projectile of two parts with the heavier in front, it should start acting more like a dart than a simple box.

  9. #9
    Member
    Join Date
    Dec 2007
    Posts
    85
    I'm not sure the engine has that capability. It seems to be a bit lacking. However, I'll check it anyway.

  10. #10
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I've used APE before, though not for this situation. I think you can create a Composite with two RectangleParticles and a SpringConstraint with stiffness = 1 to get the effect I described above.

  11. #11
    Member
    Join Date
    Dec 2007
    Posts
    85
    ... I read your post and immediately went "Oh f*ck."

    I've not quite worked with the Composite or StringConstraint classes, so I honestly have no idea what they do nor how to use them, so what you said has me a tad bit lost.

  12. #12
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    It's been a while since I played with APE. Something like this:

    Code:
    var projectile:Composite = new Composite();
    var frontBit:RectangleParticle = new RectangleParticle(10,0,5, 5);
    frontBit.mass = 2;
    var backBit:RectangleParticle = new RectangleParticle(0,0,5,5);
    //backBit's mass is 1 by default.
    var connector:SpringConstraint = new SpringConstraint(frontBit, backBit, 1);
    projectile.particles.push(frontBit);
    projectile.particles.push(backBit);
    projectile.constraints.push(connector);
    I probably screwed up something in there, but the gist is that you can now use projectile as your bullet (you can assign it its own sprite too, if you don't want the default boxes), which should rotate in a natural looking manner.

  13. #13
    Member
    Join Date
    Dec 2007
    Posts
    85
    Is there a significance to the increased mass on frontBit?

    In addition, since I need the shell to have a specific starting position and angle, how would I see to translating this into what you gave me? Do I apply them to both bits, just one bit, or to the composite itself?

    Trying to make sure I have a full understanding of how it works and how to modify it properly.

  14. #14
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Think of a dart (like with a dartboard), most of the mass is in the front. This causes the center of mass to be shifted forward, and things rotate around a point that's not in the center. If you drop the projectile without any angular momentum, it'll start rotating so that the heavy bit goes down. I think. I don't know if that's necessary for your projectile or not. You can play with the settings once you've got it set up.

    You can rotate the entire composite with rotateByAngle or rotateByRadian.
    http://www.cove.org/ape/docs/api/

    I think you'll have to move one or both of the internal particles in order to place the whole thing where you want it.

  15. #15
    Member
    Join Date
    Dec 2007
    Posts
    85
    Ok, I put that all in and so far it's working ok. I'm still making tweaks to get the positioning right. However, I've hit two things:

    I watch the two particles, and I can see them doing there thing. However, I cannot apply this to my overlaying shell movieclip. I need to find a way to find the difference between the two particles now, such that it allows me to find the angle.

    In other words, it doesn't seem to have solved much of my problem, just recreated it in a new way.

  16. #16
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Do you mean that the composite particle is working as expected (turning and adjusting angles) but you don't know how to apply that to your bullet clip? Or do you mean that it's not adjusting angle? I hope it's the former, because I'd feel terrible to have lead you on this wild goose chase if it doesn't work.

    If the composite particle IS working as expected, you could either get the angle from some trig, or attempt to get it from the Composite's sprite property.

    If the composite is NOT working as expected, could you post or pm me the code? I'll try to take a look at it tonight.

  17. #17
    Member
    Join Date
    Dec 2007
    Posts
    85
    It's a bit of both. It could just be I'm not applying everything correctly, but when I use the composite and watch (I made the back end larger to test this) it looks as though the composite is spinning around rather than the intended action. I applied my velocity to the frontBit to hopefully ensure it got the needed force, but that doesn't seem to work.

    Nonetheless, I'll PM you the code involved in creating the particles.

  18. #18
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Well, I played around a bit with APE again tonight. My idea didn't work. I think it's a limitation of the engine. What you really want to do is create a solid object with a moment of inertia spread out along its entire area. APE doesn't let you do that, and treats all particles as points, pretty much.

    So, instead, I realized that your projectile is always going to be parallel to the line tangent to its trajectory. And the instantaneous tangent at any given time is given by the difference between the projectile's location and it's immediate prior location. So I whipped this up:

    PHP Code:
    package 
    {
        
    import flash.display.Sprite;
        
    import flash.events.Event;
        
    import flash.events.MouseEvent;
        
    import flash.events.TimerEvent;
        
    import flash.text.TextField;
        
    import flash.utils.Timer;
        
    import org.cove.ape.APEngine;
        
    import org.cove.ape.Group;
        
    import org.cove.ape.RectangleParticle;
        
    import org.cove.ape.Vector;
        
        public class 
    Main extends Sprite
        
    {
            private var 
    frontPart:RectangleParticle;
            
            private var 
    btn:TextField;
            private var 
    timer:Timer;
            
            private var 
    lastPos:Vector;
            
            private static var 
    conversion:Number 180 Math.PI//radian to degree conversion
            
            
    public function Main():void
            
    {
                
    lastPos = new Vector(00);
                
    frontPart = new RectangleParticle(5050050100false1);
                
    APEngine.container this;
                
    APEngine.init();
                var 
    g:Group = new Group();
                
    g.addParticle(frontPart);
                
    APEngine.addGroup(g);
                var 
    g2:Group = new Group();
                
    g2.addParticle(new RectangleParticle(3006001000500true));
                
    g2.addCollidable(g);
                
    APEngine.addGroup(g2);
                
    APEngine.addForce(new Vector(01));
                
                
    btn = new TextField();
                
    btn.text "go";
                
    btn.0;
                
    btn.0;
                
    btn.addEventListener(MouseEvent.CLICKgo);
                
    addChild(btn);
                
                
    timer = new Timer(20);
                
    timer.addEventListener(TimerEvent.TIMERstep);
            }
            
            private function 
    go(event:Event):void
            
    {
                
    btn.text "stop";
                
    btn.removeEventListener(MouseEvent.CLICKgo);
                
    frontPart.addForce(new Vector(50, -80)); //change this vector to adjust firing angle/strength
                
    timer.start();
                
    btn.addEventListener(MouseEvent.CLICKstopGoing);
            }
            
            private function 
    step(event:Event):void
            
    {
                
    lastPos.copy(frontPart.center);
                
    APEngine.step();
                var 
    angle:Number Math.atan2((frontPart.center.lastPos.y), (frontPart.center.lastPos.x));
                
    frontPart.angle angle conversion;
                
    APEngine.paint();
            }
            
            private function 
    stopGoing(event:Event):void
            
    {
                
    btn.text "go";
                
    btn.removeEventListener(MouseEvent.CLICKstopGoing);
                
    frontPart.position = new Vector(50500);
                
    timer.reset();
                
    btn.addEventListener(MouseEvent.CLICKgo);
            }
        }

    Just an example to show you how it can be done for an arbitrary angle/strength combo.
    Last edited by 5TonsOfFlax; 06-25-2008 at 02:16 AM.

  19. #19
    Member
    Join Date
    Dec 2007
    Posts
    85
    Awesome, that actually worked!

    Thank you very much for your help, Flax! Now I can get to the fun part and make explosions.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center