## Recommended Posts

Hi All,

Hope that someone can lend a hand here. I have been going around in circles with this for the past couple of days and at this point feel that my head is going to explode.

What I want to do if determine the distance from the center of a prim to the furthest point of the prim along a particular world axis. With prims that are at zero rotation, or only rotated 90/180/270 on any axis it is simple. If I want the distance along the x-axis, for example, Zero Rotation it would be 1/2 the x size; rotated 90/270 on y it would be1/2 z size, and 90/270 rotation on z would be 1/2 y  size. The problem I am having is when there is a non-right angle rotation on an axis .. or even more, when there is a rotation on more that one axis. The size no longer is all I need as the furthest point becomes an edge/corner not the face.

I have tried multiple ways of figuring this out, but it has been way too many decades since I studied trig. Have some half solutions, but these are based on too many variables and having to check what is rotated where etc that I know there must be a simpler mathematical formula for doing this ... so hoping the math wizards out there could lend a hand.

Wanda

Edited by Wandering Soulstar
spelling

##### Share on other sites

Is a bounding box solution good enough? This will get you the bounding  box of an object in world coordinates.

```float pathMin(float a, float b) { if (a<b) { return(a); } else { return(b); }} // usual min and max, avoiding name clashes
float pathMax(float a, float b) { if (a>b) { return(a); } else { return(b); }}
//
//  pathGetBoundingBoxWorld -- get object bounding box in world coordinates
//
//  LSL gives us the bounding box in object coordinates. We have to rotate it
//  and get the limits.  One vertex at a time.
//
list pathGetBoundingBoxWorld(key id)
{
list info = llGetObjectDetails(id, [OBJECT_POS, OBJECT_ROT]) + llGetBoundingBox(id);
vector pos = llList2Vector(info, 0);            // position in world coords
rotation rot = llList2Rot(info, 1);             // rotation in world coords
integer ix;
integer iy;
integer iz;
//  Convert each corner of the original bounding box to world coordinates.
vector mincorner;                               // bounding box in world coords
vector maxcorner;
integer first = TRUE;                           // first time through
for (ix=0; ix<2; ix++)                          // do all vertices of bounding box
{   vector vx = llList2Vector(info, ix+2);
for (iy=0; iy<2; iy++)
{   vector vy = llList2Vector(info, iy+2);
for (iz=0; iz<2; iz++)
{   vector vz = llList2Vector(info, iz+2);
vector pt = <vx.x, vy.y, vz.z>;     // one corner of the bounding box in obj coords
vector ptworld = pt * rot + pos;    // in world coords
if (first)
{   mincorner = ptworld;
maxcorner = ptworld;
first = FALSE;
}  else {
mincorner = <pathMin(mincorner.x,ptworld.x), pathMin(mincorner.y, ptworld.y), pathMin(mincorner.z, ptworld.z)>;
maxcorner = <pathMax(maxcorner.x,ptworld.x), pathMax(maxcorner.y, ptworld.y), pathMax(maxcorner.z, ptworld.z)>;
}
}
}
}
return([mincorner, maxcorner]);                 // min and max corners, in world coordinates
}```

• 1

##### Share on other sites

Assuming that these "prims" are cubes... (They don't have to be.)

A cube has 8 corners, but let's focus on just one first. The one with relative position <1,1,1> from the center.

```vector corner = <1,1,1>;

corner = <1,1,1> * llEuler2Rot(<0,-45,-45> * DEG_TO_RAD);

// Or more simply
corner *= llGetRot();```

That's how you calculate the new position of the corner in any rotation (<0,-45,-45> in this case). (You'll need a list of corners and do the same for each one.)

Then, when you want to know which corner is the furthest away from the center, you go through the list of corner positions and check the absolute value of the axis you want, and always store the highest value and possibly record which corner it was. Easy peasy.

Edited by Wulfie Reanimator
• 1

##### Share on other sites

Thanks!!!!!

@animats I see yours will give me the max/min position for each xyz, which is very good. For what I need though I only every need to find one and so the base formula as pointed out by  @Wulfie Reanimator.

Following is the sample code off the back of these guides. I knew it had to be simpler than what I was doing 🙂

