• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 441
  • Last Modified:

Polygon or cube collide

hi,

i need a function that i can put two 3d cubes(or array of poligon) into and an offset and get a boolean return

something like

type t3dpoint= record
      x,y,z : extended;
end;

function polycollide(Cube1Points, Cube2Points: array of T3dpointl; OffSet: Extended):boolean;

regards, mark
0
mgazza
Asked:
mgazza
  • 5
  • 3
  • 2
  • +1
1 Solution
 
esoftbgCommented:
And what do you expect to be done inside this function (because there is not a problem only to put parameters into the function without to do anything inside it)
;-))
0
 
esoftbgCommented:
function polycollide(Cube1Points, Cube2Points: array of T3dpointl; OffSet: Extended):boolean;
begin
  Result := True;
end;

it is not a working function, but it is a very beautiful one
;-))
0
 
mgazzaAuthor Commented:
no i was discribing the function my ideal function it needs to work inside aload of other stuff ,
dont get smart
 *sigh*

it will work in conjuntion with this this only finds all objects that are inside a box i need to find out if too poilgons colide

function GetWorldBlock(self:integer;Cube:TWorldCube):Arrayof_TArrayList;
var
i:integer;
temp:array[0..255]of TArrayList;
Nofound:integer;
start:pointer;
begin
nofound:=0; //int the integer;
  for i:=0 to high(World_ArrayObjects) do begin
    if i<>self then
     with World_ArrayObjects[i] do begin
     if (Pos.x>Cube.WorldLeft)and(Pos.x<Cube.WorldRight)then //no point in wasting ticks
       if (Pos.y>Cube.WorldTop)and(Pos.y<Cube.WorldBottom)then //this way is alot faster
         if (Pos.z>Cube.WorldFront)and(Pos.z<Cube.WorldBack)then
          if World_ArrayObjects[i].Status=Stdraw then //make sure were alowed to see it
          begin
            inc(Nofound);
            temp[nofound-1]:=World_ArrayObjects[i];
          end;
      end;
     if nofound=256 then  begin//if the buffer fills up dump it
        setlength(result,high(result)+nofound);

        start:=pointer(longword(@result[0])+(sizeof(TArrayList)*(high(result)-nofound)));
        move(Temp,start^,(sizeof(TArrayList)*nofound));        //fast copy .zoom ....

        nofound:=0;
     end;
    end;
    if nofound<>0 then begin
    //dump some more
        setlength(result,high(result)+nofound);

        start:=pointer(longword(@result[0])+(sizeof(TArrayList)*(high(result)-nofound)));
        move(Temp,start^,(sizeof(TArrayList)*nofound));        //fast copy .zoom ....

        nofound:=0;
    end;
end;

function CubeFromMesh(MeshIndex:smallint):TWorldCube;
begin
{$i MeshCubes.inc}
end;

function FindFreeBlock(Wantedpoint:T3dpoint64;MeshBounds:TWorldCube):T3dpoint64;
label
check;
var
i:integer;
MeshSize:TWorldCube;
begin
   check:

  for i:=0 to high(World_ArrayObjects) do begin
  with World_ArrayObjects[i] do
     if pos.x=Wantedpoint.x then
       if pos.y=Wantedpoint.y then
         if pos.z=Wantedpoint.z then
            begin
              //keep checking until the space is free
              inc(wantedpoint.x,random(20));
              inc(wantedpoint.y,random(20));
              inc(wantedpoint.z,random(20));
              goto check;
            end;
  end;
  result:=wantedpoint;
end;


the above function will be using the collide function,

as you can see all that information is usless so stop beging cleaver if you havnt got a soliution i sujest you dont ask
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
mgazzaAuthor Commented:
i realy havnt got time to be writing out collision functions. too much work to do

function PointInPoly(APoint : TPoint ; APoly : array of TPoint) : boolean;
Var
  i, j : integer;
  npol : integer;
