I've been playing around with the code from the gamasutra article, I made a
geogebra presentation with it to test it out, and there are a few problems
with it. I guess its because of acos and atan which just work in some
quadrants.

http://www.gmodules.com/ig/creator?url=http://hosting.gmodules.com/ig/gadgets/file/111907637128246734259/GeogebraTurningtestRightOnly.xml&synd=open&w=1424&h=832&title=GeoGebra+Gadget&border=%23ffffff%7C3px%2C1px+solid+%23999999

And also I can't seen to find a way to use this properly in 3d space, where
the origin and destinations may be at different heights.
Here's the 2d code I've managed to do, var names are based on the ones from
the article, its pretty simple, and it doesn't do much, but it may have the
same flaws as the geogebra presentation :

*struct CircularPathSegment
> {
>    bool bIsCircleArc;
>    bool bIsRightTurn;
>
>    Vector vArcCenter;
>    float fTotalRadianArcSpan;
>
>    float fAngle; //Starting angle
>    float fSegmentLength; //length of arc or line
>    Vector vStart,
>           vEnd;
> };
>
> //fTurningRadius : the radius the object takes to turn.
> //vOrigin : starting point
> //vDestination : ending point
> //vOrient : Starting orientation of the object. This will help us calculate
> what turn is needed to reach the target facing forward.
> bool CalculateCurvedTurn( float fTurningRadius, Vector vOrigin, Vector
> vDestination, Vector vOrient, CircularPathSegment & pathSegmentCircle,
> CircularPathSegment & pathSegmentStraight)
> {
>    //1. is our target, left or right (only concerned about 2d for now)?
>    Vector vOD = vDestination + vOrigin;
>    const float fAngOrientDestOrigin = ( UTIL_VecToYaw(vOrient) -
> UTIL_VecToYaw(vOD) ); // calc the angle of both in the worldspace, and get
> the difference. This tells us if the turn is right or left.
>    float fAngToP = UTIL_VecToYaw(vOrient); //Angle of point vP and vOrient
> on the origin. This is to determine where is point vP, from the Origin
>
>    if( fAngOrientDestOrigin < 0 ) //Left turn
>    {
>       fAngToP += 90.0f;
>    }
>    else if( fAngOrientDestOrigin > 0 ) //Right turn
>    {
>       fAngToP -= 90.0f;
>    }
>    else
>       return false; //fuck, its straight ahead
>
>
>    //2. Get point P, the turning arc's middle point
>    Vector vP; //Circle arc middle point
>    vP.x = ( vOrigin.x + fTurningRadius ) * cos( fAngToP );
>    vP.y = ( vOrigin.y + fTurningRadius ) * sin( fAngToP );
>    vP.z = vOrigin.z;
>
>    //3. Calculate h (distance from vP to vDestination)
>    Vector vPD( vDestination.x - vP.x, vDestination.y - vP.y, vDestination.z
> - vP.z ); //Vector between point vP and vDestination
>    float h = vPD.Length2D(); //Lenght of vPD
>
>    //4. Check if our turning radius is larger than the  distance to
> Destination.
>    if( h < fTurningRadius )
>       return false;
>
>    //5. Calc lenght of d and the QoD(theta) angle
>    float d = sqrt( (h * h) - (fTurningRadius * fTurningRadius) ); //Legth
> of vQD
>    float fAngQpD = acosf( fTurningRadius / h );
>
>    //6. Calc point Q, and angle OpD(phi)
>    float fAngOpD = atan( vPD.y / vPD.x );
>    Vector vQ; //Vector of the straight line segment after the circle arc
>
>    //Depending if we're going right or left, add or substract our angles
>    float fAngTotal = fAngOrientDestOrigin > 0 ?
>                      fAngOpD + fAngQpD :
>                      fAngOpD - fAngQpD;
>    vQ.x = ( vP.x + fTurningRadius ) * cos( fAngTotal );
>    vQ.y = ( vP.y + fTurningRadius ) * sin( fAngTotal );
>    vQ.z = vP.z;
>
>
>    //7. Setup properly in 3D, and store this into a structure, so we can
> determine our current pos on path without re-calc everything
>
> }
>
> Vector GetCurrentPosOnCircularPath( CircularPathSegment &
> pathSegmentCircle, CircularPathSegment & pathSegmentStraight, float
> fUnitSpeed, float fTurningRadius, float dt )
> {
>    Vector vPos(0);
>    float fDirection=0.0f;
>    float fDistance = fUnitSpeed * dt;
>    CircularPathSegment tabSeg[] = { pathSegmentCircle, pathSegmentStraight
> };
>
>    for( int i = 0; i < 3; ++i ) //Loop through our 2 segment elements
>    {
>       if( fDistance < tabSeg[i].fSegmentLength ) //Unit is somewhere on
> this line segment
>       {
>          if( tabSeg[i].bIsCircleArc ) //Segment is an arc
>          {
>             //Get Position
>             float fCurAngle = tabSeg[i].bIsRightTurn ?
>                               ( fDistance / fTurningRadius ) +
> tabSeg[i].fAngle :
>                               ( fDistance / fTurningRadius ) -
> tabSeg[i].fAngle;
>
>             vPos.x = tabSeg[i].vArcCenter.x + fTurningRadius *
> cos(fCurAngle);
>             vPos.y = tabSeg[i].vArcCenter.y + fTurningRadius *
> sin(fCurAngle);
>
>             //Get orientation
>             fDirection = tabSeg[i].bIsRightTurn ?
>                          tabSeg[i].fAngle + 90.0f :
>                          tabSeg[i].fAngle - 90.0f;
>          }
>          else //Segment is a line
>          {
>             vPos.x = tabSeg[i].vStart.x + fDistance *
> cos(tabSeg[i].fAngle);
>             vPos.y = tabSeg[i].vStart.y + fDistance *
> sin(tabSeg[i].fAngle);
>             fDirection = tabSeg[i].fAngle;
>             break;
>          }
>       }
>       else
>       {
>          Vector v( tabSeg[i].vEnd.x - tabSeg[i].vStart.x , tabSeg[i].vEnd.y
> - tabSeg[i].vStart.y , 0 );
>          fDistance = fDistance - v.Length2D();
>       }
>    }
>
>    return vPos;
> }
> *
>

Can someone give me some pointers where to go from there to use this in 3d,
and to handle the quadrants problems ? I'm not sure what to do.

On Mon, Jul 25, 2011 at 2:36 PM, Psy_Commando <psycomma...@gmail.com> wrote:

> Thanks, I'll give this a try. Its seems pretty straight forward.
>
> On Mon, Jul 25, 2011 at 11:10 AM, Colm Sloan <colmsl...@gmail.com> wrote:
>
>> Here's an article I've used before that you might find useful:
>>
>> http://www.gamasutra.com/view/feature/3096/toward_more_realistic_pathfinding.php
>>
>> _______________________________________________
>> To unsubscribe, edit your list preferences, or view the list archives,
>> please visit:
>> http://list.valvesoftware.com/mailman/listinfo/hlcoders
>>
>>
>>
>
_______________________________________________
To unsubscribe, edit your list preferences, or view the list archives, please 
visit:
http://list.valvesoftware.com/mailman/listinfo/hlcoders

Reply via email to