/* CMD: make polygon
 */
/* by GLYPH  */

/*

 * creates a convex polygon around the points on the current layer,
   and sticks it on the next empty layer.

 * points don't have to be perpendicular to any axis.
   They should be coplanar for good results, though.
   
*/

call addlib("LWModelerARexx.port",0)
call addlib("rexxmathlib.library",0,-30,0)
call addlib("rexxsupport.library",0,-30,0)

pi = 3.1415926385897932384626

fg = curlayer()
emp = emptylayers()
if (words(emp) = 0) then do
    ok = notify(2,'!No empty layer.','Original points will be','!nuked.')
    if ok = 0 then return
end
if (words(emp) > 0) then do
    tl = word(emp,1)
    call copy()
    call setlayer(tl)
    call paste()
end
call mergepoints()
call GETPOINTS
if (n < 3) then exit()
do i=1 to n
    ox.i = x.i; oy.i = y.i; oz.i = z.i
end i
call ROTATE(arctan(y.2-y.1,x.2-x.1),'Z',cx cy cz)
call GETPOINTS
call ROTATE(arctan(x.2-x.1,z.2-z.1),'Y',cx cy cz)
call GETPOINTS
call ROTATE(arctan(y.3-y.2,x.3-x.2),'Z',cx cy cz)
call GETPOINTS
call MakeEdges
call JoinEdges
exit()


ARCTAN:
parse arg nu,de
if de = 0 then do
  actn = 999999999
  if nu < 0 then actn = -999999999
end
if ~(de = 0) then actn = nu/de
actu = actn
if actu < -1 then th = pi/2+atan(1/abs(actn))
if (actu < 1.00001)&(actu > -1.00001) then th = atan(actn)
if actu > 1 then th = pi/2-atan(1/actn)
return th*180/pi


GETPOINTS:
cx = 0;cy=0;cz=0
n = xfrm_begin()
do i=1 to n
    tmp = xfrm_getpos(i)
    parse var tmp x.i y.i z.i
    cx = cx + x.i; cy = cy + y.i; cz = cz + z.i
end i
call xfrm_end()
cx = cx/n; cy = cy/n; cz = cz/n
return


MAKEEDGES:
do i = 1 to n
 edge1.i = 0
 edge2.i = 0
end
do i = 1 to n-1
 if (edge1.i ~= 0)&(edge2.i ~= 0) then iterate
 do t = i+1 to n
  if (edge1.t ~= 0)&(edge2.t ~= 0) then iterate
  dx = x.t-x.i; dz = z.t-z.i
  call rotate(arctan(dx,dz),'Y',x.t y.t z.t)
  parse value boundingbox() with dud mx nx my ny mz nz
  mind = min(abs(mx-x.t),abs(nx-x.t))
  close = abs(mx-nx)/1000
  if mind n)
 if edge1.i ~= 0 then first = i
 else i = i + 1
end
prev = i
i = edge1.first
polylist = p.i
do until (i = first)|(i > n)
 if edge1.i ~= prev then pn = edge1.i
 else pn = edge2.i
 polylist = polylist' 'p.pn
 prev = i
 i = pn
end
call add_polygon(polylist)
call add_end()
return

    Source: geocities.com/g_fyffe/lw

               ( geocities.com/g_fyffe)