POV-Ray : Newsgroups : povray.off-topic : Math question (inside box) Server Time
31 Oct 2024 14:12:12 EDT (-0400)
  Math question (inside box) (Message 1 to 10 of 19)  
Goto Latest 10 Messages Next 9 Messages >>>
From: Patrick Elliott
Subject: Math question (inside box)
Date: 4 Aug 2013 17:50:17
Message: <51fecc99$1@news.povray.org>
Hunted around on the net and found something for 2D, but I think I got 
something wrong trying to do the 3D. Actually, I am semi-sure I know 
what I screwed up, but not how to fix it. lol But, I figured I would 
maybe, instead, ask here instead, on the chance there is a better solution.

Basically though, I have an object, its position, and its rotation, and 
I want to create a "test box" in which to work out where someone is, 
but I want it to still work, regardless of whether or not the object is 
say, rotated 35 degrees in all directions, placing my "test box" some 
place other than at nice 90 angles from the normal axis.

Now the method I had tried was:

main(){
integer left = 0;
integer right = 2;
integer length = 5;
integer top = 1.5;
integer bottom = 1.5;

//Assuming that the "front" is in the Y direction.
  integer boxlen = llGetScale().y / 2;
  vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
  vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
  vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z - bottom>;
  vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
  if (isInsideBox(bbox1, bbox2, bbox3, bbox4))
    //do other stuff, or, else, the stuff you do if they are "not" in 
the box.
}

integer triangleArea(vector A, vector B, vector C)
{
   //This is where I am screwing up.. I need to test A.z, B.z and C.z,
   //for one of the planes, but I am testing x and y in both cases, which
   //won't work.
   return(C.x*B.y-B.x*C.y)-(C.x*A.y-A.x*C.y)+(B.x*A.y-A.x*B.y);
}

integer isInsideSquare(vector A, vector B, vector C, vector D, vector P)
{
   if(triangleArea(A,B,P)>0 || triangleArea(B,C,P)>0 || 
triangleArea(C,D,P)>0 || triangleArea(D,A,P)>0)
       return FALSE;
     else
       return TRUE;
}

integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector bbox4)
{
   vector P = llDectectedPos(0);
   vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
   vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
   vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
   vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
   vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
   vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
   vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
   vector D2 = <bbox3.x,bbox3.y,bbox3.z>;
   return (isIntegerSquare(A1, B1, C1, D1, P) & isIntegerSquare(A2, B2, 
C2, D2));
}


I am 99% sure that what I failed to think about is that since one of the 
"sides" is vertical, I am testing its x and y in both cases, and thus, 
stupidly, not testing the z. Otherwise, the code works, supposedly, 
because, if your test point isn't "inside the box", one or more of the 
area calculations will end up with a negative sign.

In any case, I need to redo the code, if I want to do this, and simplify 
things a lot at well.

But, what I was wondering is.. is there some other way to do this? Some 
way that takes into account the rotation, and what amounts to a sort of 
"is this inside of the bounding box" calculation, without having to 
rotation/unrotate various things, to get the same result? Because, as 
things stand, either I need to reposition the object I am testing, or I 
need to reposition the corner of my invisible box, which I am testing 
for them to be in. And, while one is less annoying than the other.. they 
are still both annoying. lol


Post a reply to this message

From: Le Forgeron
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 03:52:55
Message: <51ff59d7$1@news.povray.org>
Le 04/08/2013 23:50, Patrick Elliott a écrit :
> Hunted around on the net and found something for 2D, but I think I got
> something wrong trying to do the 3D. Actually, I am semi-sure I know
> what I screwed up, but not how to fix it. lol But, I figured I would
> maybe, instead, ask here instead, on the chance there is a better solution.
> 
> Basically though, I have an object, its position, and its rotation, and
> I want to create a "test box" in which to work out where someone is, but
> I want it to still work, regardless of whether or not the object is say,
> rotated 35 degrees in all directions, placing my "test box" some place
> other than at nice 90 angles from the normal axis.

Why would you want to handle such box, when the interest of such code is
precisely to reduce the workload by looking only at the axes.