begin
  Result := false;
  npol := length(APoly);
  for i := 0 to npol - 1 do begin
    j := (i + 1) mod npol;
    if ((((APoly[i].Y <= APoint.Y) and (APoint.Y < APoly[j].Y)) or
         ((APoly[j].Y <= APoint.Y) and (APoint.Y < APoly[i].Y))) and
        (APoint.X < (APoly[j].X - APoly[i].X) * (APoint.Y - APoly[i].Y) /
                    (APoly[j].Y - APoly[i].Y) + APoly[i].X)) then
      Result := not Result;
  end;
end;


there you are if you like make that function take on T3dpoint and offset

or

make this take on a z value

function CheckCollision(x1, y1,ph,pw,x2, y2,eh,ew: integer): boolean;
const
  OFFSET_X = 4; //use 1 for real visual result
  OFFSET_Y = 4;
begin
  Result := True;

  if (y1 + PH - (OFFSET_Y * 2) < y2 + OFFSET_Y) or
     (y1 + OFFSET_Y > y2 + Eh - (OFFSET_Y * 2)) or
     (x1 + PW - (OFFSET_X * 2) < x2 + OFFSET_X) or
     (x1 + OFFSET_X > x2 + EW - (OFFSET_X * 2)) then
      Result := False;
end;

0
 
esoftbgCommented:
Oh, it is terrible high-mathematical stuff ....
Here is 40 minutes after midnight, so I am very tired to think about high-math even you offer 250,000 points about solution ....
Sorry, I have too much work to do too ....
Emil
0
 
Lee_NoverCommented:
you can check Olivier Renaults collision routines
I've translated the Box project to delphi (it's 2D but could be easily converted to 3D)
there are other examples as well (in c++)
Box delphi version: http://users.volja.net/stdcall/Box.zip
olivier's examples: http://uk.geocities.com/olivier_rebellion/
0
 
Sergio_HdezCommented:
OK, to know if 2 3D cubes collide (only for CUBES, not other 3D poligons), look in all 3 cordinates: They collide if and only if some X of the first cube lie between MaxX and MinX of the second one... and the same with other 3 coords... so:

