Board index » delphi » PtInRegion hits nothing?!

PtInRegion hits nothing?!

A new problem.

I create several regions using CreatePolygonRgn function, passing array of
several points (ex. 4). After that, under some condition, I have to test if
user has clicked inside that region using PtInRegion; now there are some
problems:

a) Sometimes CreatePolygonRgn returns 0 (no region created) - why is that?
b) Under any cicrumstances I can not get any hits when passing points to
PtInRegion

Here is HitTest function:
function TForm1.TestRegionHit(point: TPoint): integer;
var i: integer;
    rgn: HRGN;
    n: integer;
begin
     Result := 0;
     for i := 0 to Length(all_regions)-1 do
         begin
              n := Length(all_regions[i].region);
              rgn := CreatePolygonRgn(all_regions[i].region, n, WINDING);
              if PtInRegion(rgn, point.x, point.y) then
                 begin
                      Result := all_regions[i].region_no;
                      break;
                 end;
              DeleteObject(rgn);
         end;
     if rgn <> 0 then DeleteObject(rgn);
end;

Local variables are for better readability of the code.

Any ideas?

 

Re:PtInRegion hits nothing?!


Quote
"Davor Pleskina" <davor.plesk...@ri.tel.hr> wrote in message

news:3a3505a6_2@dnews...

Quote
> A new problem.

> I create several regions using CreatePolygonRgn function, passing array of
> several points (ex. 4). After that, under some condition, I have to test
if
> user has clicked inside that region using PtInRegion; now there are some
> problems:

> a) Sometimes CreatePolygonRgn returns 0 (no region created) - why is that?
> b) Under any cicrumstances I can not get any hits when passing points to
> PtInRegion

OK, I have found where the problem is.
It is necessary to use fixed point array length. Dynamic point arrays don't
work.

Greetins to all.

Re:PtInRegion hits nothing?!


Quote
In article <3a3611c9_1@dnews>, Davor Pleskina wrote:
> It is necessary to use fixed point array length. Dynamic point arrays don't
> work.

Davor,

They do work, I bet you passed them wrong. If pts is your dynamic array, use
rgn:=CreatePolygonRgn(pts[0],...). The variable pts points to the length info
of the dynamic array instead of to the first data location.

Renate

Renate Schaaf
http://www.xmission.com/~renates/delphi.html

Re:PtInRegion hits nothing?!


Quote
"Renate Schaaf" <rena...@xmission.com> wrote in message

news:VA.000002ad.02b2069f@xmission.com...

Quote
> In article <3a3611c9_1@dnews>, Davor Pleskina wrote:
> > It is necessary to use fixed point array length. Dynamic point arrays
don't
> > work.

> Davor,

> They do work, I bet you passed them wrong. If pts is your dynamic array,
use
> rgn:=CreatePolygonRgn(pts[0],...). The variable pts points to the length
info
> of the dynamic array instead of to the first data location.

Well, I would not bet on this, as DynArrays actually HAVE zero element; they
count from 0 to Length-1, not from 1 to Length. Right? Beside that,
CreatePolygonRgn would not ask for number of points if the first element
would tell anything about size...

Maybe I am wrong, but all my dynamic arrays start with an element [0].

Re:PtInRegion hits nothing?!


Here's sample using dynamic TPoint array.
Hope this helps.

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
type
  PPointArray = ^TPointArray;
  TPointArray = array[0..MaxInt div SizeOf(TPoint) - 1] of TPoint;
var
  Rgn: HRGN;
  P: PPointArray;
begin
  GetMem(P, SizeOf(TPoint) * 3);
  P[0] := Point(0, 0);
  P[1] := Point(50, 100);
  P[2] := Point(100, 50);
  Rgn := CreatePolygonRgn(P[0], 3, WINDING);
  Canvas.Brush.Color := clRed;
  FillRgn(Canvas.Handle, Rgn, Canvas.Brush.Handle);
  if PtInRegion(Rgn, X, Y) then Beep;
  DeleteObject(Rgn);
  FreeMem(P);
end;

Quote
Davor Pleskina wrote:
> I create several regions using CreatePolygonRgn function, passing array of
> several points (ex. 4). After that, under some condition, I have to test if
> user has clicked inside that region using PtInRegion; now there are some
> problems:

> a) Sometimes CreatePolygonRgn returns 0 (no region created) - why is that?
> b) Under any cicrumstances I can not get any hits when passing points to
> PtInRegion

Re:PtInRegion hits nothing?!


Quote
In article <3a368f8e_1@dnews>, Davor Pleskina wrote:
> Well, I would not bet on this, as DynArrays actually HAVE zero element; they
> count from 0 to Length-1, not from 1 to Length. Right? Beside that,
> CreatePolygonRgn would not ask for number of points if the first element
> would tell anything about size...

> Maybe I am wrong, but all my dynamic arrays start with an element [0].

I see you did not try :). You bet it works. Whether or not the count of a
dynamic array starts at zero is immaterial. CreatePolygonRgn takes a pointer
to the memory location of the first TPoint record. That happens to be pts[0],
and not pts. The function is a WinAPI that knows nothing about the length of
your array, or where you start counting, or what. It just slurps up a chunk of
memory, and when it can interpret that as points to make a region of, it's
happy, otherwise it gives an error.

Renate

Re:PtInRegion hits nothing?!


Hi Davor,

As working with regions is not always easy and takes memory when there are
many polygons, I wrote my own algorithm to test if the mouse is inside a
polygon. I use it in a cartographic application where there may be several
hundreds of polygons on screen - some of them with several hundreds of
points and sometimes with "holes" - and it works very fast.

You can download it on Earl Glynn's page (see the link in the thread just
after yours).

Thrse

Re:PtInRegion hits nothing?!


Quote
"Renate Schaaf" <rena...@xmission.com> wrote in message

news:VA.000002af.0325bf68@xmission.com...

Quote
> I see you did not try :). You bet it works. Whether or not the count of a
> dynamic array starts at zero is immaterial. CreatePolygonRgn takes a
pointer
> to the memory location of the first TPoint record. That happens to be
pts[0],
> and not pts. The function is a WinAPI that knows nothing about the length
of
> your array, or where you start counting, or what. It just slurps up a
chunk of
> memory, and when it can interpret that as points to make a region of, it's
> happy, otherwise it gives an error.

Than, of course, it could be truth. I am going to try this; until now I
solved a problem assigning dynamic array elements to fixed array. Your way
should be much more elegant!

Thanks.

Other Threads