GetNearestDynObject - doing the opposite
#1

I found this function on the forums, but it doesn't seem to work for me. I couldn't figure out what the problem was in the code. However, instead of the function returning the NEAREST object, it returns the FARTHEST object.

pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float: px, Float: py, Float: pz,
        currentobject = -1,
        Float:distance = -1
    ;
    GetPlayerPos( playerid, px, py, pz );

    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        if ( !IsValidDynamicObject( index ) ) continue;

        new
            Float:ox,
            Float:oy,
            Float:oz
        ;
        GetDynamicObjectPos( index, ox, oy, oz );

        new Float:odist = floatsqroot(
            floatpower( floatabs( floatsub( ox, px ) ), 2.0 ) +
            floatpower( floatabs( floatsub( oy, py ) ), 2.0 ) +
            floatpower( floatabs( floatsub( oz, pz ) ), 2.0 )
        );

        if ( currentobject == -1 )
        {
            currentobject = index;
            distance = odist;
        }
        else if ( odist < distance )
        {
            currentobject = index;
            distance = odist;
        }
    }

    return currentobject;
}
Ideas...?
Reply
#2

hm.. despite 3 or 4 optimisations, i cannot see why this algorithm should fail.. are you sure the surrounding code is ok? ^^
brb, onto editing later, expect some faster script, which will not change behavior i guess...
edit:done:
pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float:px,
        Float:py,
        Float:pz,
        currentobject = -1,
        Float:distance = 10000.0,
        Float:ox,
        Float:oy,
        Float:oz,
        Float:odist;
    GetPlayerPos( playerid, px, py, pz );
    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        if ( !IsValidDynamicObject( index ) ) continue;
        GetDynamicObjectPos( index, ox, oy, oz );
        odist = floatsqroot(
        floatpower( floatsub( ox, px ), 2.0 ) +
        floatpower( floatsub( oy, py ), 2.0 ) +
        floatpower( floatsub( oz, pz ), 2.0 )
        );
        if ( odist < distance )
        {
            currentobject = index;
            distance = odist;
        }
    }
    return currentobject;
}
...this wont fix the bug, but its a little faster - the reasons are obvious. hm... despits that, i cant help without seeing: more coooode :P

edit2: ok, i will inlcude that snippet into my actual project FS, lets see what happens. iam on it, hope youre online in .. 1 hour brb
Reply
#3

I don't see any problem. You should try debugging it and see what it prints out.
Reply
#4

You are probably not counting it correctly.

pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float: px, Float: py, Float: pz,
        currentobject = -1,
        Float:distance = -1
    ;
    GetPlayerPos( playerid, px, py, pz );

    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        if ( !IsValidDynamicObject( index ) ) continue;

        new
            Float:ox,
            Float:oy,
            Float:oz
        ;
        GetDynamicObjectPos( index, ox, oy, oz );
       
        new Float:odist = GetPlayerDistanceFromPoint(playerid, ox, oy, oz)

        if ( currentobject == -1 )
        {
            currentobject = index;
            distance = odist;
        }
        else if ( odist < distance )
        {
            currentobject = index;
            distance = odist;
        }
    }

    return currentobject;
}
Try with GetPlayerDistanceFromPoint();
Reply
#5

Quote:
Originally Posted by Babul
Посмотреть сообщение
are you sure the surrounding code is ok? ^^
It should be, yes.

Quote:
Originally Posted by YJIET
Посмотреть сообщение
I don't see any problem. You should try debugging it and see what it prints out.
Already trying that, not seeing anything wrong here.

Quote:
Originally Posted by [MG]Dimi
Посмотреть сообщение
You are probably not counting it correctly.

pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float: px, Float: py, Float: pz,
        currentobject = -1,
        Float:distance = -1
    ;
    GetPlayerPos( playerid, px, py, pz );

    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        if ( !IsValidDynamicObject( index ) ) continue;

        new
            Float:ox,
            Float:oy,
            Float:oz
        ;
        GetDynamicObjectPos( index, ox, oy, oz );
       
        new Float:odist = GetPlayerDistanceFromPoint(playerid, ox, oy, oz)

        if ( currentobject == -1 )
        {
            currentobject = index;
            distance = odist;
        }
        else if ( odist < distance )
        {
            currentobject = index;
            distance = odist;
        }
    }

    return currentobject;
}
Try with GetPlayerDistanceFromPoint();
Already tried doing it that way. Instead of it returning the farthest or the nearest object, it returns the one in the center.
Reply
#6

