Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Nearest Vector in a list

Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
01-06-2009 06:58
so i've decided to work on a path script once again. but one thing i'd like to implement is hpw to determine which position is nearest in a list of positions so that when it first starts cycling it'll move to the nearest one, and then cycle thru the locations from there, rather than moving to the first one first. not in world to try it yet. but my theory is i could have a list of vectors, and make a temporary list of vectors each followed by it's current distance. then another temp list of just the distances, sort that list, check which is the first after sorted, find it in the list of vectors and distances to find out which vector goes with it. that all kinda sounds like an over kill to me. anyone have any other suggestions to figure that out?
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
01-06-2009 07:16
I think llVecDist is probably the quickest way...

CODE

vector pos = llGetPos();
list vector_list = []; // however you populate this
integer index = llGetListLength(vector_list);
float min = 1000.0; // or some value greater than the range
while (--index >= 0) {
float distance = llVecDist(pos, llList2Vector(vector_list, index));
if (distance < min) {
min = distance;
}
}
//...etc
_____________________
http://slurl.com/secondlife/Together
Escort DeFarge
Together
Join date: 18 Nov 2004
Posts: 681
01-06-2009 07:22
you may need to use llFabs() on the distance returned, i can't remember whether the result of llVecDist is always positive (but i think it probably is)
_____________________
http://slurl.com/secondlife/Together
Meade Paravane
Hedgehog
Join date: 21 Nov 2006
Posts: 4,845
01-06-2009 08:41
From: Escort DeFarge
you may need to use llFabs() on the distance returned, i can't remember whether the result of llVecDist is always positive (but i think it probably is)

It definitely always returns >= 0.0.
_____________________
Tired of shouting clubs and lucky chairs? Vote for llParcelSay!!!
- Go here: http://jira.secondlife.com/browse/SVC-1224
- If you see "if you were logged in.." on the left, click it and log in
- Click the "Vote for it" link on the left
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
01-06-2009 17:02
From: Escort DeFarge
I think llVecDist is probably the quickest way...

CODE

vector pos = llGetPos();
list vector_list = []; // however you populate this
integer index = llGetListLength(vector_list);
float min = 1000.0; // or some value greater than the range
while (--index >= 0) {
float distance = llVecDist(pos, llList2Vector(vector_list, index));
if (distance < min) {
min = distance;
}
}
//...etc


not quite what i meant as the list will be populated with alot of vectors, alot of them will probably be in range, i want to figure out which one is closest
_____________________
Dark Heart Emporium

http://www.xstreetsl.com/modules.php?name=Marketplace&MerchantID=133020

want more layers for tattoos, specifically for the head? vote here
http://jira.secondlife.com/browse/VWR-1449?

llDetectedCollision* Functions similar to touch
http://jira.secondlife.com/browse/SVC-3369
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-06-2009 17:44
CODE

// Returns the index into 'points' of the member closest to 'pos'.
// param points - The points to search through. All elements must be vectors.
// param pos - The location to test each point against.
integer indexOfClosestPoint(list points, vector pos)
{
integer nPoints = llGetListLength(points);
integer minDistIndex = 0;
float minDist = llVecDist(pos, llList2Vector(points, 0));

integer i;
for (i = 1; i < nPoints; ++i)
{
float dist = llVecDist(pos, llList2Vector(points, i));

if (dist < minDist)
{
minDistIndex = i;
minDist = dist;
}
}

return minDistIndex;
}
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
01-06-2009 18:23
From: Hewee Zetkin
CODE

// Returns the index into 'points' of the member closest to 'pos'.
// param points - The points to search through. All elements must be vectors.
// param pos - The location to test each point against.
integer indexOfClosestPoint(list points, vector pos)
{
integer nPoints = llGetListLength(points);
integer minDistIndex = 0;
float minDist = llVecDist(pos, llList2Vector(points, 0));

integer i;
for (i = 1; i < nPoints; ++i)
{
float dist = llVecDist(pos, llList2Vector(points, i));

if (dist < minDist)
{
minDistIndex = i;
minDist = dist;
}
}

return minDistIndex;
}


awesome, thanks hewee. if i understand that right it gets the distance from each index, and if it's lower than the previous, it over writes it right?
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-06-2009 22:36
From: Ruthven Willenov
awesome, thanks hewee. if i understand that right it gets the distance from each index, and if it's lower than the previous, it over writes it right?

Right. Keeping track of the index that held the closest (so far) point as well as the distance itself, then just reporting the index. That way you can retrieve the point, re-compute the distance if you need to, or whatever (if you use multiple lists in parallel as a kind of structure type, you could even use the index to reference the other lists in the same location as the closest point that was found).