```list CORNERS = [<1.0, 1.0, 1.0>, <-1.0, 1.0, 1.0>, <-1.0, -1.0, 1.0>, <-1.0, 1.0, -1.0>, <-1.0, -1.0, -1.0>, <1.0, -1.0, -1.0>, <1.0, 1.0, -1.0>, <1.0, -1.0, 1.0>];

float get_mod(string axis, integer min)
{
rotation rot = llGetRot();
list vals = [];
integer x;

for (x = 0; x < 8; x++)
{
vector corner = llList2Vector(CORNERS, x) * rot;
//now grab just the axis we are looking for
if (axis == "x"){vals += [corner.x];}
else if (axis == "y"){vals += [corner.y];}
else if (axis == "z"){vals += [corner.z];}
}

//now sort according to which value we are looking for
vals = llListSort(vals, 1, min);

//and return the first
return llList2Float(vals, 0);
}

default
{
touch_start(integer total_number)
{
float mod = get_mod("x", FALSE);
float dist = ((llGetScale().x)/2) * mod;
float posit = llGetPos().x + dist;
}
}```

Edited by Wandering Soulstar

##### Share on other sites

Since the time has past for me to be able to edit it, please ignore the above post. I had tested this out, but only briefly and must have hit the one scenario/time it was right. I have just these past days been finally in full testing of the system where this code was .. and found out that it did not work at all. After struggling with it for much longer than I should have (being stubborn) .. I went back to @animats code .. and wouldn't you know it .. worked perfectly. For my scenario though there was one problem ... llGetBoundingBox returns for the whole linkset, whilst I need it for the specific prim ... but actually calculating the prim's bounding box is fairly simple .. at least I believe so .. basically it is just the prim scale vector with each xyz divided by 2 (max) and -2 (min) ... if this is not always correct please let me know ...

My final version is as follows .. mainly animat's code .. with formating changes based on how I like it (to each their own style) , the bounding box change, passing in the values as I do need this code to get these values for other prims as well and llGetObjectDetails does not bring back scale, and as well I have scenarios where I need to call this passing a scale that the prim does not have ... and then finally removing the pathMax, pathMin functions (again personal preference).

```vector div_vector_num(vector dividend, float divisor)
{
dividend.x = dividend.x/divisor;
dividend.y = dividend.y/divisor;
dividend.z = dividend.z/divisor;

return dividend;
}

//find the global positions of the max and min corners of a prim
//developed by animats
//minor modifications by Wanda Soulstar
list get_corners(vector pos, rotation rot, vector size)
{
// bounds in local dist from center, min & max
list bound = [div_vector_num(size, -2), div_vector_num(size, 2)];

//resulting corner positions
vector minCorner;
vector maxCorner;
//loop through the x,y,z vertices
//ctrs
integer ix;
integer iy;
integer iz;
//vertices
vector vx;
vector vy;
vector vz;
//calculations
vector pt;
vector ptWorld;

for (ix = 0; ix < 2; ix++)
{
vx = llList2Vector(bound, ix);
for (iy = 0; iy < 2; iy++)
{
vy = llList2Vector(bound, iy);
for (iz = 0; iz < 2; iz++)
{
vz = llList2Vector(bound, iz);
//now get the corner ... in obj coords
pt = <vx.x, vy.y, vz.z>;
//translate to world coords
ptWorld = pt * rot + pos;

//first time through set base
if ((ix + iy + iz) == 0)
{
minCorner = ptWorld;
maxCorner = ptWorld;
}
else
{
//calc min corner
if (ptWorld.x < minCorner.x){minCorner.x = ptWorld.x;}
if (ptWorld.y < minCorner.y){minCorner.y = ptWorld.y;}
if (ptWorld.z < minCorner.z){minCorner.z = ptWorld.z;}
//and then max corner
if (ptWorld.x > maxCorner.x){maxCorner.x = ptWorld.x;}
if (ptWorld.y > maxCorner.y){maxCorner.y = ptWorld.y;}
if (ptWorld.z > maxCorner.z){maxCorner.z = ptWorld.z;}
}
}
}
}
return([minCorner, maxCorner]);
}```

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account. ×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.