POV-Ray : Newsgroups : povray.off-topic : Math question (inside box) : Math question (inside box) Server Time
28 Jul 2024 16:22:37 EDT (-0400)
  Math question (inside box)  
From: Patrick Elliott
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

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