> 
> Now the method I had tried was:
> 
> main(){
> integer left = 0;
> integer right = 2;
> integer length = 5;
> integer top = 1.5;
> integer bottom = 1.5;
> 
> //Assuming that the "front" is in the Y direction.
>  integer boxlen = llGetScale().y / 2;
>  vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>  vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>  vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z - bottom>;
>  vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
>  if (isInsideBox(bbox1, bbox2, bbox3, bbox4))
>    //do other stuff, or, else, the stuff you do if they are "not" in the
> box.
> }
> 
> integer triangleArea(vector A, vector B, vector C)
> {
>   //This is where I am screwing up.. I need to test A.z, B.z and C.z,
>   //for one of the planes, but I am testing x and y in both cases, which
>   //won't work.
>   return(C.x*B.y-B.x*C.y)-(C.x*A.y-A.x*C.y)+(B.x*A.y-A.x*B.y);
> }
> 
> integer isInsideSquare(vector A, vector B, vector C, vector D, vector P)
> {
>   if(triangleArea(A,B,P)>0 || triangleArea(B,C,P)>0 ||
> triangleArea(C,D,P)>0 || triangleArea(D,A,P)>0)
>       return FALSE;
>     else
>       return TRUE;
> }
> 

Did you understand how it is supposed to work in 2D ? I mean the
previous two functions are using oriented triangles and area computation
(signed result) to know if P is inside ABCD.

When P is inside ABCD, ABP, BCP, CDP, DAP all have the same sign for
their area. As soon as P is outside the square, one area at least has a
negative result.

The nice thing about it is that the four points A,B,C & D only need to
be ordered in the rotating order and can be anywhere in the plane (it
does not have to be an axis-aligned square).

But it only works in 2D.


> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector bbox4)
> {
>   vector P = llDectectedPos(0);
>   vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>   vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>   vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>   vector D1 = <bbox1.x,bbox1.y,bbox1.z>;

>   vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
>   vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
>   vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
>   vector D2 = <bbox3.x,bbox3.y,bbox3.z>;

>   return (isIntegerSquare(A1, B1, C1, D1, P) & isIntegerSquare(A2, B2,
> C2, D2));
> }
> 

I do not understand the expectation here. You seems to transform the box
as two parallel to Z plane squares (axis-aligned), and then check if the
projection of P is inside the projections of both these squares.

There is plenty of situations where it will provide false positives, as
well as false negatives.

> 
> I am 99% sure that what I failed to think about is that since one of the
> "sides" is vertical, I am testing its x and y in both cases, and thus,
> stupidly, not testing the z. Otherwise, the code works, supposedly,
> because, if your test point isn't "inside the box", one or more of the
> area calculations will end up with a negative sign.

signed area calculation is only good for 2D. The extension in 3D would
need to compute the volume of a pyramid (with a triangle base) and the
maths are not to be friendly

> 
> In any case, I need to redo the code, if I want to do this, and simplify
> things a lot at well.
> 
> But, what I was wondering is.. is there some other way to do this? Some
> way that takes into account the rotation, and what amounts to a sort of
> "is this inside of the bounding box" calculation, without having to
> rotation/unrotate various things, to get the same result? Because, as
> things stand, either I need to reposition the object I am testing, or I
> need to reposition the corner of my invisible box, which I am testing
> for them to be in. And, while one is less annoying than the other.. they
> are still both annoying. lol

If you do not intend to limit yourself to a axis-aligned box, why not
instead use a sphere ?

you transform only 1 point (the center)(if you only have rotation and
translation), and then just compute the distance of the center to P (to
compare against the radius). And to avoid slow squared root, compare the
squared distance (euclidian) to the squared radius.

If you have more than rotation & translation (such as scaling and
shearing), you might need to transform the radius too (at which point,
it's better to consider 1 center and the 8 corners of the box, to
finally only kept as radius the distance from the center to the most
faraway corner)
(the box is originally the box that encloses the minimal sphere. at the
end, the radius is the radius of the sphere that encloses the
transformed box. Thus, it is bigger than the strict covering sphere, but
it is safe)

-- 
Just because nobody complains does not mean all parachutes are perfect.


Post a reply to this message

From: scott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 04:44:33
Message: <51ff65f1$1@news.povray.org>
>   vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>   vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>   vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z - bottom>;
>   vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;

Do you mean "pos.x + right" in that last line?

> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector bbox4)
> {
>    vector P = llDectectedPos(0);
>    vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>    vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>    vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>    vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
 >    vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
 >    vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
 >    vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
 >    vector D2 = <bbox3.x,bbox3.y,bbox3.z>;

If you substitute in your values for bbox1-4 from above you get the 
following (I left out the pos.x,pos.y,pos.z):

A1 = <-left  , boxlen , -bottom>
B1 = < right , boxlen , -bottom>
C1 = < right , boxlen , -bottom>
D1 = <-left  , boxlen , -bottom>

A2 = <-left  , boxlen+length , -bottom>
B2 = < right , boxlen+length , -bottom>
C2 = < right , boxlen+length , -bottom>
D2 = <-left  , boxlen+length , -bottom>

Is this really what you are expecting?

If you are trying to see if a point is inside a box, then it might be 
simpler to think of the box as being bounded by 6 infinite planes (one 
for each face), then testing which side of each plane the point is on. 
If it's on the "inside" of all 6 planes then it's inside the box.


Post a reply to this message

From: Patrick Elliott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 05:15:48
Message: <51ff6d44$1@news.povray.org>
On 8/5/2013 12:52 AM, Le_Forgeron wrote:
> Le 04/08/2013 23:50, Patrick Elliott a écrit :
>> Hunted around on the net and found something for 2D, but I think I got
>> something wrong trying to do the 3D. Actually, I am semi-sure I know
>> what I screwed up, but not how to fix it. lol But, I figured I would
>> maybe, instead, ask here instead, on the chance there is a better solution.
>>
>> Basically though, I have an object, its position, and its rotation, and
>> I want to create a "test box" in which to work out where someone is, but
>> I want it to still work, regardless of whether or not the object is say,
>> rotated 35 degrees in all directions, placing my "test box" some place
>> other than at nice 90 angles from the normal axis.
>
> Why would you want to handle such box, when the interest of such code is
> precisely to reduce the workload by looking only at the axes.
>
>
Yeah, well. I kind of thought maybe there was some way that I just 
wasn't seeing.

>>
>> Now the method I had tried was:
>>
>> main(){
>> integer left = 0;
>> integer right = 2;
>> integer length = 5;
>> integer top = 1.5;
>> integer bottom = 1.5;
>>
>> //Assuming that the "front" is in the Y direction.
>>   integer boxlen = llGetScale().y / 2;
>>   vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>>   vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>>   vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z - bottom>;
>>   vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
>>   if (isInsideBox(bbox1, bbox2, bbox3, bbox4))
>>     //do other stuff, or, else, the stuff you do if they are "not" in the
>> box.
>> }
>>
>> integer triangleArea(vector A, vector B, vector C)
>> {
>>    //This is where I am screwing up.. I need to test A.z, B.z and C.z,
>>    //for one of the planes, but I am testing x and y in both cases, which
>>    //won't work.
>>    return(C.x*B.y-B.x*C.y)-(C.x*A.y-A.x*C.y)+(B.x*A.y-A.x*B.y);
>> }
>>
>> integer isInsideSquare(vector A, vector B, vector C, vector D, vector P)
>> {
>>    if(triangleArea(A,B,P)>0 || triangleArea(B,C,P)>0 ||
>> triangleArea(C,D,P)>0 || triangleArea(D,A,P)>0)
>>        return FALSE;
>>      else
>>        return TRUE;
>> }
>>
>
> Did you understand how it is supposed to work in 2D ? I mean the
> previous two functions are using oriented triangles and area computation
> (signed result) to know if P is inside ABCD.
>
> When P is inside ABCD, ABP, BCP, CDP, DAP all have the same sign for
> their area. As soon as P is outside the square, one area at least has a
> negative result.
>
> The nice thing about it is that the four points A,B,C & D only need to
> be ordered in the rotating order and can be anywhere in the plane (it
> does not have to be an axis-aligned square).
>
> But it only works in 2D.
>
Umm. Not sure how to explain this, but, yeah, I did. I just.. screwed up 
on the coordinates. lol Umm. Let me put it this way. You are looking at 
two boxes one is laying flat, along the XY, the other is lying flat on 
the XZ (or the YZ, which I don't think necessarily matters). So.. in one 
case if the location of the thing being tested was <1,2,3>, then P 
"should be" <1,2>, and for the other plane, it should be <1,3>, with the 
corners of the two boxes, on those planes, taken from the XY, or the XZ, 
as needed.

Or, that was what I envisioned in my own head. lol Obviously, I screwed 
up from the very start.

>
>> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector bbox4)
>> {
>>    vector P = llDectectedPos(0);
>>    vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>>    vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>>    vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>>    vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
>
>>    vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
>>    vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
>>    vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
>>    vector D2 = <bbox3.x,bbox3.y,bbox3.z>;
>
>>    return (isIntegerSquare(A1, B1, C1, D1, P) & isIntegerSquare(A2, B2,
>> C2, D2));
>> }
>>
>
> I do not understand the expectation here. You seems to transform the box
> as two parallel to Z plane squares (axis-aligned), and then check if the
> projection of P is inside the projections of both these squares.
>
> There is plenty of situations where it will provide false positives, as
> well as false negatives.
>
Yeah, as I said, I fowled up. In actuality, what happens, due to the 
code being wrong, is that P is *never* inside the box.

>>
>> I am 99% sure that what I failed to think about is that since one of the
>> "sides" is vertical, I am testing its x and y in both cases, and thus,
>> stupidly, not testing the z. Otherwise, the code works, supposedly,
>> because, if your test point isn't "inside the box", one or more of the
>> area calculations will end up with a negative sign.
>
> signed area calculation is only good for 2D. The extension in 3D would
> need to compute the volume of a pyramid (with a triangle base) and the
> maths are not to be friendly
>
No doubt.

>>
>> In any case, I need to redo the code, if I want to do this, and simplify
>> things a lot at well.
>>
>> But, what I was wondering is.. is there some other way to do this? Some
>> way that takes into account the rotation, and what amounts to a sort of
>> "is this inside of the bounding box" calculation, without having to
>> rotation/unrotate various things, to get the same result? Because, as
>> things stand, either I need to reposition the object I am testing, or I
>> need to reposition the corner of my invisible box, which I am testing
>> for them to be in. And, while one is less annoying than the other.. they
>> are still both annoying. lol
>
> If you do not intend to limit yourself to a axis-aligned box, why not
> instead use a sphere ?
>
The reason is that I need the specific shape. Ok, I will attach an 
example. There is a safe, against a wall, and a counter, which is green, 
the transparent box is the "valid" area for someone to be able to access 
the safe, with the guy inside it being "allowed", and the two "red" 
figures not. There is no way to use a sphere, without detecting as 
"valid" people standing in the wrong places. Its the precise reason why 
I didn't just use the simpler method of figuring out, "Is this person 
standing in the +X direction, and within N meters of the object. That 
method would have failed to detect people, in the safe where, instead, a 
garage door, for example, if they stood at the "edge" of the door, since 
they might not be "close enough", without making the detection range 
much larger than I wanted (i.e., a 15 meter door, should detect 5 meters 
"in front of" the door, no matter where on the door, but since is using 
"center of the door", it would fail to detect someone standing against 
it, but 7 meters from the center).

However... I occurs to me that I might be able to use one plane, and a 
distance.. So, as long as the position was rotated, to match a plane 
that is align to XY (or, actually, due to how the world works, XZ), then 
I can test if its in "that" box, and then merely do:

float dist = llVecDist(llGetPos(), P);
if (dist < maxdist & dist > mindist)
{
   //Rest of the code.
}

Thus, only testing "one" box, and only on that single plane.

Then again, I screwed up the last idea so badly... lol


Post a reply to this message


Attachments:
Download 'example.png' (22 KB)

Preview of image 'example.png'
example.png


 

From: Patrick Elliott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 05:17:19
Message: <51ff6d9f$1@news.povray.org>
On 8/5/2013 1:44 AM, scott wrote:
>>   vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>>   vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>>   vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z - bottom>;
>>   vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
>
> Do you mean "pos.x + right" in that last line?
>
>> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector
>> bbox4)
>> {
>>    vector P = llDectectedPos(0);
>>    vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>>    vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>>    vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>>    vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
>  >    vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
>  >    vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
>  >    vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
>  >    vector D2 = <bbox3.x,bbox3.y,bbox3.z>;
>
> If you substitute in your values for bbox1-4 from above you get the
> following (I left out the pos.x,pos.y,pos.z):
>
> A1 = <-left  , boxlen , -bottom>
> B1 = < right , boxlen , -bottom>
> C1 = < right , boxlen , -bottom>
> D1 = <-left  , boxlen , -bottom>
>
> A2 = <-left  , boxlen+length , -bottom>
> B2 = < right , boxlen+length , -bottom>
> C2 = < right , boxlen+length , -bottom>
> D2 = <-left  , boxlen+length , -bottom>
>
> Is this really what you are expecting?
>
> If you are trying to see if a point is inside a box, then it might be
> simpler to think of the box as being bounded by 6 infinite planes (one
> for each face), then testing which side of each plane the point is on.
> If it's on the "inside" of all 6 planes then it's inside the box.
>
lol What part of, "I know I screwed up the math.", did people miss. ;)

