Topic Title

The DataCAD Developer Network (DDN) is an online resource for information and support for DCAL® (DataCAD Applications Language) developers as well as anyone interested in creating fonts, toolbars, hatch patterns, or linetypes for use in DataCAD.

Hi,I'm having trouble with the PntInPoly function provided in the DCAL for Delphi libraries. It kept crashing when called in an Offset macro I am writing, so I checked all the passed parameters in Debugger and they all appeared to be initialised with valid values. In desperation I wrote the simple test program as below:

This test program also falls over on the PntInPoly call. It gets the exact same exception as my Offset macro: exception class $C0000005 with message 'access violation at 0x00000000: read of address 0x00000000'.

There seem to be a lot of zeros in the addresses in the error message, which makes me think something might not be initialised?

Perhaps I am doing something wrong and should be initialising something else before making the call? If there is an error in the above code I would be grateful if somebody could help me out. Sometimes I miss the obvious, but at the moment I'm thinking there may be a bug in the D4D function ...

It appears that the D4D pntinpoly function is in fact unusable (I am not the only one who has found that it crashes the drawing).

For anybody interested I have written my own PntInPly function which appears to work ok (based on some Classic DCAL code in the Shadow macro which has had quite a bit of testing ... although it didn't crash, I found the result of the Classic DCAL pnt_in_poly function to be unreliable).

// check if on a boundary and also set up min & max x & y values for i := 1 to npnt do begin if ply[i].x < minx then minx := ply[i].x; if ply[i].x > maxx then maxx := ply[i].x; if ply[i].y < miny then miny := ply[i].y; if ply[i].y > maxy then maxy := ply[i].y;

// check how many times a line from ospnt to pnt crosses ply boundary // An odd number of times indicates that pnt is inside ply // An even number of times indicates that pnt is outside ply repeat satisfactory := true; trycount := 0; xcount := 0; for i := 1 to npnt do begin j := i+1; if j > npnt then j := 1;

if intr_linlin (ospnt, pnt, ply[i], ply[j], intr, true) then begin if PntsEqual (intr, ply[i], weeDist) or PntsEqual (intr, ply[j], weeDist) then begin // looks like our line goes though one of the points ... result may not be reliable satisfactory := false; trycount := trycount+1; if PntsEqual (intr, ply[i], ABSZero) then xcount := xcount+1;

// check if on a boundary and also set up min & max x & y values for i := 1 to npnt do begin if ply[i].x < minx then minx := ply[i].x; if ply[i].x > maxx then maxx := ply[i].x; if ply[i].y < miny then miny := ply[i].y; if ply[i].y > maxy then maxy := ply[i].y;

// check how many times a line from ospnt to pnt crosses ply boundary // An odd number of times indicates that pnt is inside ply // An even number of times indicates that pnt is outside ply repeat satisfactory := true; trycount := 0; xcount := 0; for i := 1 to npnt do begin j := i+1; if j > npnt then j := 1;

if intr_linlin (ospnt, pnt, ply[i], ply[j], intr, true) then begin if PntsEqual (intr, ply[i], weeDist) or PntsEqual (intr, ply[j], weeDist) then begin // looks like our line goes though one of the points ... result may not be reliable satisfactory := false; trycount := trycount+1; if PntsEqual (intr, ply[i], ABSZero) then xcount := xcount+1;