سؤال

I have two points, one start position and a goal position(dynamic). I want to spawn players as they would in a formula 1 race. i.e the second a little to the right and back of the first, third left and back of the second and so on. I have already determined the angle so they face to the goal point.

I dont know how to move relative to the line on the axes. I think my distance moves it sideways, but im not a 100% sure.. I also am too stupid to figure out how to go perpendicular of the new points, even though it's probably just adding a minus somewhere.

Well, I hope someone can help me with this, thanks a lot in advance.

Note: The code is in Pawn, a C-like scripting language.

    new x1 = RaceCheckpoints[0][0]//startpoint x
    new y1 = RaceCheckpoints[0][1]//startpoint y
    new x2 = RaceCheckpoints[1][0]//goalpoint x
    new y2 = RaceCheckpoints[1][1]//goalpoint y
    new dist = 2;
    new pos = 0;
    new x3, y3, x4, y4, a, b, norm;
    x3 = (x1 + x2) / 2;
    y3 = (y1 + y2) / 2;
    a = y1 - y2;
    b = x2 - x1;
    norm = sqrt(a*a + b*b);
    a = a / norm;
    b = b / norm;
    x3 = x3 + a * -dist;
    y3 = y3 + b * -dist;
    x4 = x3 + a * 2 * dist;
    y4 = y3 + b * 2 * dist;
    for(new i;i<MAX_PLAYERS;i++)
    {
        if(RaceParticipant[i] != 0)
        {
            if(IsPlayerInAnyVehicle(i)) PlayerVehicles[i]=GetPlayerVehicleID(i);
            else PlayerVehicles[i]=0;
            if (pos = 0)//left lane
            {
            SetPlayerPosFindZ(playerid, x3, y3, RaceCheckpoints[0][2]+10);
            new angle = atan2(y2 - x3, x2 - y3) * 180 / PI;
            SetPlayerFacingAngle(i,angle);
            pos++;
            }

            if (pos = 1)//right lane
            {
            SetPlayerPosFindZ(playerid, x4, y4, RaceCheckpoints[0][2]+10);
            new angle = atan2(y2 - x4, x2 - y4) * 180 / PI;
            SetPlayerFacingAngle(i,angle);
            pos--;
            }

        }
    }
هل كانت مفيدة؟

المحلول

Let's say that your goal lies directly in x direction. Your vector between start and goal is then (0, 1) and the angle between it and the x axis is, of course, zero. Let's also say that each car has a row ix and a columns iy and that the first car has row and column 0.

The distance of any car to the first car is then

xx = - ix * dx - iy * dd;
yy =  - iy * dy;

where dx, dy and dd are the metrics between cars:

    --------000-------------------
     |      000                dd
     |      000        111--------
     dx     000        111
     |      000        111
     |                 111
     |                 111
    --------222
            222
            222        333
            222        333
            222        333
            |          333
            |          333
            |          |
            |--- dy ---|

Now say that your goal lies somewhere else and the the vector between start and goal is (vx, vy). The angle between that vector and the x axis is a. You have to rotate your xx and yy:

xx' = cos(a) * xx - sin(a) * yy
yy' = sin(a) * xx + cos(a) * yy

You could also write this in matrix notation:

{P'} = [C] * {P}

where {P} and {P'} are your unrotated and rotated points and [C] is the rotation matrix:

      |  cos(a)     - sin(a)  |
[C] = |                       |
      |  sin(a)       cos(a)  |

Your angle is

a = atan2(vy, vx)

but you dn't really need the angle here. If you normalise vor vector (vx, vy) so that it is a unit vector, vx and vy are already the cosine and sine of your rotation.

The last step is to add your starting point to the rotated positions. Putting all this together (in C, not Pawn):

double dx = 8.0;        // x distance between 1st and 3rd car
double dy = 5.0;        // y distance between 1st and 2nd car
double dd = 1.5;        // x distance between 1st and 2nd car

double sx = 118.0;      // start point, i.e. position of 1st car
double sy = 6.0;

double gx = 240.0;      // goal point
double gy = 60.0;

int ncar = 8;           // number of cars

double vx = gx - sx;    // vector between start and goal
double vy = gy - sy;
double vv;

double acos;            // sine and cosine of the angle between
double asin;            // (vx, vy) and (1, 0)

double cx[ncar];        // car positions
double cy[ncar];

int i;

vv = sqrt(vx*vx + vy * vy);             // normalise vector
acos = vx / vv;                         // determine rotation cosines
asin = vy / vv; 

for (i = 0; i < ncar; i++) {
    int ix = i / 2;                     // grid index row
    int iy = i % 2;                     // grid index column

    double xx = - ix * dx - iy * dd;    // unrotated car pos,
    double yy =  - iy * dy;             // 1st car a (0, 0)

    cx[i] = sx + acos * xx - asin * yy;
    cy[i] = sy + asin * xx + acos * yy;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top