IDLanROI and IDLanROIGroup confusion about what is interior and exterior
Topic:
If you create an IDLanROI object (ROI = Region of Interest) you can use the IDLanROI::ContainsPoints method to determine if a point or a set of points are contained in that ROI. Easy enough, but confusion can set in when using a group of "interior" and "exterior" ROI's to define an overall ROI.
Discussion:
Using the IDLanROIGroup object you can combine ROI's to make any kind of ROI you want. For example you could make a square with a hole in it. To accomplish this you set some ROI's to "interior" and some to "exterior."
The Confusion:
When you define an ROI as interior, like so:
o1 = obj_new('IDLanROI',[0,4,4,0],[0,0,4,4], interior=1)
"interior" means a hole in the ROI. The IDLanROIGroup::ContainsPoints will give a value of 0 for any points in this "interior" ROI, because is a "hole" and thus not part of the ROI. However, in the documentation on IDLanROIGroup::ContainsPoints it says that for points "interior" to the ROI the method will return a value of 1 or true.
Then the second ROI could be defined like so:
o2 = obj_new('IDLanROI',[0,9,9,0],[0,0,9,9], interior=0)
Here, interior=0 implies that it is *not* a "hole" and that IDLanROIGroup::ContainsPoints will give a value of 1, or true, in this region.
Then the group is defined like so (see example code at the bottom for a full example):
group = obj_new('IDLanROIGroup')
group -> Add, o1
group -> Add, o2
In short:
IDLanROIGroup::ContainsPoints gives a value of 0, or false, when a point is *not* "interior" to the ROI group, *but* this corresponds to an "interior" (interior=1) ROI or "hole" which is actually "exterior" to the ROI group.
The two documents in IDL help would seem to contradict each other, but if you can keep this straight in your head, then everything will work out fine.
The example code at the bottom of the page illustrates the use of the "interior" keyword and the resulting output from the ContainsPoints method. Run the code below to get a sense of the behavior that you can expect from this method. Inside the the example code, an ROI group is generated. The image shown below displays the values returned from a call to CONTAINSPOINTS method for a 15x15 box around the ROI. The return values were mapped to the following colors:
0 -outside ROI-black
1 -inside ROI - blue
2- edge of ROI - purple
3- vertex of ROI- Red

Solution:
;+
; :Description:
; This procedure creates a square ROI with a square
; "hole" in it and then tests points along the diagonal
; to see which points lie within the ROI.
;
; It illustrates the use of the "interior" keyword and
; the IDLanROIGroup::ContainsPoints method.
;
; The procedure prints out the result from
; ::ContainsPoints for every point along the diagonal
; to give you an idea of the behaviour of the method
; so you know what to expect.
;-
pro test_ROI_ex
;set up the ROI Group object to contain the ROI's
group = obj_new('IDLanROIGroup')
;create two ROI objects------------>
;this first ROI is defined as a "hole" by interior=1
o1 = obj_new('IDLanROI',[0,4,4,0],[0,0,4,4], interior=1)
;this second ROI is not a "hole", interior=0
o2 = obj_new('IDLanROI',[0,9,9,0],[0,0,9,9], interior=0)
;add both objects to the ROI Group
group -> Add, o1
group -> Add, o2
; x will be a vector containing the output from the
;ContainsPoints method, each value in x coreponds to
;a point along the diagonal and shows if it is within
;the overall ROI or not.
x = group->containspoints(indgen(15),indgen(15))
; 0 = not contained in the ROI
; 1 = contained in the ROI
; 3 = on the edge of the ROI
print, '0=false, 1=true, 3=edge'
;This loop prints out information for each point
;along the diagonal so you can see which points
;are contained in the ROI
for ii=0, n_elements(x)-1 do begin
;false
if (x[ii] eq 0) then begin
print, string(x[ii], format='(i2)'), $
+ ' : point [' $
+ string(ii, format='(i2)') $
+ ',' $
+ string(ii, format='(i2)') $
+ '] ', $
+ 'is exterior to the ROI'
;true
endif else if (x[ii] eq 1) then begin
print, string(x[ii], format='(i2)'), $
+ ' : point [' $
+ string(ii, format='(i2)') $
+ ',' $
+ string(ii, format='(i2)') $
+ '] ', $
+ 'is interior to the ROI'
;edge
endif else if (x[ii] eq 3) then begin
print, string(x[ii], format='(i2)'), $
+ ' : point [' $
+ string(ii, format='(i2)') $
+ ',' $
+ string(ii, format='(i2)') $
+ '] ', $
+ 'is on the edge of the ROI'
endif
endfor
end