Quote:
Originally Posted by Babul
Посмотреть сообщение
despits that, i cant help without seeing: more coooode :P
I'll update to that function- thank you.

This is the code surrounding the function. It's basically a command to remove the nearest "road block." I don't see any issues with it, though!

http://pastebin.com/WBmiEJFR
Reply
#7

Hm try your original code but change it get you the furthest object, it might return you correct one
Reply
#8

Quote:
Originally Posted by [MG]Dimi
Посмотреть сообщение
Hm try your original code but change it get you the furthest object, it might return you correct one
I need the nearest object, so doing that would be a waste of time, don't you think?

EDIT: I tried doing it anyways, since there's nothing I can do until this is resolved. It DOES return the FARTHEST object with the function below:

pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float: px, Float: py, Float: pz,
        currentobject = -1,
        Float:distance = -1
    ;
    GetPlayerPos( playerid, px, py, pz );

    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        if ( !IsValidDynamicObject( index ) ) continue;

        new
            Float:ox,
            Float:oy,
            Float:oz
        ;
        GetDynamicObjectPos( index, ox, oy, oz );

        new Float:odist = floatsqroot(
            floatpower( floatabs( floatsub( ox, px ) ), 2.0 ) -
            floatpower( floatabs( floatsub( oy, py ) ), 2.0 ) -
            floatpower( floatabs( floatsub( oz, pz ) ), 2.0 )
        );

        if ( currentobject == -1 )
        {
            currentobject = index;
            distance = odist;
        }
        else if ( odist > distance )
        {
            currentobject = index;
            distance = odist;
        }
    }
    return currentobject;
}
Reply
#9

Quote:
Originally Posted by ******
Посмотреть сообщение
How can odist EVER be smaller than your inital value for distance?
Good point, but I'm not seeing how that helps but to remove an if statement.
Reply
#10

the initial currentobject=-1, then the distance to the first encountered object gets estimated. this triggers the first if-statement, and assigns the first distance. clever, if you ask me, but i prefer my solution, which assumes that all "close" objects should start at like 6000.0 units
ok, heres the real deal: i played around with mapicons, and created some 1337 objects (only 4 to 7), due to the mapicon limit. dont use it on more than 30 objects..
for me, walking around some trashcans, the checkpoints showed up like a snake on those, and the gametext told me the object id. since i started with 0 objects loaded, it was easy to check if the ids matched. they did.
oh, heres some additional code. i was too lazy to write a timer, and included your snippet into my object editor:
pawn Код:
forward OnPlayerUpdate(playerid);public OnPlayerUpdate(playerid){
    new no=GetNearestDynObject(playerid);
    new string1[64];
    format(string1,sizeof(string1),"no:%d",no);
    GameTextForPlayer(playerid,string1,100,5);
and heres your snippet, slightly modified again:
pawn Код:
stock GetNearestDynObject(playerid)
{
    new
        Float:px,
        Float:py,
        Float:pz,
        currentobject = -1,
        Float:distance = 10.0,
        Float:ox,
        Float:oy,
        Float:oz,
        Float:odist;
    GetPlayerPos( playerid, px, py, pz );
    for( new index = 0; index < CountDynamicObjects(); index++ )
    {
        //if ( !IsValidDynamicObject( index ) ) continue;
        GetDynamicObjectPos( index, ox, oy, oz );
        odist = floatsqroot(
        floatpower( floatsub( ox, px ), 2.0 ) +
        floatpower( floatsub( oy, py ), 2.0 ) +
        floatpower( floatsub( oz, pz ), 2.0 )
        );
        if ( odist < distance )
        {
            currentobject = index;
            distance = odist;
            SetPlayerMapIcon(playerid,index,ox,oy,oz,00,0xaa55ff55,3);
        }
    }
    return currentobject;
}
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)