Seriously though, Le_Fogeron says it wouldn't work anyway... :p


Post a reply to this message

From: Patrick Elliott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 05:18:43
Message: <51ff6df3$1@news.povray.org>
On 8/5/2013 2:15 AM, Patrick Elliott wrote:
> However... I occurs to me that I might be able to use one plane, and a
> distance.. So, as long as the position was rotated, to match a plane
> that is align to XY (or, actually, due to how the world works, XZ), then
> I can test if its in "that" box, and then merely do:
>
> float dist = llVecDist(llGetPos(), P);
> if (dist < maxdist & dist > mindist)
> {
>    //Rest of the code.
> }
>
> Thus, only testing "one" box, and only on that single plane.
>
> Then again, I screwed up the last idea so badly... lol

And, speaking of which.. again, I forget that the "distance" won't work 
for objects wider, or taller, than the distance... Sigh...


Post a reply to this message

From: scott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 07:35:43
Message: <51ff8e0f$1@news.povray.org>
>> Thus, only testing "one" box, and only on that single plane.
>>
>> Then again, I screwed up the last idea so badly... lol
>
> And, speaking of which.. again, I forget that the "distance" won't work
> for objects wider, or taller, than the distance... Sigh...

Make your bounding box the value of "distance" bigger than the bounding 
box of the object's geometry. That way you are checking for people 
within "distance" from the *edge* of the object, not from the centre.


