Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: Physics of 2d Space

  1. #11

    Physics of 2d Space

    Quote Originally Posted by joyrider
    Quote Originally Posted by splattergnome
    Thanks for the ]Player.x := Player.x + (cos(angle) * speed/5);
    Player.y := Player.y + -(sin(angle) * speed/5);[/code]
    can somone please post some example code which uses this ? for example just plot a pixel so that when u turn left it turn 1 degree . I've been trying it for so long but i just suck at maths and never managed to get it working right.

    thanks
    Check out the source code for my rotation tutorial. One of the examples has a moveable tank -- that probably does what you need here. Note that you have to install the CDNDXTimer.pas component first (it's just a timer component) before opening the project.

    If you want a more specific example then let me know and I'll whip one up later tonight.
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  2. #12

    Physics of 2d Space

    thanks nice info there.

    but i still got troubles, i'm using one single pixel, so i got no center to calculate it's the pixels possition itself

    thing is i'm trying to get something like a turtle graphic system similar to ure vector tank example but then for just one pixel

  3. #13

    Physics of 2d Space

    :scratch: If you want to rotate anything you have to rotate it around something. Maybe you could explain how exactly you want it to look.

  4. #14

    Physics of 2d Space

    exactly the same like the tank example mentioned above but just for one pixel not vector graphics. so that he pixel moves around and i can turn it smooth. with the tank example u need to calculate the center and rotate it against that, but for just one pixel i have no clue what to do.

    it's similar to a turtle graphics system. I thought that if i could create that, it wouldn't be hard to create a small top view race game without any scrolling

  5. #15

    Physics of 2d Space

    Just yse the pixel's position as the center, i minimized Alimonster's example to only use one pixel.[pascal]
    unit tank_class;

    interface

    uses
    Graphics;

    type
    // The following represents a point of the tank. It would have x,y and z in
    // the case of a 3D vector, but we don't need that for this example program
    TVector2D = record
    case Boolean of
    False: (pts: array[0..1] of Real);
    True : (x,y: Real);
    end;


    TTank = class
    private
    FDirection: TVector2D;
    FShowDirection: Boolean;
    protected
    FPosition: TVector2D;
    property Direction: TVector2D read FDirection write FDirection;
    public
    constructor Create;
    destructor Destroy; override;
    procedure Draw(Where: TCanvas);
    procedure Move(const Speed: Real);
    procedure Rotate(const rotation: Real);

    property ShowDirection: Boolean read FShowDirection write FShowDirection default True;
    end;

    implementation

    ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

    //
    // MakeVector
    //
    // A little helper function to set a vector to the wanted values
    //
    procedure MakeVector(var Vec: TVector2D; _x,_y: Real);
    begin
    with Vec do
    begin
    x := _x;
    y := _y;
    end;
    end;

    //
    // VectorLength
    //
    // Calculates the length of a 2D vector (for 3D, adjust to include the z value)
    //
    function VectorLength(var Vec: TVector2D): Real;
    begin
    with Vec do
    Result := Sqrt(x*x + y*y);
    end;

    //
    // Normalize
    //
    // Normalises the vector so that it's of unit length
    //
    procedure Normalize(var Vec: TVector2D);
    var
    RecipLength: Real;
    begin
    RecipLength := 1 / VectorLength(Vec);
    with Vec do
    begin
    x := x * RecipLength;
    y := y * RecipLength;
    end;
    end;


    //
    // Create
    //
    // The constructor for the class. Does constructor-y things
    //
    constructor TTank.Create;
    var
    i: Cardinal;
    begin
    inherited;
    FPosition.x:=160;
    FPosition.y:=120;

    MakeVector(FDirection, 0, -1); // facing up -- y is positive down the screen
    end;

    //
    // Destroy
    //
    // A destructor. No cleaning up to do yet
    //
    destructor TTank.Destroy;
    begin
    inherited;
    end;

    //
    // Draw
    //
    // Displays the tank to a given canvas using LineTo
    //
    procedure TTank.Draw(Where: TCanvas);
    var
    i: Cardinal;
    begin
    with Where do
    begin
    // Move to the first point
    Where.Pixels[Round(FPosition.x),
    Round(FPosition.y)] := ClBlack;

    // draw the direction too
    if FShowDirection then
    begin
    Pen.Color := clRed;
    MoveTo(Round(FPosition.X), Round(FPosition.Y));
    LineTo(Round((FDirection.x * 140) + FPosition.X),
    Round((FDirection.y * 140) + FPosition.Y));

    Pen.Color := clBlack;
    end;
    end;
    end;


    //
    // Move
    //
    // Moves the tank forward at a given speed in the direction it's facing
    //
    procedure TTank.Move(const Speed: Real);
    var
    i: Cardinal;
    begin
    FPosition.x := FPosition.x + (FDirection.x * Speed);
    FPosition.y := FPosition.y + (FDirection.y * Speed);
    end;

    //
    // Rotate
    //
    // Rotates the tank and its direction vector by the given angle (in degrees).
    // This is the interesting part in terms of the tutorial .
    //
    procedure TTank.Rotate(const rotation: Real);
    const
    DEG_TO_RAD: Real = PI/180;
    var
    i: Cardinal;
    Angle: Real;
    OldX, OldY: Real;
    begin
    Angle := Rotation * DEG_TO_RAD; // convert from degrees to radians

    // Update the direction too. This doesn't need to be translated as we're only
    // interested in which way it's pointing, not where it is
    OldX := FDirection.x;
    OldY := FDirection.y;
    FDirection.x := OldX * cos(Angle) - OldY * sin(Angle);
    FDirection.y := OldX * sin(Angle) + OldY * cos(Angle);
    Normalize(FDirection);
    end;

    end.[/pascal]

  6. #16

    Physics of 2d Space

    ah tnx man,
    i finally get the code & a bit of the maths but i do have one more question. I don't really get what the normalize procedure does or why it's need, (don't even know the meaning of normalize), i didn't use it with my test code but it still works.

  7. #17

    Physics of 2d Space

    Normalization means changing a vector so its direction stays the same, but its length becomes equal to 1, witch makes a lot of vector math functions simpler. In this case it?¢_Ts not really needed.

  8. #18

    Physics of 2d Space

    I'll expand on what Paulius said...

    Consider the basic premise of a vector: it's a bunch of numbers (one value per dimension, so x and y for R2 or x, y and z for R3) that should represents a direction. So, for example, the vector (x: 2, y: 3) represents "2 units to the right and 3 units up/down (depending on coordinate system)". Of course, such instructions have to be followed by a "start from here" point, which may well be the origin (x:0;y:0), although it doesn't have to be. It's all right saying "move 2 units to the right", but it has to be 2 units to the right of something!

    So, you can keep a vector handy for a direction -- in the case here, which way the tank or your pixel is heading. Say we had the vector (x: 1; y: 0), which would be "move to the right". If you take any 2d point and add this vector onto it (point.x := point.x + vector.x; same for y) then you'd be moving along in this direction (since that's what the vector represents, a direction).

    However, suppose we want to move along a bit further -- say, 5 times the usual amount in the direction. No problem, we'd code something like "point.x := point.x + (5 * vector.x); same for y". Everything is fine and dandy here -- we've moved 5 times further in the direction.

    But...

    (x: 1; y: 0) represents "move directly to the right"
    (x: 2; y: 0) represents "move directly to the right"
    (x: (n>0); y: 0) represents "move directly to the right"

    So you see, you have have any number of vectors pointing in the same direction. The difference between each is that they're multiples of a common base vector of unit length (e.g. (x:2; y:0) can be expressed as 2 * (x:1; y:0), with the difference in meaning being "move 2 times as far in whatever direction as the standard one does".

    If we took the vector (x: 2; y: 0) and applied it with the "point.x := point.x + (5 * vector.x); same for y" as before, we'd go in the right direction, but too far (twice as far, to be exact)!

    Normalisation is a process to ensure the vector is of unit length. Unit vectors are handy because they only give a direction, which can then be multiplied by any value to move that far. With other vectors, you usually can't express multiples of them correctly unless they are normalised. Think about this in our example again: we keep a track of where we're heading, and we say "move in this direction for {current speed} units". Hence, it's gotta be normalised.

    Hopefully this has made it clear why you sometimes need normalised vectors. If not, let me know!
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

Page 2 of 2 FirstFirst 12

Bookmarks

Posting Permissions

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