Collide(Cube1, Cube2): boolean;
var CoordXok, CoordYok, CoordYok: boolean;
begin
  CoordXok:= ((Cube1.MinX <= Cube2.MaxX) and (Cube1.MaxX >= Cube2.MinX);
  CoordYok:= ((Cube1.MinY <= Cube2.MaxY) and (Cube1.MaxY >= Cube2.MinY);
  CoordZok:= ((Cube1.MinZ <= Cube2.MaxZ) and (Cube1.MaxZ >= Cube2.MinZ);
  result:= CoordXok and CoordYok and CoordZok;
end;

I use it a lot in 2D, but the idea is the same, just without Z coord, and it is VERY fast to know if blocks collide or not.

To use offset in the function, i first should know what does it menas to you: The minimun separation to consider they collide if separation is less that offset? If it is so, then:

Collide(Cube1, Cube2, OffSet): boolean;
var CoordXok, CoordYok, CoordYok: boolean;
begin
  CoordXok:= ((Cube1.MinX <= Cube2.MaxX+OffSet) and (Cube1.MaxX >= Cube2.MinX-OffSet);
  CoordYok:= ((Cube1.MinY <= Cube2.MaxY+OffSet) and (Cube1.MaxY >= Cube2.MinY-OffSet);
  CoordZok:= ((Cube1.MinZ <= Cube2.MaxZ+OffSet) and (Cube1.MaxZ >= Cube2.MinZ-OffSet);
  result:= CoordXok and CoordYok and CoordZok;
end;

Hope it was your goal to get this function, correctme if don't.
0
 
Sergio_HdezCommented:
Ops! some typo error in my last post, all of them trivial... "function" keyword missing, and 3rd variable name is CoodZok, not CoordYok, obviously!
0
 
mgazzaAuthor Commented:
thanks alot thats just what i was looking for :D
0
 
mgazzaAuthor Commented:
humm there seams to be a problem wwhen the cube1 is coliding on the top right corner on cube2

function CubeCollide(Cube1, Cube2:TWorldCube; OffSet: Extended): boolean;
var CoordXok, CoordYok, CoordZok: boolean;
begin
  CoordXok:= ((Cube1.WorldLeft <= Cube2.WorldRight+OffSet) and (Cube1.WorldRight >= Cube2.WorldLeft-OffSet));
  CoordYok:= ((Cube1.WorldTop <= Cube2.WorldBottom+OffSet) and (Cube1.WorldTop >= Cube2.WorldTop-OffSet));
  CoordZok:= ((Cube1.WorldFront <= Cube2.WorldBack+OffSet) and (Cube1.WorldFront >= Cube2.WorldFront-OffSet));
  result:= CoordXok and CoordYok and CoordZok;
end;


{
    ........
  .\        \
  . \   wt   \
  .  \........\
  .wl'        '
  \  '  wf    '
   \ '        '
    \'........'
}
procedure TForm1.FormClick(Sender: TObject);
var
c1,c2:TWorldCube;
begin
c1.WorldLeft:=shape1.Left;
c1.WorldRight:=shape1.Left+shape1.Width;
c1.WorldTop:=shape1.Top;
c1.WorldBottom:=shape1.Top+shape1.Height;
c1.WorldFront:=0;
c1.WorldBack:=0; //depth of 10

c2.WorldLeft:=shape2.Left;
c2.WorldRight:=shape2.Left+shape2.Width;
c2.WorldTop:=shape2.Top;
c2.WorldBottom:=shape2.Top+shape2.Height;
c2.WorldFront:=0;
c2.WorldBack:=0; //depth of 10
if CubeCollide(c1,c2,0) then showmessage('hit');
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 if Shift=[ssalt] then begin
  shape1.Left:=x;
  shape1.Top:=y;
 end;
end;
0
 
mgazzaAuthor Commented:
humm judt got time to write my own function:D

this one works and well fast(when theres no colision)
(if theres 3000 objects and only 1 of them hit get wat i mean)

function InBetween(N,Alpha,Beta:integer):boolean;
begin
result:=(n>=alpha) and (n<=Beta);
end;

function CubeCollide(Cube1, Cube2:TWorldCube; OffSet: Integer): boolean;
begin
result:=false;
if
  Inbetween(cube1.WorldLeft, cube2.WorldLeft-OffSet, cube2.WorldRight+OffSet)
or
  Inbetween(cube1.WorldRight, cube2.WorldLeft-OffSet, cube2.WorldRight+OffSet)
then
  if
    Inbetween(cube1.WorldTop, cube2.WorldTop-OffSet, cube2.WorldBottom+OffSet)
  or
    Inbetween(cube1.WorldBottom, cube2.WorldTop-OffSet, cube2.WorldBottom+OffSet)
  then
    if
      Inbetween(cube1.WorldFront, cube2.WorldFront-OffSet, cube2.WorldBack+OffSet)
    or
      Inbetween(cube1.WorldBack, cube2.WorldFront-OffSet, cube2.WorldBack+OffSet)
    then result:=true;

end;
{
    ........
  .\        \
  . \   wt   \
  .  \........\
  .wl'        '
  \  '  wf    '
   \ '        '
    \'........'
}
procedure TForm1.FormClick(Sender: TObject);
var
c1,c2:TWorldCube;
begin
c1.WorldLeft:=shape1.Left;
c1.WorldRight:=shape1.Left+shape1.Width;
c1.WorldTop:=shape1.Top;
c1.WorldBottom:=shape1.Top+shape1.Height;
c1.WorldFront:=0;
c1.WorldBack:=0; //depth of 10

c2.WorldLeft:=shape2.Left;
c2.WorldRight:=shape2.Left+shape2.Width;
c2.WorldTop:=shape2.Top;
c2.WorldBottom:=shape2.Top+shape2.Height;
c2.WorldFront:=0;
c2.WorldBack:=0; //depth of 10
if CubeCollide(c1,c2,0) then showmessage('hit');
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 if Shift=[ssalt] then begin
  shape1.Left:=x;
  shape1.Top:=y;
 end;
end;
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 5
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now