Post a reply to this message

From: scott
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 07:38:14
Message: <51ff8ea6$1@news.povray.org>
On 05/08/2013 10:17, Patrick Elliott wrote:
> On 8/5/2013 1:44 AM, scott wrote:
>>>   vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>>>   vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>>>   vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z -
>>> bottom>;
>>>   vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
>>
>> Do you mean "pos.x + right" in that last line?
>>
>>> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector
>>> bbox4)
>>> {
>>>    vector P = llDectectedPos(0);
>>>    vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>>>    vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>>>    vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>>>    vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
>>  >    vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
>>  >    vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
>>  >    vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
>>  >    vector D2 = <bbox3.x,bbox3.y,bbox3.z>;
>>
>> If you substitute in your values for bbox1-4 from above you get the
>> following (I left out the pos.x,pos.y,pos.z):
>>
>> A1 = <-left  , boxlen , -bottom>
>> B1 = < right , boxlen , -bottom>
>> C1 = < right , boxlen , -bottom>
>> D1 = <-left  , boxlen , -bottom>
>>
>> A2 = <-left  , boxlen+length , -bottom>
>> B2 = < right , boxlen+length , -bottom>
>> C2 = < right , boxlen+length , -bottom>
>> D2 = <-left  , boxlen+length , -bottom>
>>
>> Is this really what you are expecting?
>>
>> If you are trying to see if a point is inside a box, then it might be
>> simpler to think of the box as being bounded by 6 infinite planes (one
>> for each face), then testing which side of each plane the point is on.
>> If it's on the "inside" of all 6 planes then it's inside the box.
>>
> lol What part of, "I know I screwed up the math.", did people miss. ;)

I was really having trouble trying to understand what you actually 
wanted to do! I don't know which parts of the above are math screw ups 
or what you actually want to do...

There are much easier, well documented, ways for doing bounding box 
tests, you don't need to go into splitting it up to squares and 
triangles and measuring areas as you seem to have done. If that's what 
you want to do?


Post a reply to this message

