PathEngine home previous: Translating the agentnext: Tutorial 3
Contents, Programmers Guide, Example Projects, Tutorials, Tutorial 2, SlideAgainst()

SlideAgainst()

SlideAgainst() is defined in 'code/sampleShared/Sliding.cpp' and is just a bit of quick and dirty vector maths.

The function is defined as follows:

void SlideAgainst(const int32_t* collidingLine, int32_t currentx, int32_t currenty, int32_t& dx, int32_t& dy)
{
    float dotproduct = static_cast<float>(dx * (collidingLine[2] - collidingLine[0]) + dy * (collidingLine[3] - collidingLine[1]));
    float ratio = dotproduct;
    int32_t axisX=collidingLine[2]-collidingLine[0];
    int32_t axisY=collidingLine[3]-collidingLine[1];
    float axisLengthSquared = static_cast<float>(axisX * axisX + axisY * axisY);
    ratio/=axisLengthSquared;
    dx = static_cast<int32_t>(static_cast<float>(axisX) * ratio);
    dy = static_cast<int32_t>(static_cast<float>(axisY) * ratio);
    int32_t targetx,targety;
    targetx=currentx+dx;
    targety=currenty+dy;
    if(SideOfLine(collidingLine,targetx,targety)==SIDE_RIGHT)
    {
        PushToLeftOfLine(collidingLine,targetx,targety);
        dx=targetx-currentx;
        dy=targety-currenty;
    }
}

This basically takes the component of the movement vector along the line of the obstruction.
It is slightly complicated by the possibility that approximation may result in a point behind the line we are sliding against.
This is detected by the SideOfLine() test, and fixed by calling PushToLeftOfLine().

PushToLeftOfLine() is defined as follows, and basically just adds or subtracts one to or from one of the coordinates depending on the angle of the line.

inline void PushToLeftOfLine(const int32_t *line, int32_t &x, int32_t &y)
{
    int32_t axisX=line[2]-line[0];
    int32_t axisY=line[3]-line[1];
    int32_t absolute_x,absolute_y;

    absolute_x=axisX;
    if(absolute_x<0)
        absolute_x=-axisX;
    absolute_y=axisY;
    if(absolute_y<0)
        absolute_y=-axisY;
    
    // force rounding in axis with smaller component
    if(absolute_y>absolute_x)
    {
        if(axisY>0)
            x--;
        else
            x++;
    }
    else
    {
        if(axisX<0)
            y--;
        else
            y++;
    }
}

Documentation for PathEngine release 6.04 - Copyright © 2002-2024 PathEnginenext: Tutorial 3