/* CMD: Floor Object
 */
/* by GLYPH  */

/*
  - defines a "floor" with a polygon in the background layer
  - aligns an object in the foreground layer so that the "floor"
    lies exactly on the X-Z plane.

    NOTE: half the time, the object will be upside-down.
    just ROTATE it 180°

*/

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

pi = 3.1415926385897932384626

fg = curlayer()
bg = curblayer()
call setlayer(bg)

call GETPOINTS
cx = 0;cy=0;cz=0
do i=1 to n
  cx = cx + x.i; cy = cy + y.i; cz = cz + z.i
end
cx = cx/n; cy = cy/n; cz = cz/n

th3 = arctan(y.2-y.1,x.2-x.1)
call ROTATE(th3,'Z',cx cy cz)
call GETPOINTS
th2 = arctan(x.2-x.1,z.2-z.1)
call ROTATE(th2,'Y',cx cy cz)
call GETPOINTS
th1 = arctan(y.3-y.2,x.3-x.2)
call ROTATE(th1,'Z',cx cy cz)

call rotate(-th1,'Z',cx cy cz)
call rotate(-th2,'Y',cx cy cz)
call rotate(-th3,'Z',cx cy cz)

call setlayer(fg)
call rotate(th3,'Z',cx cy cz)
call rotate(th2,'Y',cx cy cz)
call rotate(th1,'Z',cx cy cz)
call add_begin()
call add_point(cx cy cz)
call add_end()
my = -cy
call move(0 my 0)
parse value boundingbox() with x1 x2 y1 y2 z1 z2
if (y1+y2)/2 < 0 then call rotate(180,'Z',cx 0 cz)
return

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:
n = xfrm_begin()
do i=1 to n
    tmp = xfrm_getpos(i)
    parse var tmp x.i y.i z.i
end i
call xfrm_end()
return

    Source: geocities.com/g_fyffe/lw

               ( geocities.com/g_fyffe)