1
c from algorithm 523, acm.
2
subroutine hullcvex(n,nn,xx,nhull,iwork,in,ih,il)
3
implicit doubleprecision (a-h,o-z)
4
dimension xx(2,n),in(n),ih(n),iwork(nn),il(nn)
10
c ncount is total number of points passed to split
16
c array in contains indices 1-n in reverse order
18
call convex(n,xx,m,in,iwork,iwork(n+1),ih,nhull,il)
27
subroutine husplit(n,x,m,in,ii,jj,s,iabv,na,maxa,ibel,
29
c this subroutine takes the m points of array x whose subscripts are in
31
c and partitions them by the line joining the two points in array x whose
32
c subscripts are ii and jj. the subscripts of the points above the line
33
c are put into array iabv, and the subscripts of the points below are put
34
c into array ibel. na and nb are,respectively, the number of points above
35
c the line and the number below. maxa and maxb are the subscripts for array
36
c x of the point furthest above the line and the point furthest below,
37
c respectively. if either subset is null the corresponding
38
c subscript (maxa or maxb) is set to zero
40
c n integer total number of data points
41
c x real array (2,n) (x,y) co-ordinates of the data
42
c m integer number of points in input subset
43
c in integer array (m) subscripts for array x of the
44
c points in the input subset
45
c ii integer subscript for array x of one point
46
c on the partitioning line
47
c jj integer subscript for array x of another
48
c point on the partitioning line
49
c s integer switch to determine output. refer
52
c iabv integer array (m) subscripts for array x of the
53
c points above the partitioning line
54
c na integer number of elements in iabv
55
c maxa integer subscript for array x of point
56
c furthest above the line. set to
58
c ibel integer array (m) subscripts for array x of the
59
c points below the partitioning line
60
c nb integer number of elements in ibel
61
c maxb integer subscript for array x of point
62
c furthest below the line. set to
64
implicit doubleprecision (a-h,o-z)
66
dimension in(m),iabv(m),ibel(m)
68
c if s = 2 dont save ibel,nb,maxb.
69
c if s =-2 dont save iabv,na,maxa.
70
c otherwise save everything
71
c if s is positive the array being partitioned is above the initial
72
c partitioning line. if it is negative, then the set of points is below.
75
c check to see if the line is vertical
76
if(x(1,jj).ne.x(1,ii))goto 1
78
dir=sign(1.D0,x(2,jj)-x(2,ii))*sign(1.D0,dble(s))
81
1 a=(x(2,jj)-x(2,ii))/(x(1,jj)-x(1,ii))
96
c the point is above the line
106
c the point is below the line
115
subroutine convex(n,x,m,in,ia,ib,ih,nh,il)
116
c this subroutine determines which of the m points of array x whose subscripts
117
c are in array in are vertices of the minimum area convex polygon containing
118
c the m points. the subscripts of the vertices are placed in array ih in the
119
c order they are found. nh is the number of elements in array ih and array il.
120
c array il is a linked list giving the order of the elements of array ih
121
c in a counter clockwise direction. this algorithm corresponds to a
122
c preorder traversal of a certain binary tree. each vertex of the binary tree
123
c represents a subset of the m points. at each step the subset of points
124
c corresponding to the current vertex of the tree is partitioned by a line
125
c joining two vertices of the convex polygon. the left son vertex in the binary
126
c tree represents the subset of points above the partitioning line and the
127
c right son vertex, the subset below the line. the leaves of the tree represent
128
c either null subsets or subsets inside a triangle whose vertices coincide
129
c with vertices of the convex polygon.
132
c n integer total number of data points
133
c x real array (2,n) (x,y) co-ordinates of the data
134
c m integer number of points in the input subset
135
c in integer array (m) subscripts for array x of the points
136
c in the input subset
138
c ia integer array (m) subscripts for array x of left son
139
c subsets. see comments after dimension
141
c ib integer array (m) subscripts for array x of right son
144
c ih integer array (m) subscripts for array x of the
145
c vertices of the convex hull
146
c nh integer number of elements in array ih and
147
c array il. same as number of vertices
148
c of the convex polygon
149
c il integer array (m) a linked list giving in order in a
150
c counter-clockwise direction the
151
c elements of array ih
152
implicit doubleprecision (a-h,o-z)
154
dimension in(m),ia(m),ib(m),ih(m),il(m)
155
c the upper end of array ia is used to store temporarily the sizes of the
156
c subsets which correspond to right son vertices, while traversing down
157
c the left sons when on the left half of the tree, and to store the sizes
158
c of the left sons while traversing the right sons(down the right half)
172
c find two vertices of the convex hull for the initial partition
175
if(x(1,j)-x(1,kx))3,1,2
181
3 if(x(1,j)-x(1,kn))5,4,6
188
c if the max and min are equal, all m points lie on a vertical line
190
c if maxe (or mine) has the value true there are several
191
c maxima (or minima) with equal first coordinates
192
if(maxe.or.mine)goto 23
205
c begin by partitioning the root of the tree
206
call husplit(n,x,mm,in,ih(1),ih(2),0,ia,mb,mxa,ib,ia(ma),
208
c first traverse the left half of the tree start with the left son
211
9 if(mxa.eq.0)goto 11
220
call husplit(n,x,mb,ia,ih(inh),ih(ilinh),1,ia,mbb,mxa,
221
1 ib(nib),ia(ma),mxb)
230
if(ia(ma).eq.0)goto 11
232
c on the left side of the tree, the right son of a right son must represent
233
c a subset of points which is inside a triangle with vertices which are also
234
c vertices of the convex polygon and hence the subset may be neglected.
235
call husplit(n,x,ia(ma),ib(nib),ih(inh),ih(ilinh),2,ia,
236
1 mb,mxa,ib(nib),mbb,mxb)
239
c now traverse the right half of the tree
245
c start with the right son
248
14 if(mxb.eq.0)goto 16
257
call husplit(n,x,mb,ib(nib),ih(inh),ih(ilinh),-1,ia(nia),
258
1 ia(ma),mxa,ib(nib),mbb,mxb)
267
if(ia(ma).eq.0)goto 16
269
c on the right side of the tree, the left son of a left son must represent
270
c a subset of points which is inside a triangle with vertices which are
271
c also vertices of the convex polygon and hence the subset may be neglected.
272
call husplit(n,x,ia(ma),ia(nia),ih(inh),ih(ilinh),-2,
273
1 ia(nia),mbb,mxa,ib(nib),mb,mxb)
277
c all the special cases are handled down here
278
c if all the points lie on a vertical line
283
if(x(2,j).le.x(2,kx))goto 19
286
19 if(x(2,j).ge.x(2,kn))goto 20
291
c if there are only two points
295
if((x(1,kn).eq.x(1,kx)).and.(x(2,kn).eq.x(2,kx)))nh=2
297
c if there is only one point
302
c multiple extremes are handled here if there are several points
303
c with the (same) largest first coordinate
304
23 if(.not.maxe)goto 25
307
if(x(1,j).ne.x(1,kx))goto 24
308
if(x(2,j).le.x(2,kx))goto 24
312
c if there are several points with the (same) smallest first coordinate
313
25 if(.not.mine)goto 7
316
if(x(1,j).ne.x(1,kn))goto 26
317
if(x(2,j).ge.x(2,kn))goto 26