From: Le Forgeron
Subject: Re: Math question (inside box)
Date: 5 Aug 2013 07:43:05
Message: <51ff8fc9@news.povray.org>
Le 05/08/2013 11:17, Patrick Elliott a écrit :
> On 8/5/2013 1:44 AM, scott wrote:
>>>   vector bbox1 = <pos.x - left, pos.y + boxlen, pos.z - bottom>;
>>>   vector bbox2 = <pos.x + right, pos.y + boxlen, pos.z + top>;
>>>   vector bbox3 = <pos.x - left, pos.y + boxlen + length, pos.z -
>>> bottom>;
>>>   vector bbox4 = <pos.x - right, pos.y + boxlen + length, pos.z + top>;
>>
>> Do you mean "pos.x + right" in that last line?
>>
>>> integer isInsideBox(vector bbox1, vector bbox2, vector bbox3, vector
>>> bbox4)
>>> {
>>>    vector P = llDectectedPos(0);
>>>    vector A1 = <bbox1.x,bbox2.y,bbox1.z>;
>>>    vector B1 = <bbox2.x,bbox2.y,bbox1.z>;
>>>    vector C1 = <bbox2.x,bbox1.y,bbox1.z>;
>>>    vector D1 = <bbox1.x,bbox1.y,bbox1.z>;
>>  >    vector A2 = <bbox3.x,bbox4.y,bbox3.z>;
>>  >    vector B2 = <bbox4.x,bbox4.y,bbox3.z>;
>>  >    vector C2 = <bbox4.x,bbox3.y,bbox3.z>;
>>  >    vector D2 = <bbox3.x,bbox3.y,bbox3.z>;
>>
>> If you substitute in your values for bbox1-4 from above you get the
>> following (I left out the pos.x,pos.y,pos.z):
>>
>> A1 = <-left  , boxlen , -bottom>
>> B1 = < right , boxlen , -bottom>
>> C1 = < right , boxlen , -bottom>
>> D1 = <-left  , boxlen , -bottom>
>>
>> A2 = <-left  , boxlen+length , -bottom>
>> B2 = < right , boxlen+length , -bottom>
>> C2 = < right , boxlen+length , -bottom>
>> D2 = <-left  , boxlen+length , -bottom>
>>
>> Is this really what you are expecting?
>>
>> If you are trying to see if a point is inside a box, then it might be
>> simpler to think of the box as being bounded by 6 infinite planes (one
>> for each face), then testing which side of each plane the point is on.
>> If it's on the "inside" of all 6 planes then it's inside the box.

That's a good idea.

>>
> lol What part of, "I know I screwed up the math.", did people miss. ;)
> 
> Seriously though, Le_Fogeron says it wouldn't work anyway... :p

The test against 6 planes would work, and is easy if it is axis aligned.
If it is rotated, you have "just" to apply the same maths, it's just the
formula which become a bit harder (a plane equation is ax+by+cz+d = 0,
one side of the plane is wherer ax+by+cz+d > 0, and the other side is <0)
There is an infinity of 4D vector <a,b,c,d> to match a single plane
(indeed, if V is such vector, k.V is also another vector)
(also notice that if V is such vector, -V is the same plane but with the
inversion of the sides)
So, instead of thinking "corner of box" (8) to be grouped in
squares/side, you should have to think "plane's equation" (6).

Notice that scaling & shearing leaves plane as plane, so even if you
were to use a sheared box (such as a truncated pyramid), it would still
works.

What I said was that extending the "smart" 2D triangle-based-tests to 3D
are to be a nightmare.



-- 
Just because nobody complains does not mean all parachutes are perfect.


Post a reply to this message

From: Patrick Elliott
Subject: Re: Math question (inside box)
Date: 6 Aug 2013 00:00:02
Message: <520074c2$1@news.povray.org>
On 8/5/2013 4:35 AM, scott wrote:
>>> Thus, only testing "one" box, and only on that single plane.
>>>
>>> Then again, I screwed up the last idea so badly... lol
>>
>> And, speaking of which.. again, I forget that the "distance" won't work
>> for objects wider, or taller, than the distance... Sigh...
>
> Make your bounding box the value of "distance" bigger than the bounding
> box of the object's geometry. That way you are checking for people
> within "distance" from the *edge* of the object, not from the centre.
Only, then it detecting them too far away, when standing directly in 
front of it. If I want someone to be able to open a door from 5 meters, 
it should be 5 meters, regardless of where they are, when they do it. 
Or, in the specific case that led me to hunt for a solution, they can't 
be a) on the wrong side of a counter, b) farther than 3 meters from the 
safe, c) outside the building (i.e., behind the thing), or d) standing 
on the other side of the wall, near the safe (SL lets you pan you camera 
through things, with some of its controls, so you can't stop them 
clicking the thing, through a wall. This means a very narrow range of 
"usable" space, and distance. And the "alley" I need to test, is not 
much wider than the safe itself.

I could have gotten by with a fairly simple "angle" test, and distance, 
to see if they where close enough, in this specific case. But, not so 
with something bigger, like my hypothetical garage door.

Hmm. There is a possibility though..

avPos = llDetectedPos(0);
cPos = llGetPos(0);
ab = llGetAngleBetween(avPos, cPos);
TestDistance = ???(ab) * 5;

I.e., make the angle determine the "distance" so that every point in the 
detection range will "always" be the same distance from the object. Ur.. 
What would be the math for drawing a straight line, using a string, 
attached to a immobile peg exactly? lol


Post a reply to this message

Goto Latest 10 Messages Next 9 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.